Puce
Puce

Reputation: 38132

JAXB + OSGi with Java 11

I'm trying to load the JAXB modules as OSGi bundles with Java 11 and Apache Felix using a POM-first approach (the OSGi meta data gets generated).

First I tried with:

        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-osgi</artifactId>
            <version>2.3.3</version>
        </dependency>

but this gives me the following runtime exception:

SCHWERWIEGEND: Implementation of JAXB-API has not been found on module path or classpath.  
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception: 
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]

It might be related to the following issue, but I'm not sure: https://github.com/eclipse-ee4j/jaxb-api/issues/78

So I tried with v3.0.0 but now one of my annotation processory which generate an XML document using JAXB, fails:

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project my-module: Compilation failure
Implementation of JAXB-API has not been found on module path or classpath.

I noticed that jaxb-osgi-3.0.0.jar does not provide the com.sun.xml.bind package anymore

I also tried to migrate from javax.xml.bind to jakarta.xml.bind, but the Maven Plugins, which generate POJO classes from XSDs, don't seem to be ready yet at the time of writing (neither org.jvnet.jaxb2.maven2:maven-jaxb2-plugin nor org.codehaus.mojo:jaxb2-maven-plugin).

My questions:

  1. Where can I get the com.sun.xml.bind from?
  2. How do the jaxb-osgi and jaxb-impl modules relate?
  3. How is this all supposed to work?
  4. How can I proceed?

Update - background information

I have the following setup based on the Extender Pattern:

Goal: it should be easy to create extendee modules such as X, Y, Z

Everything works fine with Java SE 8 where JAXB is still bundled with the JRE.

Update 1

Because the Maven plugins are not ready I'm stuck with v2.3.3 for now.

I changed the following:

This solved the java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory issues (it doesn't seem to be the correct solution for this, though), but now the ObjectFactory cannot be located though they were generated.

Update 2

I'm using now a modified jaxb-osgi bundle (see issue) and Apache Aries SPI Fly Dynamic Weaving Bundle (1.3.2) (the reference implementation of the OSGi ServiceLoader Mediator specification) and I added the following requirements to the core module M:

Require-Capability: [...],osgi.extender;filter:="(o
 sgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:=
 "(osgi.serviceloader=javax.xml.bind.JAXBContextFactory)";cardinality:=m
 ultiple,[...]"

The services seem to get detected:

2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.xml.bind.v2.JAXBContextFactory of service javax.xml.bind.JAXBContextFactory in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.code_injector.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.locator.SourceLocationAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.sync.SynchronizedMethodAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.at_generated.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.episode.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.accessors.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi

But I still get:

javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
 - with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory not found by 

Why does it try to load the hard-coded default com.sun.xml.bind.v2.ContextFactory instead of com.sun.xml.bind.v2.JAXBContextFactory via ServiceLoader?

Upvotes: 4

Views: 5266

Answers (1)

Piotr P. Karwasz
Piotr P. Karwasz

Reputation: 16045

Since each OSGI bundle uses its own classloader the JAXB API is not able to use the standard ServiceLoader to locate the JAXB implementation. However since version 2.2.2 the JAXB API can use osgi-resource-locator as a fallback.

Therefore, in order to use JAXB on Java 11, you just need to:

  1. Add a dependency on the javax.xml.bind and org.glassfish.hk2.osgiresourcelocator packages,
  2. Deploy the osgi-resource-locator and jaxb-osgi bundles together with your bundle.

Remark: if you want to use MOXy, you need additional steps, since MOXy does not ship with a META-INF/services/javax.xml.bind.JAXBContext file (cf. this answer).

Upvotes: 6

Related Questions