Oracle's point of view:
- There is no longer a JRE (SOURCE: Try to find a JRE that oracle offers you above version 8 - it doesn't exist).
- Instead, you write your app with modules, and use the jlink tool to make a 'tree shaken' JVM, this is a JVM with all the stuff that the modules you are using as basis don't even need. You produce one JVM for each and every platform you are interested in exporting as stand-alone installer thing.
- You then write an installer that installs the tree-shaken JVM, and your app, somewhere. The tree shaken JVM is not registered as 'system JVM', in fact that notion that there is a JVM installed on a PC and you can find it using e.g. registry keys or by looking in known places such as
C:\Program Files\JavaSoft
is obsolete. You don't do that, that JVM is only for that app, that app knows where to find it and nothing else on the system does. Each and every java-based app has its own copy of its own (tree shaken or not) JVM that only it uses.
- You, as the 'vendor', are on the hook for maintenance. If the JVM you shipped has a gaping security hole in it and that gets abused, it's your fault for not updating it, not oracle's. Oracle does not run
jusched.exe
or any other tooling to ensure it is kept up to date.
An easy alternative to this is that you simply move the responsibility of having a java runtime that can run your app to the shoulders of your user. Tell THEM to go download a JDK (because a JDK can run java apps just as well, actually better, than a JRE can), tell THEM to ensure it's on the $PATH
or in a known location / tells you where to find it / set JAVA_HOME
, and they are responsible for keeping it up to date.
Other vendors' point of view:
- Various other vendors do make a JRE for more modern versions. I have no idea if these JREs ship with
jusched.exe
or other update mechanisms, and how (or even if) these JREs register their existence in a way that your app / your installer can figure out where they are. You'd have to investigate.
There is no need to actually treeshake a JVM, you can also just ship a full blown JDK with your app. For example, if your installer ends up doing this:
- Sets 'program install root' ('root') to
C:\Program Files\EmilysAwesomeGame
- Unpacks JDK17 for windows x64 into
ROOT\jdk
.
- Unpacks all your dependency jars into
ROOT\lib
.
- Unpacks your main app into
ROOT\emilygame.jar
- Makes a
.BAT
file that runs %~dp0\jdk\home\bin\java -jar %~dp0\emilygame.jar
and that jar has a MANIFEST with a Class-Path
entry containing e.g. lib\javafx.jar lib\someotherdep.jar
, then.. that'll work fine, and replacing that bat file with an exe that does the same thing also works fine (and 'ship your own JVM in a subdir' is a model that tools like launch4j and similar have supported for a long time already).
The downside of not treeshaking is that the JDK is pretty large, and includes all sorts of stuff you wouldn't be using. But, it's just a matter of saving on disk space, a non-treeshaken JDK isn't going to run any slower, those unused parts would simply end up never being loaded.
A very common 'deployment model' is that you offer an msi with an exe for windows-x86 and tell everybody else to go install a JDK on their own responsibility and ship plain jars for everybody else (linux users, mac users, windows-aarch64, etc).