Hi,
I am trying to use javax.xml.stream.XMLInputFactory
and javax.xml.stream.XMLOutputFactory
inside an OSGi framework. These use ServiceLoader
internally to locate concrete XMLInputFactory
and XMLOutputFactory
classes, i.e. by invoking javax.xml.stream.FactoryFinder
. However, FactoryFinder
is part of the JDK and so has no osgi.serviceloader
metadata.
The only way I know to add extra requirements to Bnd is:
-runrequires: \
osgi.serviceloader;filter:='(osgi.serviceloader=javax.xml.stream.XMLInputFactory)';osgi.serviceloader='javax.xml.stream.XMLInputFactory',\
osgi.serviceloader;filter:='(osgi.serviceloader=javax.xml.stream.XMLOutputFactory)';osgi.serviceloader='javax.xml.stream.XMLOutputFactory',\
However, I still get this exception at runtime:
=> javax.xml.stream.FactoryConfigurationError: Provider for javax.xml.stream.XMLInputFactory cannot be found
java.xml/javax.xml.stream.FactoryFinder.find(FactoryFinder.java:320)
java.xml/javax.xml.stream.XMLInputFactory.newFactory(XMLInputFactory.java:323)
com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:120)
com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:106)
com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:90)
com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:129)
com.fasterxml.jackson.dataformat.xml.XmlMapper.builder(XmlMapper.java:220)
...
FWIW, this is happening with a locally-patched 2.14.0-SNAPSHOT version of Jackson where I have added these Bnd annotations:
package com.fasterxml.jackson.dataformat.xml;
@ServiceProvider(JsonFactory.class)
@ServiceConsumer(XMLInputFactory.class)
@ServiceConsumer(XMLOutputFactory.class)
public class XmlFactory extends JsonFactory
However, it occurs to me that it is the system bundle which is the actual “consumer” here, and so maybe that is where the requirement should be. But there is no obvious equivalent of -runsystemcapabilities
for requirements other than -runrequires
.
For reference, my -runbundles
does contain:
org.apache.aries.spifly.dynamic.bundle;version='[1.3.2,1.3.3)',\
Can anyone help me sort my .bndrun
file out please?
Thanks,
Chris
Edit: From the POV of a TestOSGi
Gradle task, this test fails:
@ServiceConsumer(XMLInputFactory.class)
class ServiceLoaderTest {
private static final Logger logger = LoggerFactory.getLogger(ServiceLoader.class);
@Test
void loadXMLInputFactoryByClassLoader() {
final XMLInputFactory inputFactory = XMLInputFactory.newFactory(XMLInputFactory.class.getName(), getClass().getClassLoader());
assertNotNull(inputFactory);
logger.info("FOUND: {}", inputFactory);
}
}
but this succeeds:
@ServiceConsumer(XMLInputFactory.class)
class ServiceLoaderTest {
private static final Logger logger = LoggerFactory.getLogger(ServiceLoader.class);
@Test
void serviceLoadXMLInputFactory() {
final ServiceLoader<XMLInputFactory> inputFactoriesLoader = ServiceLoader.load(XMLInputFactory.class, getClass().getClassLoader());
final List<XMLInputFactory> inputFactories = inputFactoriesLoader.stream().map(ServiceLoader.Provider::get).collect(toList());
assertThat(inputFactories).isNotEmpty();
inputFactories.forEach(input -> logger.info("FOUND: {}", input));
}
}