I have never looked into the details of how spi-fly relates to non-osgi service loading, but your use of service loader uses B’s bundle class loader, whereas the neo4j use uses A’s bundle classloader. What is found is consistent with what you’ve configured in the respective manifests.
David Jencks Sent from my iPhone > On Sep 18, 2019, at 2:58 AM, Cyrille Duret <cdu...@gmail.com> wrote: > > Hello, > I want to embedd neo4j in a bundle A, and create an graph database in a > bundle B. > > Neo4j kernel artifact relies heavily on SPI mechanism for exposing config > properties so I use SPI Fly to mediate the java ServiceLoader : > <dependency> > <groupId>org.apache.aries.spifly</groupId> > <artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId> > <version>1.2.3</version> > </dependency> > > > My bundle A config : > > <Embedd-Dependency> > .. > *;groupId=org.neo4j;artifactId=neo4j-kernel;inline=META-INF/services/*, > .. > </Embedd-Dependency> > <SPI-Provider>*</SPI-Provider> > <Export-Package> > ..org.neo4j.configuration;version=${neo4j-version}, > ..</Export-Package> > > > My bundle B config : > > <Import-Package> > .. > org.neo4j.configuration;version=${neo4j-version}, > .. > </Import-Package> > <SPI-Consumer>*</SPI-Consumer> > > > In my B activator start method : > import org.neo4j.configuration.LoadableConfig; > .. > ServiceLoader<LoadableConfig> serviceLoader = > ServiceLoader.load(LoadableConfig.class); > Iterator<LoadableConfig> it = serviceLoader.iterator(); > // I can see all exposed config from bundle A > while( it.hasNext() ) { > final LoadableConfig config = it.next(); > System.out.println("-> "+config); > } > > // The call from this static method does not return any config > List<LoadableConfig> configs = LoadableConfig.allConfigClasses(); > System.out.println("configs from LoadableConfig => "+configs.size()); > > > the org.neo4j.configuration.LoadableConfig.allConfigClasses method which is > embedded in A has the following implementation : > static List<LoadableConfig> allConfigClasses() > { > return Iterators.stream( ServiceLoader.load( LoadableConfig.class > ).iterator() ).collect( Collectors.toList() ); > } > > I do not understand why the allConfigClasses() method does not see the > exposed SPI services and why my ServiceLoader.load snippet code does. > I have noticed that if I added <SPI-Consumer>*</SPI-Consumer> to A, the > LoadableConfig.allConfigClasses does indeed work. > > Anyone can explain me why the static method does not work in the first place > and why it does when adding <SPI-Consumer>*</SPI-Consumer> to A ?? > > thank you > Cyrille >