Re: Platform wrapped jar cannot access META-INF/service impl via ServiceLoader
Geertjan, Emi and Boris, Many thanks for responding. It seems that Lookup and ServiceLoader are similar, yet different enough to be troublesome. I will need to do more testing, but first I will try to inject the services I need via a method, and not via META-INF/resources. Much appreciated. -Damian On Sat, 17 Aug 2019 at 21:38, Boris Heithecker wrote: > Are you sure that the services your third-party jar wants to look up via > java.util.ServiceLoader.load(Clazz.class) are registered as > META-INF/services entries? > The problem could be that Lookup.getDefault().lookup(Clazz.class) also > looks up services registered in the system file system (layer.xml) in the > /Services subdirectory. > Also, are you sure that your third-party jar does not specify a particular > class loader it finds appropriate when looking up up the service, i.e. > using the method signature java.util.ServiceLoader.load(Clazz.class, > MyLoader.class)? In the default case, > java.util.ServiceLoader.load(Clazz.class) uses > Thread.currentThread().getContextClassLoader() to look up the required > service, but this may be jdk implementation dependent. > Does your external jar require the service at an early phase during > start-up? The implementing module may not be fully ready yet. > Also, make sure no attempt is made to double load the service interface > class from two different classloaders. The NetBeans classloader system > allows, in principle, multiple definitions of the same class with the same > qualified name. But these are not available on the context classloader. > Look through the logs, you get it warning saying something like ".. won't > arbitrarily load class x from class loader y and z". > Maybe this helps. > Boris > > > On Sat, 17 Aug 2019 at 08:12, Damian Carey wrote: > >> Hi all, >> >> We have a "mature" (10+ year old) Netbeans Platform Swing product, which >> has 35+ modules. This all works well. >> >> As usual, when one Netbeans module provides an Implementation we find it >> from other Netbeans modules using the usual idiom ... >> Provider: puts entry in META-INF/services >> Consumer: MyClass myObj = Lookup.getDefault().lookup(MyClass.class); >> >> Our current issue is that we need to add an external jar that is NOT >> built using Netbeans, so it can't use Lookup. I have placed this external >> jar into a module wrapper, and one of our modules depends on it so we can >> successfully start this service as appropriate. Again, everything is >> perfect with this setup. >> >> The problem is that this external jar is looking for services from our >> Netbeans platform product, it is seeking them using standard java >> ServiceLoader capability, but the implementations are not found. >> >> I *think* that if we use the Netbeans System ClassLoader then it CAN >> locate the implementations, however we don't want to use the system >> classloader because it will cause other issues. >> >> Does anyone have any suggestions on how a wrapped jar might access >> Netbeans META-INF/services implementations via vanilla Java ServiceLoader >> SPI interface? >> >> Any suggestions would be hugely appreciated. >> >> Many thanks, >> -Damian >> > > > -- > Boris Heithecker > > > Dr. Boris Heithecker > Lüneburger Str. 30 > 28870 Ottersberg > Festnetz: +49 4205 315834 > Mobil: +49 170 6137015 >
Re: Platform wrapped jar cannot access META-INF/service impl via ServiceLoader
Are you sure that the services your third-party jar wants to look up via java.util.ServiceLoader.load(Clazz.class) are registered as META-INF/services entries? The problem could be that Lookup.getDefault().lookup(Clazz.class) also looks up services registered in the system file system (layer.xml) in the /Services subdirectory. Also, are you sure that your third-party jar does not specify a particular class loader it finds appropriate when looking up up the service, i.e. using the method signature java.util.ServiceLoader.load(Clazz.class, MyLoader.class)? In the default case, java.util.ServiceLoader.load(Clazz.class) uses Thread.currentThread().getContextClassLoader() to look up the required service, but this may be jdk implementation dependent. Does your external jar require the service at an early phase during start-up? The implementing module may not be fully ready yet. Also, make sure no attempt is made to double load the service interface class from two different classloaders. The NetBeans classloader system allows, in principle, multiple definitions of the same class with the same qualified name. But these are not available on the context classloader. Look through the logs, you get it warning saying something like ".. won't arbitrarily load class x from class loader y and z". Maybe this helps. Boris On Sat, 17 Aug 2019 at 08:12, Damian Carey wrote: > Hi all, > > We have a "mature" (10+ year old) Netbeans Platform Swing product, which > has 35+ modules. This all works well. > > As usual, when one Netbeans module provides an Implementation we find it > from other Netbeans modules using the usual idiom ... > Provider: puts entry in META-INF/services > Consumer: MyClass myObj = Lookup.getDefault().lookup(MyClass.class); > > Our current issue is that we need to add an external jar that is NOT built > using Netbeans, so it can't use Lookup. I have placed this external jar > into a module wrapper, and one of our modules depends on it so we can > successfully start this service as appropriate. Again, everything is > perfect with this setup. > > The problem is that this external jar is looking for services from our > Netbeans platform product, it is seeking them using standard java > ServiceLoader capability, but the implementations are not found. > > I *think* that if we use the Netbeans System ClassLoader then it CAN > locate the implementations, however we don't want to use the system > classloader because it will cause other issues. > > Does anyone have any suggestions on how a wrapped jar might access > Netbeans META-INF/services implementations via vanilla Java ServiceLoader > SPI interface? > > Any suggestions would be hugely appreciated. > > Many thanks, > -Damian > -- Boris Heithecker Dr. Boris Heithecker Lüneburger Str. 30 28870 Ottersberg Festnetz: +49 4205 315834 Mobil: +49 170 6137015
Re: Platform wrapped jar cannot access META-INF/service impl via ServiceLoader
I don't have a solution at hand but remember that the lookup will keep a single object instance in memory for a given service entry while the ServiceLoader will create fresh instances if it's just reading META-INF/service files (unless the JAR keeps a reference to a single ServiceLoader instance so the cache is reused). So you want a "bridge" from ServiceLoader to the default lookup or just a way to instantiate the services? I guess the most heavy duty solution would be to bytecode engineer the 3rd party JAR so you it either calls the lookup or allows you to inject values. PS: I had the reverse problem: the ServiceLoader finding classes when I didn't want it to find any (geotools JARs). This was happening because those JARs were in the boot classpath for some reason. --emi On Sat, Aug 17, 2019 at 9:12 AM Damian Carey wrote: > > Hi all, > > We have a "mature" (10+ year old) Netbeans Platform Swing product, which has > 35+ modules. This all works well. > > As usual, when one Netbeans module provides an Implementation we find it from > other Netbeans modules using the usual idiom ... > Provider: puts entry in META-INF/services > Consumer: MyClass myObj = Lookup.getDefault().lookup(MyClass.class); > > Our current issue is that we need to add an external jar that is NOT built > using Netbeans, so it can't use Lookup. I have placed this external jar into > a module wrapper, and one of our modules depends on it so we can successfully > start this service as appropriate. Again, everything is perfect with this > setup. > > The problem is that this external jar is looking for services from our > Netbeans platform product, it is seeking them using standard java > ServiceLoader capability, but the implementations are not found. > > I *think* that if we use the Netbeans System ClassLoader then it CAN locate > the implementations, however we don't want to use the system classloader > because it will cause other issues. > > Does anyone have any suggestions on how a wrapped jar might access Netbeans > META-INF/services implementations via vanilla Java ServiceLoader SPI > interface? > > Any suggestions would be hugely appreciated. > > Many thanks, > -Damian - To unsubscribe, e-mail: users-unsubscr...@netbeans.apache.org For additional commands, e-mail: users-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
Re: Platform wrapped jar cannot access META-INF/service impl via ServiceLoader
I can't respond theoretically to this but would be happy to look at it if you could put a small app together that reproduces this, on GitHub. Gj On Sat, Aug 17, 2019 at 8:12 AM Damian Carey wrote: > Hi all, > > We have a "mature" (10+ year old) Netbeans Platform Swing product, which > has 35+ modules. This all works well. > > As usual, when one Netbeans module provides an Implementation we find it > from other Netbeans modules using the usual idiom ... > Provider: puts entry in META-INF/services > Consumer: MyClass myObj = Lookup.getDefault().lookup(MyClass.class); > > Our current issue is that we need to add an external jar that is NOT built > using Netbeans, so it can't use Lookup. I have placed this external jar > into a module wrapper, and one of our modules depends on it so we can > successfully start this service as appropriate. Again, everything is > perfect with this setup. > > The problem is that this external jar is looking for services from our > Netbeans platform product, it is seeking them using standard java > ServiceLoader capability, but the implementations are not found. > > I *think* that if we use the Netbeans System ClassLoader then it CAN > locate the implementations, however we don't want to use the system > classloader because it will cause other issues. > > Does anyone have any suggestions on how a wrapped jar might access > Netbeans META-INF/services implementations via vanilla Java ServiceLoader > SPI interface? > > Any suggestions would be hugely appreciated. > > Many thanks, > -Damian >