In my Java program, I need to launch another JAR file (respecting its MANIFEST.MF) without creating a new instance of Java Virtual Machine. How can that be done?
Why I need this: I am currently writing a "wrapping" program for an application run on a remote hosting so I can have better control over the server via TCP. There, hosting software would run the file specified by me (the wrapping program), and the program has to open its own TCP server and then launch the main server. Although I know I could create a new process and have my application control it via its standart IO streams (System.in, System.out, System.err), that would limit my possibilities while also probably violating hosting terms. So I tried manually invoking server's main class. However, manifest file may specify data required by the server (such as Class-Path property or application-dependant properties) that I may not know about.
A way to do this is by creating a Java agent, which is a piece of code that you can let the JVM call before the main program runs. An agent is a class with a premain method (similar to the main method of a normal program). You start your agent by specifying the -javaagent option as an extra option on the command line when you start the program.
I need to launch another JAR file (respecting its MANIFEST.MF) without creating a new instance of Java Virtual Machine.
Another idea would be to read the jar file's manifest file and use its contents for starting the code in that jar file. The Manifest class would be useful.
Also it would require a custom classloader to read the class files from the jar file.
Back when java was so slow (1.4 in 2004) I wrote a program to allow the execution of multiple jar files from a single JVM. It took forever for the JVM to start, so I tried to start it once and then reuse.
It was simple minded but has worked for years. I still use it. In fact I found a way to start it from a browser so I can use my search program from the chrome browser.
Thank you for your awnser, but I am afraid that is not exactly an option.
I personally could modify my main server's JAR file to include an agent class, but I also want to publish this application later for others to use, and your solution would cause a couple of problems:
a) modifying a JAR file is often a violation of application's license, thus it would be illegal to inject an agent class into a JAR;
b) in many cases (including mine) JVM arguments cannot be changed, thus making Command-Line Interface unreliable and useless.
posted 2 years ago
Norm Radder, thank you for your awnser. I checked manifest file specification and realized that out of all those attributes I only need Class-Path and Main-Class attributes to launch main method. It is then not my responsability to process all manifest data.
So I will try creating a ClassLoader with the subject JAR and all Class-Path entries as code sources, then loading class specified by Main-Class attribute and finally invoking its main() method with desired "console" arguments.
posted 2 years ago
Can you post the code when you get it working? I'd like to see what it takes.