Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid JAXB default factory class on JavaSE 11 #78

Closed
bravehorsie opened this issue Nov 8, 2018 · 56 comments · Fixed by #100
Closed

Invalid JAXB default factory class on JavaSE 11 #78

bravehorsie opened this issue Nov 8, 2018 · 56 comments · Fixed by #100

Comments

@bravehorsie
Copy link
Contributor

    private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";

Jaxb api uses invalid default factory class which referes to JDK versions, which has included JAXB implementation. Since JDK 11 it is no longer valid. Default factory class should be "com.sun.xml.bind.v2.ContextFactory" without "internal" so it takes jaxb-ri as default or should be excluded completely printing describing error message when no implementation is found.

See javax.xml.bind.ContextFinder

@col-panic
Copy link

col-panic commented Dec 12, 2018

Facing the same problem here, porting my application (to java version "11.0.1" 2018-10-16 LTS). Starting the application leaves me with

javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[na:na]
	at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[na:na]
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[na:na]
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[na:na]
	at ch.elexis.core.common.DBConnection.unmarshall(DBConnection.java:133) ~[na:na]
	at info.elexis.server.core.connector.elexis.common.ElexisDBConnectionUtil.<clinit>(ElexisDBConnectionUtil.java:40) ~[na:na]
	at info.elexis.server.core.connector.elexis.internal.Activator.start(Activator.java:33) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:782) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1) ~[na:na]
	at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:775) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:732) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1005) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:357) ~[na:na]
	at org.eclipse.osgi.container.Module.doStart(Module.java:584) ~[na:na]
	at org.eclipse.osgi.container.Module.start(Module.java:452) ~[na:na]
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:471) ~[na:na]
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) ~[na:na]
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:557) ~[na:na]
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:331) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:473) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:414) ~[na:na]
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:153) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:612) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.initDependencyManagers(AbstractComponentManager.java:992) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1019) ~[na:na]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:860) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:755) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430) ~[na:na]
	at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657) ~[na:na]
	at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341) ~[na:na]
	at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:387) ~[na:na]
	at org.apache.felix.scr.impl.Activator.access$200(Activator.java:52) ~[na:na]
	at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:262) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:139) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:49) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:475) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1) ~[na:na]
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) ~[na:na]
	at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:911) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:151) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:233) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:140) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:132) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:194) ~[na:na]
	at org.eclipse.osgi.container.Module.publishEvent(Module.java:479) ~[na:na]
	at org.eclipse.osgi.container.Module.start(Module.java:470) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1685) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1664) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1627) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1558) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:343) ~[na:na]
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:135) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[na:na]
	at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[na:na]
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276) ~[na:na]
	... 62 common frames omitted

@lukasj
Copy link
Contributor

lukasj commented Dec 12, 2018

this should be fixed in 2.3.2, right @bravehorsie ?

@col-panic
Copy link

Is 2.3.2 already available? I saw that there is a name change to jakarta.xml.bind - but although there is a release available on this site, I can't find the respective artifacts on mavencentral.

@lukasj
Copy link
Contributor

lukasj commented Dec 12, 2018

Not yet, it's available only for testing in the sonatype's staging repo (so still subject to change)

@col-panic
Copy link

As soon, as @bravehorsie might confirm that a patch is already provided in 2.3.2 i could test it for my scenario!

@col-panic
Copy link

Please also confirm, that this package works under osgi - I just checked out the source and manually altered the above mentioned string. Yet a startup within an osgi setting is not possible.

@bravehorsie
Copy link
Contributor Author

No it is not fixed. There was an issue reported that this change will break CTS Glassfish tests for the first Jakarta release and should be left in place as was for JavaSE 8, so there is less work on fixing CTS tests.
@lukasj If that is not the issue anymore I will create a PR.

@bravehorsie
Copy link
Contributor Author

@col-panic It was fixed once in jaxb-api 2.4.0-b180830.0359 but was reverted back in 2.3.1 due to above error report.

@col-panic
Copy link

@bravehorsie I see that you already have a multi-release bundle, wouldn't it be possible to extract this constant into a separate class, and overriding this class in a >= Java 11 bundle only? The tests should stay ok then, no?

So whats the overall state for this on Java 11?

@col-panic
Copy link

I just tried the version mentioned (2.4.0-b180830.0359) - yet I can't seem to get it work in an osgi environment (Java 11.0.1 / org.eclipse.osgi_3.13_100.v20180827-1536), the stack trace is the same, but with different name

javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:269) ~[na:na]
	at javax.xml.bind.ContextFinder.find(ContextFinder.java:412) ~[na:na]
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[na:na]
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[na:na]
	at ch.elexis.core.common.DBConnection.unmarshall(DBConnection.java:133) ~[na:na]
	at info.elexis.server.core.connector.elexis.common.ElexisDBConnectionUtil.<clinit>(ElexisDBConnectionUtil.java:40) ~[na:na]
	at info.elexis.server.core.connector.elexis.internal.Activator.start(Activator.java:33) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:782) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1) ~[na:na]
	at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:775) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:732) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1005) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:357) ~[na:na]
	at org.eclipse.osgi.container.Module.doStart(Module.java:584) ~[na:na]
	at org.eclipse.osgi.container.Module.start(Module.java:452) ~[na:na]
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:471) ~[na:na]
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) ~[na:na]
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:557) ~[na:na]
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:331) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:473) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422) ~[na:na]
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:414) ~[na:na]
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:153) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:612) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.initDependencyManagers(AbstractComponentManager.java:992) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1019) ~[na:na]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:860) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:755) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675) ~[na:na]
	at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430) ~[na:na]
	at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657) ~[na:na]
	at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341) ~[na:na]
	at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:387) ~[na:na]
	at org.apache.felix.scr.impl.Activator.access$200(Activator.java:52) ~[na:na]
	at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:262) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:139) ~[na:na]
	at org.apache.felix.scr.impl.AbstractExtender.addingBundle(AbstractExtender.java:49) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:475) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1) ~[na:na]
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) ~[na:na]
	at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229) ~[na:na]
	at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450) ~[na:na]
	at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:911) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:151) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:233) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:140) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:132) ~[na:na]
	at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:194) ~[na:na]
	at org.eclipse.osgi.container.Module.publishEvent(Module.java:479) ~[na:na]
	at org.eclipse.osgi.container.Module.start(Module.java:470) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1685) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1664) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1627) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1558) ~[na:na]
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233) ~[na:na]
	at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:343) ~[na:na]
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:135) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
	at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[na:na]
	at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[na:na]
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:267) ~[na:na]
	... 62 common frames omitted

I'm not sure whether this problem belongs here, so I cross-posted this in https://www.eclipse.org/forums/index.php/t/1096601/

@col-panic
Copy link

@bravehorsie
Copy link
Contributor Author

@col-panic com.sun.xml.bind.v2.ContextFactory is in org.glassfish.jaxb:jaxb-runtime artifact. The ClassNotFound error probably means that you either:

  • haven't put jaxb-runtime jar at class path or module path at all
  • have put it to module path but didn't add com.sun.xml.bind module to module graph with either --add-modules or by requiring in your project module.
  • put jaxb-api to module path and jaxb-runtime to classpath and so API doesn't read the implementation in order to create factory.

I see that you already have a multi-release bundle, wouldn't it be possible to extract this constant into a separate class, and overriding this class in a >= Java 11 bundle only?

Yes, that would work, but after configuring jaxb properly you should not need it.

@lukasj
Copy link
Contributor

lukasj commented Dec 13, 2018

what about targeting 2.4.0 for JDK 11+ and 2.3.x for JDK 8+? 2.3.x should be doable ie as @col-panic suggests (multi-release jar) or by adding additional 'try' option to lookup non-internal version of the ContextFactory.

There are two additional things we probably should keep in mind:

  1. with JAXB-RI removal from JDK, by default, there is no implementation for the API to work with, so the existing lookup for com.sun.xml.{internal.}bind.v2.ContextFactory should probably be removed unless the spec says the opposite; there is also an option to follow what JAF or mail is doing - providing somegroupId:jakarta.xml.bind artifact being API+impl bundle
  2. there is MOXy (other JAXB implementation)

@col-panic
Copy link

@bravehorsie thanks, ... this is a real pain, so there seem two be 2 possible solutions in an OSGI setting

  1. Add the patch from https://sjhannah.com/blog/2018/11/21/jaxb-hell-on-jdk-9/ then directly deliver all required libraries with the osgi bundle (each added to the runtime) - this somehow seems to work out, but is not a viable solution
  2. Extend the JRE with --add-modules to include all jaxb requirements - I made this to some point but am stuck with Module com.sun.xml.txw2 not found, required by com.sun.xml.bind

Why does the classloader in at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:135) ~[na:na] not simply resolve com.sun.xml.bind.v2.ContextFactory if it is available in the runtime in the form of org.glassfish.jaxb.runtime?

Is the whole setting of using Java11/Osgi/JAXB Implementation tested somewhere?

@lukasj
Copy link
Contributor

lukasj commented Dec 13, 2018

org.glassfish.jaxb* artifacts we're never intended for usage in OSGi environment (this will very likely change rather sooner than later); if you need OSGi, then com.sun.xml.bind:jaxb-osgi is what one needs (it's being consumed by GlassFish - which is OSGi based, or latest eclipselink)

@col-panic
Copy link

@lukasj Thank you very much for that hint, I think it works now! With jaxb-api 2.4.0-b180830.0359 and com.sun.xml.bind.jaxb-osgi(2.4.0b180830_0438)

@col-panic
Copy link

@lukasj it only works with my manually modified version of jaxb-api, where I additionally add
Import-Package: com.sun.xml.bind.v2;resolution:=optional to MANIFEST.MF

@lukasj
Copy link
Contributor

lukasj commented Dec 13, 2018

it may not be required if methods taking classloader as an argument (such as JAXBContext.newInstance(String contextPath, ClassLoader classLoader)) are used. Problem here is related to the behaviour of ServiceLoader in OSGi

@bravehorsie
Copy link
Contributor Author

Is the whole setting of using Java11/Osgi/JAXB Implementation tested somewhere?

Its tested in Glassfish for Java8. However in OSGi, where it is all loaded from classpath it should not matter if it is used on 11.

It is tested externally to be usable on module path outside of OSGi. OSGi and JPMS doesn't relate to each other.

@col-panic
Copy link

@lukasj now it seems to work out! I added Import-Package: com.sun.xml.bind.v2 to my consumer bundle, and extended JAXBContext.newInstance with my own classloader! Thanks a lot!

@col-panic
Copy link

col-panic commented Jan 21, 2019

Although the approach with extending JAXBContext.newInstance works - I don't like it that much, as it forces me to change a lot of code.

So instead I built a multi-release fragment attaching to jaxb-api, that imports the package com.sun.xml.bind.v2 for java > 8.

See elexis/elexis-3-core@5ee9a7e for the resp. patch provided to our project.

@col-panic
Copy link

I did a short blog post summing all the steps and troubles http://www.descher.at/descher-vu/2019/01/java-11-jaxb-and-osgi/

@lukasj
Copy link
Contributor

lukasj commented Jan 21, 2019

you should use 2.3.2 instead of 2.4.0-b1808whaever or wait for some 2.4.0 build from this year coming from this repo

@col-panic
Copy link

will do, as soon as jaxb-api is publicly available in version 2.3.2, will do for the others (jaxb-osgi) right now

@lukasj
Copy link
Contributor

lukasj commented Jan 24, 2019

It already is: https://repo1.maven.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/2.3.2/

@col-panic
Copy link

And with 2.3.2 we face the original error ... [java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory - reminds me why I have to use 2.4.0whatever

@bravehorsie
Copy link
Contributor Author

Does your environment support Multi-Release JAR Files, or does it override this functionality provided by JDK9+ in any way?
On JDKs > 1.8 a class ModuleUtil referencing the old factory should not be loaded.

@col-panic
Copy link

I'm not sure. I use OSGi (Equinox), which from R7 supports Multi-Release Jars. It could well be, that it's behaviour is different, to that of the "plain multi-release jar support".

@krishnaUsharani
Copy link

Facing same issue with jaxb 2.2.11 version. Please suggest in fixing this issue:

javax.xml.bind.DataBindingException: 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.internal.bind.v2.ContextFactory]
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:260) ~[jaxb-api-2.3.1.jar!/:2.3.0]

@vladimirfx
Copy link
Contributor

It would be nice to see 2.3.3 release ;)

@CardContact
Copy link

Any news on this issue ?

The latest CXF 3.3.2 in Equinox is also failing with "Implementation of JAXB-API has not been found on module path or classpath", when wired to com.sun.xml.bind:jaxb-osgi:2.3.2.

CXF also uses the JABXContext.newInstance(Class...) variant that does not allow overwriting the context class loader (see #99).

@StepeCZ
Copy link

StepeCZ commented Sep 16, 2019

Hi, I read all information on this issue, including the blog summary, but still I´m unable to get it resolved.
In my case I´m not using Java modules explicitly, Im just trying to compile Java8 project on Java11/12. Based on information gathered I should be fine with adding the right dependencies on classpath in the old-school style, i.e. declaring them in Gradle.

Can someone explain why the ContextFactory class is not found despite I´m instructing the use of correct package (i.e. without "internal") via system property and I can see very well the package/class exists and the jaxb-runtime.jar is on classpath.

I have following, but still the same ClassNotFoundException:

dependencies {
compile gradleApi(),
localGroovy(),
"com.sun.activation:javax.activation:1.2.0",
"jakarta.xml.bind:jakarta.xml.bind-api:2.3.2",
"com.sun.xml.bind:jaxb-osgi:2.3.2",
"org.glassfish.jaxb:jaxb-xjc:2.3.2",
"org.glassfish.jaxb:jaxb-core:2.3.0.1",

@lukasj
Copy link
Contributor

lukasj commented Sep 16, 2019

@StepeCZ how does your javac configuration look like? Generally speaking passing '-release 8' with no jaxb api/impl on the classpath/modulepath to javac from JDK 11 should just work as long as there is no dependency on implementation specific classes in your sources since JAXB as such was included in JDK 8. If you have some dependency on the implementation classes then all you should need is just an implementation on the classpath (jaxb-core and/or jaxb-impl is enough for just runtime - dependening on the specific version, -osgi is just all in one bundle of core/impl/xjc/jxc, api is included in JDK 8).

@StepeCZ
Copy link

StepeCZ commented Sep 16, 2019

@lukasj Thanks for the response. The project uses JAXB as part of the Gradle build to generate classes from XSD files etc. This is done by plugin which has all these JAXB related dependencies it works well on Java 8 but fails with this error on anything > Java 11. I still havent understood why JAXB classes are not visible to the Gradle build process, perhaps there is some special treating needed ... I added the dependency to buildscript section as well, but no luck so far.
I can see it is picked but error is thrown:

``
[org.gradle.internal.operations.DefaultBuildOperationExecutor] Build operation 'Resolve jaxb-runtime.jar (org.glassfish.jaxb:jaxb-runtime:2.3.2)' completed
[org.gradle.internal.component.model.ComponentAttributeMatcher] Selected match org.glassfish.jaxb:jaxb-runtime:2.3.2 configuration runtime from candidates [org.glassfish.jaxb:jaxb-runtime:2.3.2 configuration runtime] for {org.gradle.dependency.bundling=external, org.gradle.jvm.version=12, org.gradle.usage=java-runtime}

@lukasj
Copy link
Contributor

lukasj commented Sep 17, 2019

@StepeCZ I'm sorry but I have no idea about what gradle plugin nor it's version are you talking about. It could be a bug there as well. Another thing is that you said it's a problem on JDK11 first and now it is on 12. The best would be to file new issue and provide either some minimal project or steps to reproduce problems you're seeing together with environment description (OS/JDK at least). Thanks!

@mseele
Copy link

mseele commented Sep 24, 2019

When will the 2.3.3 release be pushed to repositories?
https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api still lists 2.3.2 as latest version.

@lukasj
Copy link
Contributor

lukasj commented Sep 24, 2019

@mseele central repository is the source of truth. Not having something available in mvnrepository.com does not necessarily imply it does not exist.

In any case, 2.3.3 is mostly ready and pushing the release itself to central is currently out of my control. I assume it is going to take ~2 weeks till it passes all necessary reviews required by https://jakarta.ee/about/jesp/

@mseele
Copy link

mseele commented Oct 16, 2019

@lukasj Still no 2.3.3 release. Is there any resource where the progress of reviews, etc. is documented?
Like a roadmap for the review!?

@lukasj
Copy link
Contributor

lukasj commented Oct 16, 2019

@mseele see jakartaee/specifications#44

@zhsc
Copy link

zhsc commented Oct 17, 2019

For anyone using bndtools this config seems to work:

add to your central.deps.maven (assuming using MavenBndRepository):

javax.xml.bind:jaxb-api:2.4.0-b180830.0359
com.sun.xml.bind:jaxb-osgi:2.4.0-b180830.0438
com.sun.activation:javax.activation:1.2.0

Then in your .bndrun file:

-runpath: \
	jaxb-api;version='[2.4.0,2.4.1)',\
	com.sun.xml.bind.jaxb-osgi;version='[2.4.0,2.4.1)',\
	com.sun.activation.javax.activation;version='[1.2.0,1.2.1)'

Note: the -runpath instruction will add it to the launcher's regular classpath, but include the bundles and expose those packages to the OSGi world via the systembundle for consumption.
See documentation here for details

Not the most ideal since it's really bypassing the OSGi bundle mechanism's here, but it gets you going until this can be resolved.

@kevin-cat
Copy link

对于使用bndtools的任何人,此配置似乎都有效:

添加到您的central.deps.maven中(假设使用MavenBndRepository):

javax.xml.bind:jaxb-api:2.4.0-b180830.0359
com.sun.xml.bind:jaxb-osgi:2.4.0-b180830.0438
com.sun.activation:javax.activation:1.2.0

然后在您的.bndrun文件中:

-runpath: \
	jaxb-api;version='[2.4.0,2.4.1)',\
	com.sun.xml.bind.jaxb-osgi;version='[2.4.0,2.4.1)',\
	com.sun.activation.javax.activation;version='[1.2.0,1.2.1)'

注意:-runpath指令会将其添加到启动器的常规类路径中,但包括捆绑软件,并将这些软件包通过systembundle公开给OSGi世界以供使用。
有关详细信息,请参见此处的文档

这不是最理想的选择,因为它实际上绕过了OSGi捆绑程序机制,但是它可以帮助您解决问题。

我添加了你说的三个依赖,已经解决了问题,3q

@mathew-ferry13
Copy link

@lukasj Any update on a 2.3.3 getting pushed up to mvnrepository?

@Sanne
Copy link

Sanne commented Nov 14, 2019

@mseele central repository is the source of truth. Not having something available in mvnrepository.com does not necessarily imply it does not exist.

@lukasj true what matters is central, not mvnrepository.com . Please note though that while the request of others might have been unclear, it's not available in Maven Central either.

@lukasj
Copy link
Contributor

lukasj commented Nov 14, 2019

still waiting for getting approval from ee4j PMC

@mseele
Copy link

mseele commented Nov 28, 2019

@lukasj what is the problem of getting approval from ee4j PMC? Is there anything we can help with?

@mathew-ferry13
Copy link

@lukasj Any update on this?

@bravehorsie
Copy link
Contributor Author

2.4.0-b180830.0359 version of jsonb-api doesn't have the problematic default factory class included in case anyone is in haste for the fix. I guess it can be safely used besides its beta, because the only significant change between this version and curretnly the latest 2.3.1 in public repository was reintroducing problematic ".internal" package.

@lukasj
Copy link
Contributor

lukasj commented Feb 6, 2020

version 2.4.0-b180830.0359 has different license - may or may not be an issue.

in any case ballot for 2.3.3 has already been started, see https://www.eclipse.org/lists/jakarta.ee-spec/msg00593.html for details

@vidhikapoor1990
Copy link

Hello,
In our application we have upgraded to JAVA 11 .After intergrating the JAXB-API(2.3) ,JAXB-Runtime(2.3) and activation(1.1).
I am still getting exception :
Implementation of JAXB-API has not been found on module path or classpath.

  • with linked exception:
    [java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
    our application is OSGI complaint,
    Could you please suggest ,how to resolve this error

@FelixJongleur42
Copy link

org.glassfish.jaxb* artifacts we're never intended for usage in OSGi environment (this will very likely change rather sooner than later); if you need OSGi, then com.sun.xml.bind:jaxb-osgi is what one needs (it's being consumed by GlassFish - which is OSGi based, or latest eclipselink)

Solved it for me, thank you!

@donatelloOo
Copy link

donatelloOo commented Feb 5, 2021

Still having the issue with following dependencies in the classpath running on JDK11 (oracle):

            <dependency>
                <groupId>jakarta.xml.bind</groupId>
                <artifactId>jakarta.xml.bind-api</artifactId>
                <version>2.3.3</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jaxb</groupId>
                <artifactId>jaxb-runtime</artifactId>
                <version>2.3.3</version>
            </dependency>
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]
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:232)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
    [...]
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory
  at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
  at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
  at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:92)
  at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:125)
  at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:230)
  ... 90 more

What do you suggest ?

@donatelloOo
Copy link

See my comment here, when current thread classloader is a PlatformClassLoader, the JAXB runtime MUST be in added as a module in order to be available.

https://stackoverflow.com/questions/54632086/java-11-implementation-of-jaxb-api-has-not-been-found-on-module-path-or-classpa/66068044#66068044

@bourgesl
Copy link

Here is my solution using JAXB 2.3.3 (on jdk8 to 16) to explicitely define the ContextFactory class:

    /** JAXB implementation 2.3.0 provided in JMCS libraries */
    private static final String JAXB_CONTEXT_FACTORY_IMPLEMENTATION = "com.sun.xml.bind.v2.ContextFactory";

    static {
        // Define the system property to define which JAXB implementation to use:
        System.setProperty("javax.xml.bind.JAXBContextFactory", JAXB_CONTEXT_FACTORY_IMPLEMENTATION);
        System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, JAXB_CONTEXT_FACTORY_IMPLEMENTATION);

        if (org.apache.commons.lang.SystemUtils.JAVA_VERSION_FLOAT >= 16.0f) {
            // JDK16 support fix:
            /*
                ERROR [main] com.sun.xml.bind.v2.runtime.reflect.opt.Injector - null
                java.security.PrivilegedActionException: null
                Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
                    at java.base/java.lang.Class.getMethod(Class.java:2195)
                    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:170)
                    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:166)
                    at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)
            */
            final String key = "com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize";
            System.setProperty(key, "true");
            logger.info("Fix JDK-16+ support: version = {} (set {} = true)", 
                    org.apache.commons.lang.SystemUtils.JAVA_VERSION_FLOAT, key);
        }
        logger.info("JAXB ContextFactory: {}", System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY));
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.