Why is the java PATH variable needed only for terminal execution? - java

Why is there no need to add the path of the java installation to the PATH variable when starting a jar with double-click while it is needed to start the jar from command line? Why does the OS only know where java is installed when executing with a double-click (without the PATH variable)?
Related Questions:
Is it necessary to set the path variable in java installation?
Is JAVA_HOME variable needed when Java Path is defined in system environment variable?

When on the command line, you call an executable and pass it a file as an argument. Since it does not know where this executable is, you either need to call it with an absolute path (Includes the entire path from the drive letter to the executable) or the executable must be present in one of the locations listed in the system PATH environment variable.
However, when double clicking a file Windows does not have the luxury of being told which application it should use ahead of time. To solve this issue, Windows keeps a global registry of programs, file extensions, and various metadata about them. This includes stuff like which icon to display for that file type, the path to the executable used to open that file, extensions associated with a given program, the path to the uninstaller to use if deleted from the control panel, and much more.
The Java installer handles updating the registry for you behind the scenes so you don't need to, however depending on your installation setting it may not update the system path since most people will only use the double clicking method.

Related

How to Download Java and run a file on command line

I know this is SUPER basic. I am very new to all of this. I tried to download java and run a helloworld by following these instructions: https://docs.oracle.com/javase/tutorial/getStarted/cupojava/win32.html
I got an error when I tried to use the "javac" command to compile. This is what appears in the command prompt:
C:\Users\USer18\Desktop>javac HelloWorldApp.java
'javac' is not recognized as an internal or external command, operable program or batch file.
Does this mean I downloaded java incorrectly? When I downloaded it, there were 3 different things to choose from, but I could only choose one, so I chose the first one. I tried to download java again and select the second one, but it said it didn't work.
Thanks in advance for helping me!
From the tutorial you linked, it tells you to "consult the installation instructions" found here: https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html
For Windows JDK, the instructions linked are here: https://docs.oracle.com/javase/8/docs/technotes/guides/install/windows_jdk_install.html#CHDEBCCJ
The part you need to look for is "Updating the PATH Environment Variable"
Updating the PATH Environment Variable
If you do not set the PATH variable, you need to specify the full path
to the executable file every time you run it, such as:
C:> "C:\Program Files\Java\jdk1.8.0\bin\javac" MyClass.java
It is useful to set the PATH variable permanently so it will persist
after rebooting.
To set the PATH variable permanently, add the full path of the
jdk1.8.0\bin directory to the PATH variable. Typically, this full path
looks something like C:\Program Files\Java\jdk1.8.0\bin. Set the PATH
variable as follows on Microsoft Windows:
Click Start, then Control Panel, then System.
Click Advanced, then Environment Variables.
Add the location of the bin folder of the JDK installation to the PATH variable in System Variables. The following is a typical value
for the PATH variable:
C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jdk1.8.0\bin
Note:
The PATH environment variable is a series of directories separated by semicolons (;) and is not case-sensitive. Microsoft Windows looks
for programs in the PATH directories in order, from left to right.
You should only have one bin directory for a JDK in the path at a time. Those following the first instance are ignored.
If you are not sure where to add the JDK path, append it.
The new path takes effect in each new command window you open after setting the PATH variable.
When ever we execute any command, it is searched in the directory where we are current in or mentioned in PATH environment variable. The oly thing which you need is just add <path of yourjdk>\bin to PATH
Windows 10 and Windows 8
In Search, search for and then select: System (Control Panel)
Click the Advanced system settings link.
Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New.
In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
Windows 7
From the desktop, right click the Computer icon.
Choose Properties from the context menu.
Click the Advanced system settings link.
Click the Advanced system settings link.
In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
Reopen Command prompt window, and run your java code.

Must I place all dependent DLLs into the JDK's bin folder?

My java application depends on a DLL, and that DLL further depends on libstdc++-6.dll.
I tried to:
placed the libstdc++-6.dll in a folder
and put the folder in the %PATH%
Then I meet the java.lang.Unsatisfied LinkError: The specified procedure could not be found when launching application from Eclipse.
But if I put the libstdc++-6.dll into the JDK's bin folder, say C:\Java\jdk1.6.0_45_32bit\bin. It works fine.
But I don't want to pollute the JDK folder. I remember windows will search %PATH% to locate dependent DLLs. Why can't I use the %PATH% in this issue?
Update 1
There are 2 different %PATH% environment variables in Windows.
User variables
System variables
I just accidentally find that:
If I put the DLL's folder to User %PATH%, it cannot be found.
If I put the DLL's folder to System %PATH%, it works.
Why?
Update 2
Inspired by this thread:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH
I start to wonder maybe my User %Path% is too long. So I moved the folder path containing my dependent DLL from the end of User %PATH% to the beginning. It works now!
At first, I conclude that one who implemented the Windows' DLL lookup algorithm has some truncation issue. And I almost consider it as another annoying Windows Bug.
But I wrote another Windows application which has similar DLL dependencies to confirm my guess. That application works fine! So I have to review my conclusion.
I checked my User %PATH% entry one by one, and place the folder to each possible location. And finally, I find the root cause.
I have a C:\MinGW\bin entry in User %PATH%, which happens to contain a
libstdc++-6.dll (977KB) but unfortunately, which isn't compatible
with the one I need (825KB). It only works if I place my folder before MinGW. So it's actually DLL collision during %PATH% resolution.
Now this issue seems resolved. But another one comes up, do I need to switch back and forth if I want to use both my DLL and the MinGW?
Update 3
Please check the comment by #AndyThomas. He mentioned using System.loadLibrary() for both direct and indirect DLLs. This way, all we need to care about is the java.library.path property. I think that's a once-for-all solution.
First: put all DLL files you need in the same directory
Then: Load native libs - to do so you have 3 options:
Set VM Options while you run your app.
-Djava.library.path="C:\Your Directory where Dll is
present"
Example:
java -Djava.library.path="C:\Your Directory where Dll is
present" -jar app.jar
Load specific native library from within the app:
a) Place the directory that contains the file aaa.dll directly under the Java project.
b) And place this line on the top of stack trace of your app: System.loadLibrary("aaa")
Use VM options from within your app:
System.setProperty( "java.library.path", "C:\Your Directory where Dll is
present" );

Java program is loading from system32 folder, not from folder, which it is placed

I wrote desktop program in Java on Windows 7 and hanged it on startup by writing to registry the path of jar file (kind of C:\Users\User\Documents\My App.jar) in HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run branch. When my program loads with Windows, it must load some text file that placed in the same folder as the program:
File f = new File("text.txt"); // without full path to file
if(!f.exists())
JOptionPane.showMessageDialog(null, "File not found: " + f.getAbsolutePath());
but cant do it and I get message: "File not found: C:\Windows\system32\text.txt". It appears as if the program is located in the system32 folder and a text file, respectively, too. What did I do wrong?
My theory: if you installed Java for Windows via the traditional installer, in addition to the place you told it to put it (canonically, JAVA_HOME), the installer drops a java.exe in the system32 directory, so it's likely that when you're starting the JVM on startup, system32 is the working directory and that's where it will look for files with relative path names like the one you've provided.
The easiest solution is to specify the path to the text file absolutely in your code. I would also recommend specifying the full path to java.exe in your registry key (I would guess that right now it's just java.exe with no path) so that you can guarantee which version you're running; if you have multiple versions of Java installed only the most recently one installed will have java.exe in system32 and without a qualifying path I would guess that's the one you're getting since PATH will probably be minimal at that point.
As a closing--unrelated to your problem--point, I hate that Java does this on Windows and wipe that copy of java.exe out immediately, and then set up PATH to make sure the version I want is the one that is executed on demand.
You need to get current working directory and use it as a part of absolute path to a file.
Take a look at this question: Getting the Current Working Directory in Java
The other workaround would be to read this registry key you described and using this information to read a file from desired path - read/write to Windows Registry using Java
The path that you are referring is the working directory, and is not where the application is installed. Like if you put a shorcut to it, you can change the working directory and it will change the result you are getting. But as you put it to startup automatically, probably windows is setting this as the working directory.
Like that:
Use registry to startup a program, and also change the current working directory? 1
You can try to pass the file directory to your app with a command line parameter in the registry.
1 - This probably won't solve the problem for you, don't seems you have one, its just an explanation
I think that #Omaha's answer is describing what is going on (you are launching java.exe from the system32 directory - the JRE installer places a copy of java.exe in system32 to make it easier for users to access).
The actual solution to your situation is to adjust your CurrentVersion\Run registry entry so it specifies a default working folder for the application. Check out: Use registry to startup a program, and also change the current working directory?

javac not recognized as an internal or external command

What are the path variable supposed to be to ensure "javac" will work? Should it be in both system and user variables and should the "\bin" part be included?
I have a Program Files and Program Files(x86) and the JDK is in both. Which one should i use? Eclipse is working perfectly, it's only when using command line that I get this. Anyone?
Eclipse comes with its own Java compiler, it doesn't have to use an external one.
You should find the bin directory under whichever JDK you want to use and then add it to the path (I prefer the user path but, since I only ever run as one user, I'm not sure what the difference is).
And make sure it's the JDK, not just the JRE.
For example, mine is in c:\program files\java\jdk1.6.0_17\bin (32-bit WinXP).
One final thing, if you're changing the environment variables in the control panel, that won't affect cmd windows that are already open. You'll need to open up a new one to get the new environment settings (trap for wary players).

Java - Adding directories to PATH?

I'm going through the Java EE 6 Tutorials and on page 68 under SDK Installation Tips, it says:
"After you install the GlassFish Server, add the following directories to your PATH to avoid having to specify the full path when you use commands:
as-install-parent/bin
as-install/bin
How do you add these to the "PATH"? Is it the System Properties, Advanced tab, Environment Variables box that I need to edit inside? What if I already have other directories indicated in PATH already? Will the SDK get confused or does it not matter?
Is it the System Properties, Advanced tab, Environment Variables box that I need to edit inside?
That's one way, in Windows. In this case, if you have an open CMD window, you need to open a new one so that it will get the new settings.
What if I already have other directories indicated in PATH already?
The PATH variable is a list of directories separated by a semicolon. Simply add the semicolon and the new directory. Example:
C:\Program Files\Mercurial;C:\cygwin\bin
In an open CMD window, you can also use set:
set PATH=%PATH%;C:\glassfish\as-install-parent\bin;C:\glassfish\as-install\bin
In Unix, use export, and colons instead of semicolons.
export PATH=$PATH:/usr/glassfish/as-install-parent/bin:/usr/glassfish/as-install/bin
Of course, remember to replace C:\glassfish from my examples with the actual directory where you installed Glassfish.
One last thing, keep in mind this variable is only used by the operating system to find the executables in the bin folders; it's not used by Java nor Glassfish.

Categories