How to set -Xbootclasspath for a JRE with a custom launcher? - java

I have a Java application which is using a certain Java Runtime Environment. The application uses it's own launcher to startup the java virtual machine. No use of the java.exe, javaw.exe, javaws.exe binaries is being made -- as the application seems to have it's own launcher which is a different executable. This custom launcher is using the rest of the JRE files, such as bin/client/jvm.dll and rt.jar package etc.
Now, the problem is that I want to set a boot class path for this custom launcher. The custom launcher does not support the -Xbootclasspath command line parameter, like the default java.exe does.
Is there any way for me to set the boot class path now for this java runtime environment?
Thanks in advance.
Some things to keep in mind:
I do not have the source of this application
This is meant for self and personal debugging use only, not for distribution
Update: not getting a lot of replies, so let me rephrase my question. Books like http://my.safaribooksonline.com/0672326388/ch15lev1sec5 tell you to set the -Xbootclasspath, however how does one set such path when the application has it's own JRE launcher directly loading the java libraries without usage of the default java.exe etc. executables?

If I understand you correctly, the custom launcher is some native code app that starts the JVM to run the Java app; i.e. java.exe etc, ... but different.
A couple of things that might work are:
adding your JAR to the Java installation's "endorsed" directory, or
inserting your stuff inside the installation's "rt.jar" file, or some other standard JAR.
But in both cases, you could be changing the behavior of the Java installation for every application (and person) that uses it.

Related

how to run another .jar file when the current program has a bundled jre?

Before when users were required to have a jre installed to run aps:
ProcessBuilder builder = new ProcessBuilder("java -jar execute.jar");
Now with jlink and jpackage being released .jars can be deployed with a bundled jre.
What is the correct method to start another .jar from a program that had been deployed with jlink/jpackage?
java -jar will not work as java is not installed on the end user anymore
see:
How to call an embedded jre from command line in order to run java applications
This is a similar problem but does not address creating the .jar with jlink/jpackage
If you have a main class defined, you should be able to run "java -jar HelloWorld.jar".
Otherwise seems like you can create a launcher pointing to a starting module.
From Redhat Reference:
https://access.redhat.com/documentation/en-us/openjdk/11/html/using_jlink_to_customize_java_runtime_environment/creating-custom-jre-modular
Create a custom JRE with the required modules and a custom application launcher for your application.
$ ./jdk-11/bin/jlink --launcher hello=sample/sample.HelloWorld --module-path sample-module --add-modules sample --output custom-runtime
$ ./custom-runtime/bin/hello
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:
For jlink - Java Platform, Standard Edition Deployment Guide: Self-Contained Application Packaging: Supporting Multiple Entrypoints
For jpackage - Packaging Tool User's Guide: Support Application Requirements: Add Launchers
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.

Deploying basic java app for distribution

I created a java text based game. I exported it as a runnable jar file in eclipse, but double clicking didn't work to run it (not sure why this is, would appreciate an explanation) so I created a .bat file which has:
java -jar game.jar
This works on some computers. However, when a user who doesn't have java in their PATH (I assume this is the reason) runs the .bat file, it comes up with the error:
java is not recognized as an internal or external command
How can I make my java game able to run on all computers that have java (1.6) installed?
java -jar <your-jar> is, I think, the best you can do, if you want to support different operating systems as well. If a user doesn't have java command in the path, java support has not been installed as a public JRE and user should either fix the configuration or explicitly specify which private JRE is to be used. Oracle documentation explicitly states about the public JRE that
You must set the PATH environment variable to point to JAVA_HOME\bin
(where JAVA_HOME is the location where you installed the public JRE)
to register the JRE.
so a user should do just that. You can, however, check if JAVA_HOME is set and if java exists in the path and provide informational error message if it is not.
If you're fine with only supporting windows, you can use various .exe packaging systems to ease the process for end user. See this, this and this thread for details.

Simple swing application. The jar file runs on my computer, but not others

This is my first question, so apologies for any mistakes. I'll try and give all the info I can. Basically I've written a simple swing application which just loads in image into a JPanel and displays it. I'm using Netbeans 7.1 and I have the latest version of the Java SDK.
Anyway, I've used the "Build" feature in NetBeans 7.1 to deploy my application into a Jar file. When I double click the Jar File on my PC, it runs without a problem. However when I put it on other computers (Tested on 2 others so far, both with the most current JRE) it fails to open, citing the following error:
could not find the main class: swong.Startup. Program will exit
swong is my package name, and Startup is the location of my main method. I have checked the manifest file which is created with Netbeans' build, and it[the manifest] does indeed contain the location of my main method class.
From searching, I've come across similar issues in which the classpath is set wrongly, but I don't understand how this could cause my particular error.
If someone could help me, I would be over the moon. I've been studying java for a year or so, and I've got a good handle down, but I've NEVER been able to make a Jar that runs on a computer which wasn't my own. So, 10 points and thanks in advance.
xo.
EDIT: Thank you for the responses. I'm doing shift work and swamped, but I will test and poke with these responses tomorrow and provide more information. Thanks again. xo
I had d same problem while distributing my app. There is 1 solution that you create a batch file with 'java -jar AppName.jar' and asking user to double click on this batch file to execute your app. What i did was to provide a JRE installation exe(eg: jre_1.7.0) with your app.
Now create a Batch file (install.bat) in which write following commands
jre_1.7.0 -> this will install jre on user's pc
set path="C\Program Files\Java\jre_1.7.0\bin"
java -jar yourAppName.jar
Why i installed JRE because different people have different JRE versions installed. So this makes it difficult to set path to the installed JRE's bin folder & calling the 'java -jar' command. Hence as you know which folders your JRE installation will create hence it is easy to set path and execute your jar file with 'java-jar' command.
Check that your jar file has the following structure (at least)
jarfile.jar
|---------- swong
|---------- Startup.class
|---------- META-INF
|---------- MANIFEST.MF
It seems like the class "Startup" is missing. Maybe your jar only contains the .java files, not the compiled classes.
This error message can be a mistakable java7 error, when you try to start java7 compiled classes with a different Java Runtime Environment then java7. Have you validated, that your .jar is started within a Java7 environment on those other test machines? Sometimes it happens, that you have installed different versions of JREs and you might not be sure which one is actually started.
To check which enviroment is used, you can check in your registry for the following value:
HKEY_CLASSES_ROOT\jarfile\shell\open\command
this should point to your latest JRE. Or if you'd like to stay compatible to java6 as well, define the appropiate compile level in your build environment.

Where do I put Java Dependencies to run crawler4j-2.2.jar?

I'm new to Java and aren't sure where to place the Java Dependencies which are required to run crawler4j. Do I put them in the same folder, or do I put them where Java is located on my machine, or what? Please help me.
Putting the dependent JARs in the same folder as your application JAR / bytecode files is a reasonable approach. As others mention, you need to ensure that the actual folder containing the JARs is on the classpath when the JVM is launched to run the application. The -cp argument is the recommended way to do this, and it is common practice to create a little shell script / batch file to launch the app with the appropriate JVM parameters.
Putting them into the Java installation is not a good idea for a couple of reasons.
It might have unforeseen side-effects on other applications run using that installation. This includes applications run by other users.
It will make upgrading your Java installation to the next patch level more difficult.
You need to put them on the CLASSPATH. If you're running your/the application from the command line you can specify your classpath using the -cp argument for java
You put them in your classpath. The classpath can be specified with the -cp argument when you run the java program.
java -cp depend1.jar;depend2.jar;etc... Class2Run

Is it impossible to embed Java3D in a way that I don't need to install it?

I'm running a big application and a small part of it includes Java 3D, the problem is many users need to use the code, but it isn't practical for everyone to install Java 3D just to run the application if they aren't even going to use that section of the application.
Is it possible through compiling an extra jar, or changing some paths, to include Java 3D in a project without installing it on a system? Or perhaps to manually include any dlls?
The demos at java3d prove that it is possible.
You only need to include the required jar files to your projects distribution.
Yes, it is possible. You will need to pull the required jars and native libraries from the java3d site. I pulled them from the java3d demos, but that requires digging through the xml launch descriptor files.
The place you'll run into the most trouble is when linking to the .so / .dll files. This is typically specified on the classpath before your app starts, but since you don't know what platform you're using until your app starts, it's a catch22.
There are two possible solutions:
1. Bootstrap your program with a simple class that detects the platform and sets up a new jvm (with the proper libraries specified) for the real application.
2. Dynamically load the libraries (I've never actually used this method for native implementations, but I see no reason why it wouldn't be possible).
Unfortunately, neither method is terribly straight forward.
I've done this with no problems (and many users tested that it works, Windows OS) by simply adding the jars to the classpath and dropping the appropriate dlls into the "working" directory where the .bat file running Java started. One catch is I had to have two bat files - one 32 bit and one 64 bit. Each bat file copy/renames the appropriate dll to j3dcore-ogl.dll, since depending on which version of Java (32/64 bit) you're running, a different jar is needed.
Example .bat file:
del j3dcore-ogl.dll
copy j3dcore-ogl-64.dll j3dcore-ogl.dll
java -Xmx2048m -classpath ./YourJar.jar;./lib/tinylaf.jar;./lib/j3dcore.jar;./lib/j3dutils.jar;./lib/vecmath.jar your.package.MainClass
#pause

Categories