If you have to run the second JAR in its own JVM, then you have to have a JRE or JDK installed to do that.
Alternatively, you need to use jlink
or jpackage
or whatever to turn it into a self-contained application and distribute that instead of the second JAR. The user has to install that application in a place that your main application can find.
In either case, you run the second application as a separate process; i.e. as a separate JVM.
If it acceptable to run the second JAR in the current JVM, then it may be possible to do the following:
- Open the JAR file to read its MANIFEST.
- Fetch the
Main-Class
and Class-Path
manifest attributes
- Create a new classloader with a classpath that includes the second JAR and all of its dependencies. (This assumes that they are available ... at the locations specified by the Class-Path attribute.)
- Use the classloader to load the main class.
- Use reflection to find and call the main classes entry point method; i.e. the
static void main(String[])
method. Pass it a String[]
to represent the command line arguments.
There are a couple of problems with this approach.
The application you are running from the 2nd JAR will share the environment with your main application. The same standard input/output/error. The same current directory and environment variables.
If the second application misbehaves ... it can bring down the main application in various ways. A security sandbox might help, but it won't protect against everything.
If the main application has been distributed with a custom JRE, then it may not include all of the Java SE classes that the second application needs. If that is the case you will get classloader exceptions or errors.
Finally, this approach may not work at all if the packaging technology you use uses an AOT compiler to compile the main application + all classes that it uses to native code.
UPDATE - Now that I understand what you are actually doing here (you have a main app and an updater app), I think there is another way to do this. The jlink
utility allows you to create a bundle which has multiple entry points. When this is installed, I would expect it to appear as commands with different names that are links to the same executable. They would (naturally) use the same embedded JRE.
Read the following for more information:
Note that doing it this way would address possible issues with functionality missing from the bundled JRE. The jlink
or jpackage
command should make sure that all classes / modules that are needed will be included.