JAVA_HOME meaning [duplicate] - java

This question already has answers here:
Towards the "true" definition of JAVA_HOME
(5 answers)
Closed 4 years ago.
Why does ActiveMQ provider needs JAVA_HOME env variable to be set
to a jdk location.
What does it use that variable for?
If it needs to run java command and relating commands, why bother with JAVA_HOME.
If PATH env variable is set correctly, java command is always available.
Or am I missing some points?
EDIT:
I don't think my question is a duplicate,
I'm asking pretty precise points on that variable, also in correlation to $PATH env variable and ActiveMQ.

The actual REASON for the JAVA_HOME is that many apps need to find more than just executables in the path, some java apps need to find the jar file they are supposed to use as a library -- Remember that there may be more than one java installation installed and that any given app may want a specific java version that isn't the one on the path.
Consider an app that uses a specific version of java that isn't on the path. You can specify a path to the java.exe, but how does the app know which set of libraries it's supposed to be using if it needs to interact with them in some way other than just using them? It could probably figure it out from the environment, but might be inaccurate and would definitely be platform dependent.
There is usually more than one way to set give the app this information, JAVA_HOME is one, often they don't need it at all.

Related

What exactly is the java executable, what does it do and where can I find the sources for it? [duplicate]

This question already has answers here:
Totally Confused with java.exe
(3 answers)
How is JNI_CreateJavaVM invoked when running a java app from the command line
(1 answer)
Closed 1 year ago.
My question is regarding the java executable, the one that you use to run a Java program and that on Linux it is found for example in /usr/bin/java.
I have been experimenting a bit as I want to look into how everything happens behind the scenes, like how does the bytecode gets loaded, how is the execution of the actual Java program starting and other details that may not be so straightforward.
Until now I have looked at the execution with strace and found that a new thread is created and that thread is the one on which the Java program actually gets executed (from another question that I posted). From what I understand the java executable is a launcher of some sort, but I do not understand all the operations that happen behind the scenes.
So, what exactly is the java executable and is there any place where I can find the source code for it (this would really help me)?
The primary source file for the launcher in the current development JDK can be found here: https://github.com/openjdk/jdk/blob/master/src/java.base/share/native/libjli/java.c
As you see, it's quite short and delegates most of the work to other pieces of code, but should be useful as a starting point.
If you want to see the source for other JDK versions (this is basically the main development repo for future Java versions), you need to look into the appropriate repository.

Force an java application to use specific jre [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have created an java application and it is working in some machine but not in few machines. I am not sure if it is because of the jre.
How can I find the path from which my application uses the jre and how can I force that application to use a jre in a specific location.
Thanks in advance
To answer the question at hand, Java system properties hold the values you seek:
String jreLocation = System.getProperty("java.home");
String javaVersion = System.getProperty("java.version");
I add the second of these as your problem may be caused by differing versions of Java (if the error is, say, a java.lang.UnsupportedClassVersionError).
In terms of enforcing a particular JRE, it's not possible to force the JVM version from a running Java program (this would need to be in a shell script or similar). You could check the value of "java.home" and exit if it's not the one you want but this would be unwise as this will vary from system to system. A slightly better options would be to exit with an error message if the "java.version" is not within a set of supported values.
However the best approach would be to fix the original problem such that your program works on all the systems you need it to run on. To this end, I'd recommend starting a new question with the error you get when running the program on these other systems.
You can write a script file to run a specific JRE, however do note that the problem is most likely not the JRE's fault unless the major version is different.
You cannot force a JRE to be ran in your Java program, because it would be too late.
You can find out the path of the JRE being use by checking the value of java.home system property. For example:
System.out.printf( "java.home = %s\n", System.getProperty( "java.home" ) );
Changing the JRE depends, particularly, on how you run your application:
If you are running your program through a command-line interface, you would need to modify your PATH environment variable to point to the correct java executable.
If you are running your program through an IDE, you may need to define a JRE_HOME environment variable and restart your IDE, or change the running configuration of your project.
To find out more about other useful properties in Java, take a look at https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html.
If your Java application requires a specific JRE, I think your best bet would be to package your application as "self-contained" bundle, containing the JRE. As many have already pointed out, once your application has started, the JRE is already chosen, and the only option you have, is to check the system variables, and possibly quit the application with some error message.
You can read more about the process of creating a self-contained application bundle at Oracle's Deployment Guide: Self-Contained Application Packaging.

How to get information from Linux continuously via Java, if there is a change in a directory? [duplicate]

This question already has answers here:
Directory listener in Java
(3 answers)
Closed 9 years ago.
There are two directories with the same content (local directory and remote directory). sync files do when a change in one of the directories. I check directories continuously via Java and to get information for changes on the directories. But I'm looking for an alternative way.
My question is;
Does linux give informations for changes on a directory?
and if linux gives the information,
How to get the information from Linux continuously via Java, if there is a change in a directory?
Any idea?
Since you're using Java 6 (and therefore cannot use nio to watch a directory), you should take a look at JNotify. It lets you watch directories for file changes. It works in Linux by providing a native library which uses inotify.

Detect if certain software is installed on a user's machine in Java

I have a Java application which requires certain software (one of them being Perl) before it can be run. What I used to do to detect for Perl is:
Runtime.getRuntime().exec("perl Test.pl");
and if there was an IOException declare that there was no Perl.
However, one of my users complained that the app kept failing because he had not placed Perl in his path varible. So this is why I'm asking: Is there any cross-operating system way to detect whether Perl (or any other software) is installed on the user's system and the path to the program?
These kind of questions seem to be popping out every now and then and the answer (almost) always is no. Most general reason for the negative answer is that Java is run in a homogenous Virtual Machine environment which is by design the same on all platforms; Those operations you can't abstract away/do reliably on at least the most supported platforms just can't be done easily. Detecting external events in the OS in general such as which non-Java applications are also run/installed falls into that "not easy to do" category.
Certainly there could be need/market for JNI libraries for the purpose but those steer heavily from the cross-platform requirement these questions always seem to want to and that's why the short answer is "no". As far as I can see, what you're doing currently is the cleanest way to detect Perl unless you're willing to include perljvm or similar in your project.
If the user is not willing to either
Install perl in an agreed upon location
Indicate where perl has been installed by storing it's location in an environment variable, config file, windows registry, etc.
then it seems you're only option is to search the entire disk for an executable named 'Perl'. Obviously this could take a very long time, but if you store the location somewhere, at least you should only need to search for it once
I don't know your target audience (users), but upon failure you could prompt the user to enter the path (a FileChooserDialog) and then store this path for future usage (if the exception is not thrown again). I did that some time ago, luckily I had users that were SysAdmins, so it was OK for them to provide that info when the error happened the first time (I also documented how to update or change these values in a properties file).
Other option as mentioned by Don, is to install the required software as relative to your installation, that's a more common option.
Getting windows native information using java SDK is not possible without support of external APIs. Instead of using external APIs (which is mostly LGPL licensed and not completely open), we can use the shell commands to get the same.
Step 1 - Checking if (perl) an application is installed
For checking if an application is installed, use ProcessBuilder or Runtime.exec to run one of the following PowerShell command,
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall* | Select-Object DisplayName | where {$_.DisplayName -match "perl"}
Replace "perl" with your choice of software and stream the output of these and process it.
If PERL (for above question), follow below 2 steps to set path and run perl script from java
Step 2 - If available, set it to Environment Path using java code.
Step 3 - Run your perl script.

How can I set the process name for a Java-program? [duplicate]

This question already has answers here:
how to change the name of a Java application process?
(10 answers)
Closed 8 years ago.
If a Java program is started, it get's in the system process-monitor the name java. Many Java-programs are that way hard to distinguish. So it would be nice, if a way exists, to set the name, that will be shown in the process-monitor. I'm aware that this may work different on different Operating Systems.
A simple way would be, if the java-interpreter would support a switch to set the name, like this:
java -processname MyProgram -jar MyProgram
But I couldn't find such a switch, so it is probably non-existant. An API in Java to set the process-name would be also fine.
So, so you have any suggestions?
I don't know if this is possible, but you could use a command line tool that comes with the JDK called 'jps'. It's like *nix ps, but just Java programs instead. jps -v shows all the arguments you have passed to java.
Also, I have seen people attach a "process name" to their java processes by adding an unused -Dmyprocessname to the args.
as #omerkudat said:
jps -v
prints out all java processes {processID, params list}
If the params list is not enough to recognize the applications you need,
try adding some dummy params when running them:
java -Dname=myApp -cp myApp.jar some.client.main.MainFrame
This will print like:
7780 MainFrame -Dname=myApp
and you can use the process ID to kill / monitor it.
You can do this with an LD_PRELOAD shim: https://github.com/airlift/procname
The shim simply calls the Linux-specific prctl() when the process starts:
static void __attribute__ ((constructor)) procname_init()
{
prctl(PR_SET_NAME, "myname");
}
The call has to happen on the main thread, so it isn't possible to do this from Java or even with a JVMTI agent, since those happen on a different thread.
When I first read this, the idea of changing the process name struck me as impossible. However, according to this ancient thread on the sun forum you can use C++ wrappers around the JVM executable to achieve this.
Though frankly, I wonder what your real problem is, as I'd guess there is a more standard solution then attempting to change the process name.
Your best option is something like launch4j
http://launch4j.sourceforge.net/
There is a bug logged in the sun bugtracker for this, but it's not high priority
http://bugs.sun.com/view_bug.do?bug_id=6299778
There are mainly 2 approaches: one is as already described: using tools like Launch4j, WinRun4J to create native Windows launchers.
Another approach that seems better is to use Apache Procrun to wrap the java application as a Windows service. During the install service process, we can give the process an meaningful name such as OurApp.exe.
All we need do is rename prunsrv.exe to OurApp.exe and replace every occurrence of prunsrv.exe in our install|start|stop|uninstall service scripts to MyApp.exe.
See more from Using Apache Procrun to Rename Process Name of a Java Program in Windows
If you want to use a different process name you'll have to create your own binary to launch your Java application using something like JSmooth.
Look at this question for a discussion of creating such binaries.
That's because Java applications aren't actually executable they're ran by the Java virtual machine which is why java appears in the process monitor, it's the host of your application.
Things like LimeWire however do but I think that's more down to GCJ - http://gcc.gnu.org/java/

Categories