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

Java 9 Support #57

Open
swpalmer opened this issue Mar 9, 2017 · 28 comments
Open

Java 9 Support #57

swpalmer opened this issue Mar 9, 2017 · 28 comments

Comments

@swpalmer
Copy link

swpalmer commented Mar 9, 2017

To be clear, I have successfully used this plugin with Java 9, but the support is incomplete because of new options related to modularization.

In Java 9 the javapackager tool has an --add-modules option.

In fact if you run the jfxNative task with Java 9 you will see in the output something like this (note the references to modules):

:jfxNative
Putting task artifact state for task ':jfxNative' into context took 0.0 secs.
Executing task ':jfxNative' (up-to-date check took 0.0 secs) due to:
  Task has not declared any outputs.
Adding 'deploy' directory to classpath: src/main/deploy
Creating parameter-map for bundler 'ALL'
Add /Users/scott/dev/MyApplication/build/jfx/app/lib/somelibrary-3.0.3.jar file to application resources.
Add /Users/scott/dev/MyApplication/build/jfx/app/MyApplication-1.0.3.jar file to application resources.
Skipping 'WebStart JNLP Bundler' because of configuration error 'No OutFile Specificed'
Advice to fix: Please specify the name of the JNLP Outut file in 'jnlp.outfile'
Creating app bundle: /Users/scott/dev/MyApplication/build/jfx/native/MyApplication.app
Module jdk.jvmstat does not exist.
Module jdk.management.agent  does not exist.
Module java.management.rmi  does not exist.
Module jdk.vm.ci does not exist.
"Adding modules: [java.rmi, jdk.charsets, java.xml, jdk.xml.dom, java.datatransfer, jdk.httpserver, javafx.base, java.desktop, java.security.sasl, jdk.zipfs, java.base, jdk.crypto.ec, java.sql.rowset, javafx.swing, jdk.jsobject, jdk.sctp, java.smartcardio, jdk.unsupported, jdk.scripting.nashorn, java.security.jgss, java.compiler, javafx.graphics, javafx.fxml, jdk.dynalink, javafx.media, jdk.accessibility, jdk.security.jgss, java.sql, javafx.web, java.logging, java.xml.crypto, jdk.jfr, jdk.packager.services, jdk.net, java.naming, javafx.controls, java.prefs, jdk.naming.rmi, java.management, jdk.jdwp.agent, java.instrument, jdk.management, jdk.security.auth, java.scripting, jdk.naming.dns, jdk.localedata] to runtime image."
outputDir = /Users/scott/dev/MyApplication/build/jfx/native/MyApplication.app/Contents/PlugIns/Java.runtime/Contents/Home
modulePath = [/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods]
addModules = [java.rmi, jdk.charsets, java.xml, jdk.xml.dom, java.datatransfer, jdk.httpserver, javafx.base, java.desktop, java.security.sasl, jdk.zipfs, java.base, jdk.crypto.ec, java.sql.rowset, javafx.swing, jdk.jsobject, jdk.sctp, java.smartcardio, jdk.unsupported, jdk.scripting.nashorn, java.security.jgss, java.compiler, javafx.graphics, javafx.fxml, jdk.dynalink, javafx.media, jdk.accessibility, jdk.security.jgss, java.sql, javafx.web, java.logging, java.xml.crypto, jdk.jfr, jdk.packager.services, jdk.net, java.naming, javafx.controls, java.prefs, jdk.naming.rmi, java.management, jdk.jdwp.agent, java.instrument, jdk.management, jdk.security.auth, java.scripting, jdk.naming.dns, jdk.localedata]
limitModules = []

Those modules seem to have been picked up automatically. My application needs to explicitly add some modules that aren't automatically included though. E.g. java.xml.bind and java.xml.ws

So there needs to be a way to specify additional modules in the jfx configuration, or perhaps as a temporary workaround, just a way to specify additional options to javapackager in a raw form. It could work much like adding compiler options:

tasks.withType(JavaCompile) {
    if (JavaVersion.current().java9Compatible) {
        options.compilerArgs.add '--add-modules'
    	options.compilerArgs.add 'java.xml.bind,java.xml.ws'
    }
}

I think it is important to have support for Java 9 early, even if it might need to change. This allows issues to be reported against Java 9 so they can be fixed. If people can't build their projects with Java 9 they won't find out about issues until they are too late to fix for the Java 9 initial release.

@FibreFoX
Copy link
Owner

FibreFoX commented Mar 9, 2017

I do know this ;) it is a long time ago, that I had JDK9 installed. Will implement this, when JDK9 is official.

EDIT: I will look into this the next week, I need to think about developing with different JDKs ;) so this might take some while ... but shouldn't be that hard to implement

@FibreFoX FibreFoX self-assigned this Mar 9, 2017
@swpalmer
Copy link
Author

swpalmer commented Mar 9, 2017

You mention "when JDK9 is official". As I hinted at the end of description, I was hoping to build with Java 9-ea. (Java 9 has been feature complete for a while now, so I'm ramping up my testing efforts.) That's also why I mentioned the possibility of a more direct method of adding any arbitrary options. It may allow people to workaround this and future issues. Even if you don't have proper support until JDK 9 is official, perhaps you can point me to some way I could hack this in?

@purringpigeon
Copy link

purringpigeon commented Mar 9, 2017 via email

@FibreFoX
Copy link
Owner

FibreFoX commented Mar 9, 2017

@swpalmer nagging sometimes works ;) I will take a look into this the next days, if you need to fiddle with a local version, just look at the "workers": https://github.com/FibreFoX/javafx-gradle-plugin/tree/master/src/main/java/de/dynamicfiles/projects/gradle/plugins/javafx/tasks/workers

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 3, 2017

@swpalmer what EA-version are you using?

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 3, 2017

@purringpigeon @swpalmer This might even already be working, not sure and haven't digged too deep into this. Please try the following:

jfx{
    // ... other stuff ...
    bundleArguments = [
        'add-modules': 'java.xml.bind,java.xml.ws'
    ]
}

There is a lot of new stuff on a new location for parameter-map: https://github.com/teamfx/openjfx-9-dev-rt/blob/master/modules/jdk.packager/src/main/java/jdk/packager/internal/JLinkBundlerHelper.java#L83

Can you try that and report back?

@swpalmer
Copy link
Author

swpalmer commented Apr 4, 2017

Packaging still doesn't work with that. I get errors trying to copy jars into the application bundle, but the build continues and claims to succeed. Looking into the application bundle I can see that my jars are missing.
This is from the build log (slightly sanitized for the web):

:jfxNative
The jar lib/MyServer-3.1.3.jar has a main class my.company.myserver.MyServerMain that does not match the declared main my.company.myserver.ui.MyServerAdminApp
Creating app bundle: /Users/scott/dev/MyServerAdminApp/build/jfx/native/My Server Admin.app
Module jdk.jvmstat does not exist.
Module jdk.management.agent  does not exist.
Module java.management.rmi  does not exist.
Module jdk.vm.ci does not exist.
"Adding modules: [java.xml.bind, java.xml.ws, java.rmi, jdk.charsets, java.xml, jdk.xml.dom, java.datatransfer, jdk.httpserver, javafx.base, java.desktop, java.security.sasl, jdk.zipfs, java.base, jdk.crypto.ec, java.sql.rowset, javafx.swing, jdk.jsobject, jdk.sctp, java.smartcardio, jdk.unsupported, jdk.scripting.nashorn, java.security.jgss, java.compiler, javafx.graphics, javafx.fxml, jdk.dynalink, javafx.media, jdk.accessibility, jdk.security.jgss, java.sql, javafx.web, java.logging, java.xml.crypto, jdk.jfr, jdk.packager.services, jdk.net, java.naming, javafx.controls, java.prefs, jdk.naming.rmi, java.management, jdk.jdwp.agent, java.instrument, jdk.management, jdk.security.auth, java.scripting, jdk.naming.dns, jdk.localedata] to runtime image."
outputDir = /Users/scott/dev/MyServerAdminApp/build/jfx/native/My Server Admin.app/Contents/PlugIns/Java.runtime/Contents/Home
modulePath = [/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods]
addModules = [java.xml.bind, java.xml.ws, java.rmi, jdk.charsets, java.xml, jdk.xml.dom, java.datatransfer, jdk.httpserver, javafx.base, java.desktop, java.security.sasl, jdk.zipfs, java.base, jdk.crypto.ec, java.sql.rowset, javafx.swing, jdk.jsobject, jdk.sctp, java.smartcardio, jdk.unsupported, jdk.scripting.nashorn, java.security.jgss, java.compiler, javafx.graphics, javafx.fxml, jdk.dynalink, javafx.media, jdk.accessibility, jdk.security.jgss, java.sql, javafx.web, java.logging, java.xml.crypto, jdk.jfr, jdk.packager.services, jdk.net, java.naming, javafx.controls, java.prefs, jdk.naming.rmi, java.management, jdk.jdwp.agent, java.instrument, jdk.management, jdk.security.auth, java.scripting, jdk.naming.dns, jdk.localedata]
limitModules = []
excludeFileList = .*\.diz
stripNativeCommands = true
userArguments = {}
java.nio.file.NoSuchFileException: /Users/scott/dev/MyServerAdminApp/build/jfx/native/My Server Admin.app/Contents/Java/lib/MyServer-3.1.3.jar
java.nio.file.NoSuchFileException: /Users/scott/dev/MyServerAdminApp/build/jfx/native/My Server Admin.app/Contents/Java/lib/MyServer-3.1.3.jar
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:248)
        at java.base/sun.nio.fs.UnixCopyFile.copy(UnixCopyFile.java:586)
        at java.base/sun.nio.fs.UnixFileSystemProvider.copy(UnixFileSystemProvider.java:254)
        at java.base/java.nio.file.Files.copy(Files.java:1277)
        at jdk.packager/jdk.packager.builders.mac.MacAppImageBuilder.copyClassPathEntries(MacAppImageBuilder.java:457)
        at jdk.packager/jdk.packager.builders.mac.MacAppImageBuilder.prepareApplicationFiles(MacAppImageBuilder.java:387)
        at jdk.packager/jdk.packager.internal.JLinkBundlerHelper.execute(JLinkBundlerHelper.java:352)
        at jdk.packager/com.oracle.tools.packager.mac.MacAppBundler.doBundle(MacAppBundler.java:359)
        at jdk.packager/com.oracle.tools.packager.mac.MacAppBundler.execute(MacAppBundler.java:437)
        at de.dynamicfiles.projects.gradle.plugins.javafx.tasks.workers.JfxNativeWorker.jfxnative(JfxNativeWorker.java:348)
        at de.dynamicfiles.projects.gradle.plugins.javafx.tasks.JfxNativeTask.jfxnative(JfxNativeTask.java:32)

@swpalmer
Copy link
Author

swpalmer commented Apr 4, 2017

Note I am using 9-ea+163. Tried with Gradle 3.4.1 and 3.5-rc-2.

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 5, 2017

@swpalmer Are you using some IDE for this? Do you know if gradle is already fully compliant with jdk9? On what OS are you using this?

As there are a lot of internal changes, including the places where the packager-classes are, this might take some while and might break compatibility with jdk8 ... will look into this deeply but will take some time (this goes for the javafx-maven-plugin too).

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 6, 2017

@swpalmer Can you confirm, that it works with the javapackager itself? Coming from the sourcecode, it looks strange how the content inside that .cfg-files is gathered:

        // The main app is required to be a jar, modular or unnamed.
        if (mainJarType == Module.ModuleType.Unknown || mainJarType == Module.ModuleType.ModularJar) {
            if (mainModule != null) {
                out.println("app.mainmodule=" + mainModule); // TODO get app class from main module mainifest.
            }
        }
        else {
            String mainClass = JLinkBundlerHelper.getMainClass(params);

            if (mainJar != null && mainClass != null) {
                // If the app is contained in an unnamed jar then launch it the
                // legacy way and the main class string must be of the format com/foo/Main
                out.println("app.mainclass=" + mainClass.replaceAll("\\.", "/"));
                out.println("app.mainjar=" + mainJar.toPath().getFileName().toString());
            }
        }

The comment jar, modular or unnamed is not reflected inside that IF-condition, maybe "unknown" was wrongly used as "unnamed" .... still trying to understand what is happening, thats why im interested if this already works.

There is a lot of new stuff inside the internals, even the way how I need to load that jdk-classes, not familiar with that new jmod-files (and how to load them or requireing them).

@swpalmer
Copy link
Author

swpalmer commented Apr 6, 2017

It's such a pain right now to build and run on JDK 9 that I'm not sure when I will have the time to sink into this. I'm wondering if part of the issue is that my application is not modular itself? I will respond here if I find anything new.

(OT: Why is there an explicit call to .toString() in that code when printing the mainjar name?)

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 6, 2017

Regarding the toString: Path.getFileName() it returns a Path ;)

@swpalmer
Copy link
Author

swpalmer commented Apr 6, 2017

So? String concatenation operator automatically appends the equivalent of toString() ... explicitly calling it is redundant.

@FibreFoX
Copy link
Owner

FibreFoX commented Apr 6, 2017

haha, indeed :D maybe some internal checkstyle-rule or something with static code quality checks

@JustGregory-zz
Copy link

@swpalmer regarding JDK 9 already. It seems to be the case that, even after the release of a new JDK version, most people take a while if/when they upgrade JRE/JDK depending on usage. In my case when Java 6 came out and I was making Minecraft mods and I asked someone (casually) if they thought I should build against JDK 6 compatibility, the answer I got was a generic "I dunno, people are mostly Java 4 yet".

Well, if that holds, then even on Java 9 release, people would still be using various builds of Java 6, 7, or 8 for some time. Having JDK 9 support is good and all, I just don't think it needs to be done any sooner than a couple months after 9 is officially released. -- Only my opinion btw.

@FibreFoX
Copy link
Owner

@JustGregory thats somewhat my own view of the whole jdk9 situation, but the plugin currently works ;) and still need some (spare) time to figure out what is happening.

What bugs me the most, is the taste of the javapackager being unfinished, I'm not that familiar with the new module-concept, especially with maven-plugins and gradle-plugins requiring other dependencies (like how to depend on jdk.packager.jmod).

Inside the maven-plugin, the dependency is loaded via transitive dependencies, but on gradle I choose a different way of loading/manipulating libs inside the classloader.

Has anyone of you a good and up2date reference on how this module-concept works?

@JamzTheMan
Copy link

  1. I think the difference is Java upgrades in the past have been more painful and less automated. For our app we had to make several changes in code going to 1.6, 1.7 we had just a couple and none for 1.8. in fact many users were ahead of us on jre installs for 1.7...

@swpalmer
Copy link
Author

@JustGregory @FibreFoX There exists a certain chicken and egg problem. We can't move to Java 9 until the tools we use support it, and the tools we use see no motivation to move to Java 9 because nobody is using it yet.
My motivate is simple, I want to make sure that my software is ready to take advantage of Java 9. If there are issues with Java 9 that need to be addressed by the JDK team (Java 9 "bugs") that hold back my application taking advantage of other Java 9 features, that sucks. The Java update cycle is rather slow, so I want to be able to run my code on Java 9 as soon as possible so I can report issues. The "next" Java update is already too far away. In many cases there may be API changes required in the Java code and that kind of change needs to be identified very early because it won't change in an update release. At this point it is already too late. Java 9 is beyond the point were any significant changes can happen before it is released. :-(
That is why I think it is very important that development tools support new Java versions as soon as possible - far before the release. Because if I can't even build/run on the next version, how am I supposed to report issues with it?

@FibreFoX
Copy link
Owner

@swpalmer As I'm not in the state of having a full picture of Java 9, so just to clarify: using the bundled javapackager from the JDK, do you get working bundles?

@swpalmer
Copy link
Author

@FibreFoX Well that's sort of the problem.. I don't know yet because it means I have to re-write my project build scripts to call javapackager directly (at which point I wouldn't need this plugin). I'm not even certain that the command-line interface of javapackager is complete enough to allow it. I haven't found the time to do figure it all out. I think I have a simpler project somewhere, where I did just that... I remember having to work around all sorts of issues with javapackager including the correct resources.
I too don't have a full picture of Java 9... I'm discovering new requirements as I go.

@FibreFoX
Copy link
Owner

@swpalmer :) okay ... makes me feel a bit less stupid. As far as I understood, not all parts are finished inside the native launcher stuff. Currently I'm a bit too busy with my normal paid work stuff, but will dig into this again when having more time.

You will get informed when I had the chance to make some adjustments to this gradle-plugin.

@FibreFoX
Copy link
Owner

https://developer.jboss.org/blogs/scott.stark/2017/04/14/critical-deficiencies-in-jigsawjsr-376-java-platform-module-system-ec-member-concerns

I'm very interested in how this will resolve ... Jigsaw is not only a problem for this javafx-build-plugins, but for others too ... and the article kinda reflects my own thoughts about the whole module-concept :/ until there is proper support of gradle/maven, my work on supporting jdk9 will be pending.

@SingingBush
Copy link

Gradle 4.1 is now available with support for Java 9 modules and Java 9 itself should be released next month. Could this issue get picked up again

@FibreFoX
Copy link
Owner

Hi folks,

just wanted you to inform that I'm more active on my spare-time projects again, after some refactoring of the javafx-maven-plugin, there will be some more activity on the gradle-project. Sorry to keep you waiting ;) but as there were no PRs, I suspect you waiting for me to do the code-tinkering.

@netzwerg
Copy link

Fyi, I did a test build of my project on OSX: I am not using modules, but observed that jfxNative is no longer creating a .dmg (only a .app which does not launch).

@FibreFoX
Copy link
Owner

Anyone who is interested of testing the current snapshot-version (8.9.0-SNAPSHOT), should use the following:

buildscript {
    dependencies {
        classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.9.0-SNAPSHOT'
    }
    repositories {
        mavenLocal()
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }

    }
}
apply plugin: 'java'

repositories {
    mavenLocal()
    mavenCentral()
}

apply plugin: 'javafx-gradle-plugin'

It was required to remove some MacOSX-workaround (had to delete it making it compile), but i doubt this feature was used a lot (will wait for feedback on this one). This was compiled using JDK 9, but I hope this does not create any trouble for you.

As there are no special options for setting the new JDK 9 module things, please use the generic bundleArguments built-in hack:

bundleArguments = [
    // "--module-path"
    'module-path': 'PATH_1;PATH_2;PATH_3', // use File.pathSeparator !!! os-dependant

    // "--module"
    'module': 'module1,module2,module3',

    // "--add-modules"
    'add-modules': 'module1,module2,module3',

    // "--limit-modules"
    'limit-modules': 'module1,module2,module3'
]

For all the developers using the runtime: null-hack to disable bundling the JRE, this seems to not being supported (but I just might have missed the corresponding map-parameter for this).

Hoping for your feedback, thanks a lot in advance and sorry for over four month of delay after official JDK 9 release.

@FibreFoX
Copy link
Owner

FibreFoX commented Jan 26, 2018

No, this currently does NOT work, because the JDK contains some utterly stupid bug, more details at the javafx-maven-plugin project: javafx-maven-plugin/javafx-maven-plugin#287 (comment)

EDIT: there is a breaking change inside the windows-bundlers, linux-users and mac-users are still encouraged to check the latest snapshot-version.

@FibreFoX
Copy link
Owner

FibreFoX commented Feb 1, 2018

@FibreFoX FibreFoX removed this from the v9.0.0 milestone Mar 30, 2018
@FibreFoX FibreFoX removed their assignment Apr 14, 2018
@FibreFoX FibreFoX added this to the project rework milestone Dec 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants