Skip to main content

Making Windows find JARs like it finds EXEs and CMDs

Posted by mkarg on December 29, 2010 at 6:33 AM PST

After more than a decade in the Java universe, today I had just enough of remembering where my executable JARs are located and typing all the lengthy path names, so I finally taught Windows to deal with Java archives just the same way as it deals with it's native executables EXE and CMD. The trick is so simple that I actually do not understand why the JRE installer isn't applying it automatically to prevent everybody from reinventing the wheel.

Nobody wants to type so much

Two of my most needed programs when coding on Windows, even in the Eclipse era, are the Command Line Interface (CLI) and the Text Editor. As programmers always are in a hurry, and as I am faster in typing than in clicking, I typically start those by entering their respective binary image names at the start line (thanks Microsoft for not completely dropping it even in Windows 7). After decades of Windows, I meanwhile know that those images are "%WINDIR%\System32\cmd.exe" and "%WINDIR%\System32\notepad.exe". In fact, this was not always the case. I can remember that before Windows NT it was not cmd.exe but COMMAND.COM (which actually still is existing even on Windows 7). But actually, I never typed the complete path, and I typically do not type the extension. Actually I don't care where to find the program, and I don't care whether the image is an EXE, COM, CMD or whatever. Windows knows where to find them, even if I am in a different current working directory, even if I omit the file extension. So now I want that magic for JARs, too. I want that my Java applications is found and started, without giving the absolute path, without giving the .jar file extension.

Getting rid of the file extension

For this to work, the first step is to tell Windows to consider a particular file extension as searchable. This is as easy as adding the extension ".jar" to the list of searchable extensions, which is stored in the PATHEXT environment variable. At the command line, this can be done temporarily (i. e. for just the current CLI session) using SET PATHEXT=%PATHEXT%;.JAR, but to make it persistent for future uses, it makes sense to instead set this in the Windows registry (e. g. using the "Extended Systems Settings" GUI). This was half the rent already. Now Windows knows that you will omit this extension from now on.

Getting rid of the path

The second step is to tell Windows to consider a particular path as searchable. This is as easy as appending the location to the PATH environment variable, which can be done in several ways, e. g. by using the command line for a temporary change using SET PATH=%PATH%;C:\WhereMyJarIsLocated or using the mentioned GUI. That's it. Now Windows will search that place(s) for my JARs. Great.

No magic included, unfortunately

As I wrote, it's just two little tweaks. No tricks. No Magic. All the rest is done by the operating system's intrinsic fmunctionality, plus a trick applied by the JRE installer: The installer already was kind enough to register the "javaw.exe" program as the executor for JAR files. So Windows knows what to do with our JAR once it was found. In the very early ages of Java, one had to do that manually, which was not complicated, but just another more GUI click to do.

But the world is not perfect yet. When running our executable JAR, what Windows actually is executing is not our JAR but the Java VM Launcher (i. e. %WINDIR%\System32\javaw.exe). That launcher is interpreting (or compiling and then executing) the content of our JAR (for those who forgot). So, the operating system's list of processes does not contain our JAR. It just contains javaw.exe, once for each started executable JAR. This is rather annoying, as one cannot easily find out which PID in fact is executing which JAR. You certainly can configure Task Manager to display the complete (and rather lengthy) command line invoked to run this process, but it is just not as smart as real EXEs, which are directly named as the process name. Sad but true, there is no simple help for this. Using a hard or soft link is not enough to rename the process (it still will show the target's name, not the source's name). In fact, to solve that, one would have to write a wrapper (or copy javaw.exe, or use one of those fancy wrappers available on the web). It would just be nice if javaw would create such a copy the fly and hand over execution to the newly created copy, but in fact I doubt that Oracle will do that any soon...

Regards, Markus.


An overview of all my different publications and products can be found on my personal web site Head Crashing Informatics (http://www.headcrashing.eu).

 

Comments

Making Windows find JARs like

Thanks for the tip.
As for getting the pid, you can always run jps from the CMD. Not as elegant as seeing it in the task manager, but does the job...

Making Windows find JARs like

This is not working due to two bugs, but with a little trick you can make it work. It seems JPS has a nasty bug, I'll file a bug report with javasoft.com to get it fixed... When starting an executable JAR and then using jps to get the mapping of PIDs to running Java programs...
C:\>"C:\Program Files\Java\jdk1.6.0_22\demo\jfc\Metalworks\Metalworks.jar"
C:\>jps
...it outputs this fancy result:
7112 Program
2224 Jps
Funny, isn't it? Looks like JPS is not able to deal with blanks in path names! To work around this, you can use the -m command line switch. This is intended to show the arguments passed in. As the first argument is the binary image path, you will get the right (well, actually an improved but still wrong) output then:
7112 Program Files\Java\jdk1.6.0_22\demo\jfc\Metalworks\Metalworks.jar
4644 Jps -m
This is not a complete fix, as you still wouldn't see a difference between two JARs in the same path on different drives (C:\Program Files vs. D:\Program Files), but for most cases it will do. To get the complete, correct result, you need to add another switch (-l, intended for getting the full package name -- don't ask me why it fixes the problem!), and it will work:
7112 C:\Program Files\Java\jdk1.6.0_22\demo\jfc\Metalworks\Metalworks.jar
5524 sun.tools.jps.Jps -ml
I wonder why so many programmers have problems with blanks in command lines: Windows actually does all the parsing for you, so why do so many programmers parse on their own and then do faults like these (and here, there actually are two faults: First, stop parsing at blanks, second, cut away driver letters)...

Markus, Thanks a lot for

Markus,
Thanks a lot for bringing up this topic I was asked in pretty much the same way by a member of Chennai JUG at a prior meeting (the 2nd was reported about here at java.net;-)
While the special emphasis on Windows may not be up to Java alone, or at least raise the question of platform-independence (i.E. do you expect that to work on Mac, Linux/Unix and other systems, too or just Windows?) if you happen to be a JCP member already, it seems like it touches a few aspects of the new Java Modularity JSR, formed mostly by EC members so far, but open to non-EC members, too. I hope, it becomes a "real" JSR soon, but if you are a JCP member, please ask the PMO and they might add you to the list, at least as observer.
Not to mention, upcoming JCP EC elections may benefit from more International candidates, especially in Silicon Valley dominated SE/EE ;-)
Regards,
Werner
(currently only Individual SE/EE EC Member)