Jabref: Java 9/JDK9 compatibility - blocks: Java 11/JDK11 compatibility

Created on 28 Feb 2017  路  37Comments  路  Source: JabRef/jabref

JabRef does not run on Java9

This issue collects all java 9 related problems. Starting point: http://discourse.jabref.org/t/cannot-start-jabref-3-7-3-6-using-java-9-on-ubuntu-16-04/361/8

Not supported JREs

This presents some JRE outputs to support issue finding during search.

Keywords: Java9, Java 9, JRE9, JRE 9

openjdk version "9.0.1"
OpenJDK Runtime Environment (build 9.0.1+11-Debian-1)
OpenJDK 64-Bit Server VM (build 9.0.1+11-Debian-1, mixed mode)

Development hints

build-system

Most helpful comment

Maybe now it is more reasonable to transfer to Java 11 LTS?

All 37 comments

Apple/OSX compatibility:

These new methods replace the functionality of the internal APIs contained in the OS X package com.apple.eawt which are not accessible by default in JDK 9. Note that the package com.apple.eio is no longer accessible and no public replacement exists in JDK 9.

http://openjdk.java.net/jeps/272
http://download.java.net/java/jdk9/docs/api/java/awt/Desktop.html#setOpenFileHandler-java.awt.desktop.OpenFilesHandler-

Please note that for Mac OS, notifications are only sent if the Java app is a bundled application, with a CFBundleDocumentTypes array present in its Info.plist. See the Info.plist Key Reference for more information about adding a CFBundleDocumentTypes key to your app's Info.plist.

I get the following error when trying to run JabRef on Linux with OpenJDK9. Should I file a new ticket for this?

>

kai@chipad:~/Downloads$ java -jar ./JabRef-3.8.2.jar
Apr 17, 2017 10:42:01 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
10:42:02.130 [AWT-EventQueue-0] INFO  net.sf.jabref.migrations.PreferencesMigrations - Migrating old custom entry types.
10:42:02.389 [AWT-EventQueue-0] ERROR net.sf.jabref.FallbackExceptionHandler - Uncaught exception Occurred in Thread[AWT-EventQueue-0,6,main]
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
    at net.sf.jabref.logic.importer.ImportFormatReader.resetImportFormats(ImportFormatReader.java:56) ~[JabRef-3.8.2.jar:?]
    at net.sf.jabref.JabRefMain.start(JabRefMain.java:78) ~[JabRef-3.8.2.jar:?]
    at net.sf.jabref.JabRefMain.lambda$main$0(JabRefMain.java:40) ~[JabRef-3.8.2.jar:?]
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313) ~[?:?]
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:759) ~[?:?]
    at java.awt.EventQueue.access$500(EventQueue.java:97) ~[?:?]
    at java.awt.EventQueue$3.run(EventQueue.java:712) ~[?:?]
    at java.awt.EventQueue$3.run(EventQueue.java:706) ~[?:?]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:88) ~[?:?]
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:729) ~[?:?]
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:199) [?:?]
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) [?:?]
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) [?:?]
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) [?:?]
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:?]
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) [?:?]
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:533) ~[?:?]
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:186) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:476) ~[?:?]
    ... 17 more

Thanks for your report. this is a problem we still have to solve.
A while ago I posted a workaround: You need to clone the repo and compile the code (with jdk8) for yourself using ./gradlew build (ignore the failing tests). That will generate some startup scripts that work with jdk9

As jdk9 is on it's way to the final release, we definitely should focus on getting JabRef to work with jdk9.

Okay, the final release of java 9 is out and I played around with jdeps to anaylze dependencies to internal jdk libs:
To summarize:
controlsfx
Our custom hack
and wiremock

build -> JDK removed internal API
build -> javafx.controls
build -> javafx.graphics
   org.jabref.gui.customjfx.CustomJFXPanel            -> com.sun.javafx.embed.EmbeddedSceneInterface        JDK internal API (javafx.graphics)
   org.jabref.gui.fieldeditors.EditorTextArea         -> com.sun.javafx.scene.control.behavior.BehaviorBase JDK internal API (javafx.controls)
   org.jabref.gui.fieldeditors.EditorTextArea         -> com.sun.javafx.scene.control.behavior.TextAreaBehavior JDK internal API (javafx.controls)
   org.jabref.gui.fieldeditors.EditorTextArea         -> com.sun.javafx.scene.control.skin.TextAreaSkin     JDK internal API (JDK removed internal API)
   org.jabref.gui.fieldeditors.EditorTextArea$1       -> com.sun.javafx.scene.control.skin.TextAreaSkin     JDK internal API (JDK removed internal API)
   org.jabref.logic.l10n.LocalizationParser           -> com.sun.javafx.application.PlatformImpl            JDK internal API (javafx.graphics)
customjfx-1.0.0.jar -> javafx.base
customjfx-1.0.0.jar -> javafx.graphics
   org.jabref.gui.customjfx.support.InputMethodSupport -> com.sun.javafx.collections.ObservableListWrapper   JDK internal API (javafx.base)
   org.jabref.gui.customjfx.support.InputMethodSupport$InputMethodRequestsAdapter -> com.sun.javafx.scene.input.ExtendedInputMethodRequests JDK internal API (javafx.graphics)
objenesis-2.6.jar -> jdk.unsupported
   org.objenesis.instantiator.sun.UnsafeFactoryInstantiator -> sun.misc.Unsafe                                    JDK internal API (jdk.unsupported)
   org.objenesis.instantiator.util.ClassDefinitionUtils -> sun.misc.Unsafe                                    JDK internal API (jdk.unsupported)
   org.objenesis.instantiator.util.UnsafeUtils        -> sun.misc.Unsafe                                    JDK internal API (jdk.unsupported)
wiremock-2.8.0.jar -> java.xml
   com.github.tomakehurst.wiremock.matching.EqualToXmlPattern$SkipResolvingEntitiesDocumentBuilderFactory -> com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl JDK internal API (java.xml)


Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependence on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

JDK Internal API                         Suggested Replacement
----------------                         ---------------------
sun.misc.Unsafe                          See http://openjdk.java.net/jeps/260

Controlsfx has a java9 comptaible 9.0.0 release http://fxexperience.com/controlsfx/
FontawesomeFX is working on java 9 support: https://bitbucket.org/Jerady/fontawesomefx/issues/48/cssparser-unavailable-in-java-9

FontawesomeFX 9.0.0 is out, with java 9 module support
http://www.jensd.de/wordpress/?p=2686

wiremock shouldn't be a problem as it is only used in the tests

So just to sum up and make sure that I understand everything: Our major problems with Java 9 are:

  • Some apple extensions are gone and we are going to need special packaging for IOS?
  • We need a release of OpenJDK with a fix to the special characters bug (did they honestly push the fix that they already implemented to v10 as in Java 10? Please tell me this is not true) or we need to change our local fix for it (this smells very much like a blocker).

The main blocker is that we have to adjust our start build scripts/installer to add these command line parameter for module config stuff.
https://docs.oracle.com/javase/9/migrate/toc.htm#JSMIG-GUID-7744EF96-5899-4FB2-B34E-86D49B2E89B6

Apple Extensions have somehow been directly incorporated (If I read the changelog correct)

@lenhard Since OracleJDK is a somehow a commerical product, there won't be any backport. We can either skip Java9 or change our local fix. @Siedlerchr or @lenhard Can you create an issue at https://github.com/JabRef/org.jabref.gui.customjfx.support/issues so that we can track that?

I began a skeletton for working on the Java9 support at https://github.com/JabRef/jabref/pull/3425

Feel free to continue. I personally could have time in December or January for that, but not earlier.

@koppor The fix was in the OpenJDK - There we did get the fixed code
https://bugs.openjdk.java.net/browse/JDK-8185792

I think that jgoodies is going to become a major problem. The versions we use seem to use internal APIs (correct me if I'm wrong) and the newer versions of jgoodies are no longer free.

Hence, we will need to replace the usage of jgoodies, but it is used in so many places. The default look and feels are even based on it.

Time to migrate all to javafx. For java 9 there are compatibility switches to allow internal API access. To see what deps use internal apis you can run the jdeps cli Tool fRom the jdk9

I have inspected the libraries we use. jgoodies-common and jgoodies-forms seem to be fine (haven't seen JDK internal API there), but for for jgoodies-looks, there's this dependency:

on jgoodies-looks-2.7.0.jar   com.jgoodies.looks.windows  -> com.sun.java.swing.plaf.windows  JDK internal API (java.desktop)

If I interpret everything right that means that we don't have too much pressure from jgoodies for layouting (good), but we'll have to find a solution for the look and feels. That might be small code changes, but with a wider effect.

A nice guide for legacy conversion to java 9
https://techbeacon.com/legacy-developers-guide-java-9

@lenhard If that is the only dependency, maybe we can patch jgoodies-looks to use UIManager.getSystemLookAndFeelClassName() instead? (See https://docs.oracle.com/javase/8/docs/technotes/guides/swing/1.4/Post1.4.html). Maybe, we can even go without patching if we avoid the respective method in JGoodies looks to be used at all? ^^

@koppor We might be able to do that. But instead of endlessly sticking to arcane technology (jgoodies has left open source almost three years ago), I am for cutting it and moving forward. Maybe we should be looking for newer look and feels instead?

We can discuss this of course.

Migration to Java9 should also offer easy extraction/separation of libraries such as org.jabref.model. Refs https://github.com/JabRef/jabref/issues/110.

@florian-beetz Did you see this issue yet? Maybe relevant.

Maybe now it is more reasonable to transfer to Java 11 LTS?

Java 11 would definitely be our goal. However, as this builds on java module system introduced in 9, the key problems (some external dependencies) remain

JabRef 3.8.2 (bundled in Ubuntu 18.10) does not start because of the following error

Error occurred during initialization of boot layer
java.lang.module.FindException: Module java.se.ee not found

Ubuntu 18.10 uses this as default JRE:

$ java -version 
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)

I also tried with Oracle JRE 11:

$ java -version 
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)

which resulted in the same error...

JabRef 3.8.2 is really old. I suggest you use the latest development version from https://builds.jabref.org/master/
However, it still requires Java 8.as default. In addtion it requires openjfx installed or oraclejkd8

@Siedlerchr How to run it?

$ java -jar ./JabRef--master--latest.jar
Error: Could not find or load main class org.jabref.JabRefMain
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

Please be careful when upgrading from 3.8 to a 4.* version!
4.* will modify the structure of your bib file and you can not step back to 3.8 then. Make a backup!

And the UI of 4.* has its own "problems". So plesae do your own test with it before you really switch the version.

This problem has gotten worse since the release of Ubuntu 18.10 (Cosmic Cuttlefish). This version of Ubuntu no longer ships openjfx for java 8, and instead only ships a version for java 11, which does not work with JabRef.

Is there any estimate as to when JabRef will be compatible, or should I install oracle jdk 8 in the meantime?

EDIT: I tried running the latest development build here, not an old 3.8.x version.

The more participants in #hacktoberfest, the earlier. See also
https://help.jabref.org/en/FAQcontributing. We welcome new contributors.
All of us are working in our free time on JabRef.

The main problem right now is that some libraries that we use are not yet compatible with Java 9. So we will have to wait until this is fixed (or look for alternative solutions).

So for now it is probably the best to install jdk 8 yourself.

Is there a list of these libraries somewhere? A lot of the time, this can be circumvented by using automatic module names which can be generated with jar --file=foo.jar --describe-module, and then adding those libraries as requirements in jabref's module file which seems to exist already

See https://github.com/JabRef/jabref/pull/3421#issuecomment-389229101 and the other comments in this PR. As you seem to be knowledgeable about the Java 9 stuff, you might want to join forces with @florian-beetz .

As JRE we opted for Liberica JDK, because it included JavaFX directly, which should not cause any issues during installation (additional JMOD file etc). (This should be written down as MADR)

Superseeded by PR #3421

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JoKalliauer picture JoKalliauer  路  3Comments

a-torgovitsky picture a-torgovitsky  路  3Comments

Siedlerchr picture Siedlerchr  路  4Comments

tobiasdiez picture tobiasdiez  路  4Comments

LinusDietz picture LinusDietz  路  3Comments