简体   繁体   中英

How can I bundle the JAXB runtime libraries with OpenJDK 11?

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, eg 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 java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector.<clinit>(Injector.java:182)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:66)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:164)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.optimize(Accessor.java:270)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.property.ArrayProperty.<init>(ArrayProperty.java:53)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.<init>(ArrayERProperty.java:73)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:85)
    at java.xml.bind@10.0.2/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 java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:499)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:316)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
    at java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1141)
    at java.xml.bind@10.0.2/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 java.xml.bind@10.0.2/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:282)
    at java.xml.bind@10.0.2/javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:271)
    at java.xml.bind@10.0.2/javax.xml.bind.ContextFinder.find(ContextFinder.java:406)
    at java.xml.bind@10.0.2/javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:706)
    at java.xml.bind@10.0.2/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 java.xml.bind@10.0.2/com.sun.xml.internal.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:186)
    at java.xml.bind@10.0.2/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 :

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'

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

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.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM