-1

Java 9 introduced modules, which was a horrible fix for a non-existing problem. Searching google "How to install java modules" doesn't bring up anything useful.

Now, before I give in to the temptation and repackage the whole JDK and JavaFX into a single jar file, and add it to the classpath (assuming that still works), can anyone help me with undoing what these idiots did?

What I want is for any jar to run with "java -jar *.jar". Without --module-path, without --add-modules.

The first part seems easy, copying all jmods into JDK/jmods should work, but after that I need a way to tell the java runtime to always load all modules.

(And no, I don't want to learn how to "properly" use modules, I want a way to install them and forget about them.)

Evan Dark
  • 1,311
  • 7
  • 7
  • *And no, I don't want to learn how to "properly" use modules, I want a way to install them and forget about them.* Use Java 8 then. Alternatively, and additionally, you will probably notice there is no Java JRE distribution after Java 11. You learn how to **properly** use modules, and use the **new `jlink`** command to create custom application runtimes. Or, as I said at first, just stick with Java 8. – Elliott Frisch Apr 04 '20 at 18:48
  • "_which was a horrible fix for a non-existing problem_" – that would depend on what problem you think they were trying fix. All they did was take a pattern everyone was using anyway and made it official. However, I do think they should have made it easy to create executable JAR files when using modules rather than offering no support whatsoever. – Slaw Apr 04 '20 at 19:34
  • I didn't think that using Java 8 forever was a valid solution. Maybe it is, because I don't see how would anyone write programs is java 9+, if there is no sensible way for the users to install the required libraries. – Evan Dark Apr 04 '20 at 21:07
  • I believe the intention is to stop using executable JARs altogether and instead ship entirely self-contained applications (including the Java runtime needed to run the application). With a purely modular application you can create a minimal, custom runtime image using the `jlink` tool. Combine that with the `jpackage` tool (Java 14, incubator) and you can package and deploy Java applications as native executables/installers. But I believe `jpackage` does not require modules or `jlink` and can create classpath-based applications as well. – Slaw Apr 04 '20 at 21:56
  • If you want to create an executable fat/uber JAR for a JavaFX application, however, that's still possible. Check out [this answer](https://stackoverflow.com/a/52654791/6395627) and [this answer](https://stackoverflow.com/a/55303408/6395627) (and mipa's answer). – Slaw Apr 04 '20 at 22:00
  • @Slaw If that was the intention, its a **horrible** idea. I'll end up with the same horrible code bloat, that electron has, where "Hello World" is 100 MB, because it contains an entire browser! – Evan Dark Apr 05 '20 at 15:44
  • I disagree. One of the things I've always disliked about Java is the need for the correct version of Java to be installed on the end system. The other thing I disliked is that a JAR file does not behave like a native application. For desktop applications both problems are not very user friendly. The added built-in support for creating entirely self-contained yet minimal applications is something I'm glad they added. And the nice thing about is: _You don't have to use that deployment model_. In other words, the addition of JPMS did not break your ability to create executable JAR files. – Slaw Apr 05 '20 at 15:52
  • @Slaw except that they decided to turn JavaFX into a module. With this they basically broke all JavaFX applications in Java 9+. But I have to agree, creating the module system was not the problem. How they did it was. – Evan Dark Apr 05 '20 at 15:55
  • Making the JavaFX library modular isn't the problem in itself either. The problem resolves around an implementation detail that I think was a mistake. Specifically, JavaFX applications have the ability to omit the main method as long as the main class is a subclass of `Application`. To handle that case there's some special code in the launch sequence of _Java itself_. This code, when the main class is an instance of `Application`, checks to make sure the `javafx.graphics` _module_ is in the boot layer, throwing an error if its not. Other than that, JavaFX can be used from the classpath. – Slaw Apr 05 '20 at 16:06
  • Note that modules (more specifically, the module-info descriptors) are ignore when placed on the classpath. The other problem for JavaFX applications specifically is the fact the library was removed from OracleJDK (it was never included in OpenJDK, as far as I know). This forces the application to "drag along" the JavaFX library JARs just like any other third-party library, though JavaFX is platform-specific. – Slaw Apr 05 '20 at 16:08
  • That said, there are some distributions which still include JavaFX. For instance, check out [Zulu Community](https://www.azul.com/downloads/zulu-community/). Looks like https://bell-sw.com/pages/java-14/ is another such distribution. – Slaw Apr 05 '20 at 16:26

1 Answers1

2

There is absolutely no need to do anything of what you considered to too. If you don't want modules (like me) then just don't use them. You can run even very big JavaFX applications without even thinking about modules. Just do the following. Put all dependencies on your classpath as usual (also the JavaFX jars). Then add a separate launcher to your program like this:

public class MyApp extends Application {
   <rest of the JavaFX code deleted>
}

class MyAppLauncher {public static void main(String[] args) {MyApp.main(args);}}

Now call this launcher instead of your real main and you are done.

mipa
  • 10,369
  • 2
  • 16
  • 35
  • Actually I was looking for a way to modify the JDK, not the Jar. Basically I want to be able to use both Java 8 and Java 9+ jars with JDK 11 - which, despite how easy it should be, seems like a ridiculously hard task. – Evan Dark Apr 05 '20 at 16:02