Reputation: 321
Background:
In my organization there are a lot of Java based Windows desktop applications. In our proprietary software deployment system the applications don't contain an individual JRE / JDK. Rather a common JRE (so far Oracle 8 Java SE JRE) is deployed to the users machine, which is attached to the individual applications based on environment variables.
We would like to migrate the JRE from Oracle 8 Java SE JRE to OpenJDK 11 without having to modify the applications. From Java 8 to Java 11 various libraries got removed, e. g. JavaFX. Using the Java module system and the jlink tool, I can create my own proprietary JDK enhanced with OpenJFX:
jlink --module-path ..\mods;C:\Temp\javafx-jmods-11.0.2 --add-modules=ALL-MODULE-PATH,java.base,java.compiler,java.datatransfer,java.desktop,... --output C:\Temp\OpenJDK+OpenJFX
Applications, which need JavaFX can use this proprietary JDK without being changed.
When I try to apply the same method to the latest beta of JAXB, I get the following error:
jlink --module-path ..\mods;C:\Temp\jaxb-ri-2.4.0-b180830.0438\jaxb-ri\mod --add-modules=java.xml.bind,java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,... --output C:\Workspace\Java\OpenJDK_11.0.2_JFX_JAXB
Error: automatic module cannot be used with jlink: java.activation from file:///C:/Temp/jaxb-ri-2.4.0-b180830.0438/jaxb-ri/mod/javax.activation-api.jar
As per https://github.com/eclipse-ee4j/jaf/issues/13, "JAXB API uses activation-api as its dependency and is forced to use it as an automatic module or from classpath because of missing a module-info.java descriptor file."
Furtheron as per Is it possible to use jlink on JDK 11 to make a runtime including the Java SE EE modules that were removed? I can bundle the module java.xml.bind using jlink from Java 10, which still contained it. Indeed jlink succeeds, if I add two modules from OpenJDK 10.0.2 to the module path:
jlink --module-path ..\mods;C:\Temp\jdk-10.0.2\jmods\java.xml.bind.jmod;C:\Temp\jdk-10.0.2\jmods\java.activation.jmod --add-modules=java.xml.bind, ...
But when I run my application with the generated JDK, I get errors like this:
!ENTRY org.eclipse.osgi 4 0 2019-02-15 15:58:58.642
!MESSAGE Application error
!STACK 1
org.eclipse.e4.core.di.InjectionException: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:410)
at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:318)
at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:162)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createDefaultHeadlessContext(E4Application.java:491)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createDefaultContext(E4Application.java:505)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:204)
at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:614)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590)
at org.eclipse.equinox.launcher.Main.run(Main.java:1499)
Caused by: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:124)
at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:399)
... 22 more
Caused by: java.lang.ClassNotFoundException: javax.annotation.PostConstruct cannot be found by org.eclipse.e4.core.di_1.6.100.v20170421-1418
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:433)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:395)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:387)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:150)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 24 more
Or this:
Feb. 15, 2019 2:49:03 NACHM. com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector <clinit>
SEVERE: null
java.security.PrivilegedActionException: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String, [B, int, int, java.lang.ClassLoader, java.security.ProtectionDomain)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:182)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:66)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:164)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:270)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.property.ArrayProperty.<init>(ArrayProperty.java:53)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.<init>(ArrayERProperty.java:73)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:85)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:47)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:499)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:316)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1141)
at [email protected]/com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:150)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at [email protected]/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:282)
at [email protected]/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:271)
at [email protected]/javax.xml.bind.ContextFinder.find(ContextFinder.java:406)
at [email protected]/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:706)
at [email protected]/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:647)
at com.xxx.build.automation.utils.internal.CategoryFileHandler.unMarshalFile(CategoryFileHandler.java:17)
at com.xxx.build.automation.utils.common.GetComponentName.doExecuteInternal(GetComponentName.java:89)
at com.xxx.build.automation.utils.common.GetComponentName.execute(GetComponentName.java:72)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at jdk.internal.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:357)
at org.apache.tools.ant.Target.performTasks(Target.java:385)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
at org.apache.tools.ant.Main.runBuild(Main.java:758)
at org.apache.tools.ant.Main.startAnt(Main.java:217)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
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:2109)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:186)
at [email protected]/com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:182)
... 48 more
Question:
Is there any possibility, how I can bundle the JAXB libraries with OpenJDK 11?
Hint:
Upvotes: 20
Views: 8533
Reputation: 131
JAXB has been removed from JDK starting with version 11, you would need to add it as you add all other dependencies.
Example for maven:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb.api.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.api.version}</version>
</dependency>
Upvotes: 0
Reputation: 321
My organization finally gave in to modify the applications at compile time. It is not the solution I was searching for, but at least it works for us.
Upvotes: 0
Reputation: 158
Try to include these two dependencies:
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime'
Upvotes: 1
Reputation: 3337
If you are using javax
API modules, it is usually not possible to upgrade from jdk8 without modifying you application. Some implementations like com.sun
packages where physically removed since jdk9 and you have to add them as dependency.
You are also running into the java.lang.NoSuchMethodException
so the current available implementation is not compatible anymore with the javax
API from jdk10
Upvotes: 0