java.exe is the JVM runtime or JIT that lets you
execute your class files. It comes bundled with the JDK.
If you install Java 1.6.0_17
in the default directory you should find it in J:\Program Files\java\jdk1.6.0_17\bin\java.exe.
The java.exe that comes in the stripped down JRE
install for end users that does not include the compiler etc. is used to be
called jre.exe. In JDK 1.3+,
there is only one java.exe. jre.exe
is gone. For all practical purposes you can treat jre.exe
as identical to java.exe.
The key thing to understand about java.exe
is that it wants the name of a class on the command line, not the name of
a class file. It could have been made smart enough to eat either, but it
wasn’t.
The other thing to understand is that java.exe
and javac.exe were written by two different
teams of people who never had coffee together. That’s why the command line
switches are so infuriatingly inconsistent.
All applications that you run with java.exe (such
as HelloWorld.java ) must have a
public static void main ( String[] args )
method.
Long Command Lines
javac.exe has the @file.txt
method to build up long command lines out of pieces. Unfortunately you can’t
do that with java.exe. If your command line is
too long what can you do?
- Specify classpath as SET CLASSPATH= rather than a
command line option -cp .
- Write a little kicker program in C or Java that exec’s
java.exe with the command line. That way it can
be arbitrarily long.
- Use tcc/TakeCommand or 4DOS.
It lets you have lines 1023 characters long, and provides for line continuation.
CLASSPATH And File Naming Recipes
Here are my simplified rules for using CLASSPATH and naming the files on the java.exe
command line:
- Use JDK 1.1 or later. Configure your SET
CLASSPATH= to clear it out. Avoid JDK 1.0 if
you can because its CLASSPATH is more complicated since it has to help java find
the standard classes.
- In all that follows, everything is strictly case sensitive.
- To run a HelloWorld.class app, in the default package in C:\MyDir,
use
CD \MyDir
java.exe -classpath . HelloWorld
Note that the -classpath must come before the HelloWorld
classname. To remember the order, you can think of it like this. java.exe
needs to know the classpath before it can search for the class. If you get them
reversed you will just get a mysterious NoClassDefFoundError.
- The following will not work to run a HelloWorld.class
app, in the default package in a jar in C:\MyDir, use
- To run a HelloWorld.class app in C:\com\mindprod\mypackage,
in package com.mindprod.mypackage, use
CD \
java.exe -classpath . com.mindprod.mypackage.HelloWorld
- The following will not work to run a HelloWorld.class
app in C:\com\mindprod\mypackage, in package com.mindprod.mypackage:
CD E:\com\mindprod\mypackage
java.exe -classpath . com.mindprod.mypackage.HelloWorld
For that to work, you must use smartj instead of java.exe.
- The following will not work to run a HelloWorld.class
app in C:\com\mindprod\mypackage, in a jar in package com.mindprod.mypackage,
use
- The following will work to run a HelloWorld.class app
in C:\com\mindprod\mypackage, in a jar in package com.mindprod.mypackage,
use
CD \AnyDir
java.exe -jar HelloWorld.jar
- If for any reason the examples shown do not work with your version of java.exe,
try various combinations of com.mindprod.mypackage.HelloWorld,
com/mindprod/mypackage/HelloWorld and com\mindprod\mypackage\HelloWorld.
The Java.exe Command Line
- Note, unlike with javac.exe or <APPLET
CODE, you don’t specify the extension (.class).
- Note, unlike all other command line utilities in the universe, you cannot
specify the fully qualified filename of the class file. You must however
specify the full package name.
- The CLASSPATH must provide access to all the needed *.class,
*.zip and *.jar files.
- If you want to run an Applet you need to use
AppletViewer or a browser instead of java.exe, and you
need to compose some HTML with an <APPLET tag in it.
- The switches are case sensitive.
- Make sure you specify the -options before the name of the class you want to
execute, otherwise they will be interpreted as parameters to your main method.
- If you use the -jar option, the java.exe
ignores the classpath. It will only look in that jar. You can’t specify a
class. You must use the Main-Class specified in the
manifest. If there is no Main-Class, then nothing will
work. To execute some other class besides the Main-Class,
don’t use -jar ; put the jar on the classpath
instead.
- With JDK 1.4.2 the command line switches had a
major overhaul. Many of the old switches no longer work.
| Java.exe command line switches |
| Option |
effect |
| -help |
print out info on options. Trust what it says over what I say here.
Knowledge keeps no better than fish. |
| -version |
print out the build version. |
| -v -verbose |
turn on verbose mode. |
| -server |
use the version of the JVM optimised for server apps. This only works with
the private JRE java.exe that comes with the JDK in J:\Program Files\java\jdk1.6.0_17/bin/java.exe,
not the public JRE in C:\Program Files\java\jre6/bin/java.exe. |
| -client |
This is the default. Use the version of the JVM optimised for client apps |
| -Xint |
Use a pure interpreter, not the Hotspot JIT. |
| -XX:MaxPermSize=64m |
Size of the permanent generation memory pool in megabytes for long lived
objects. |
| -XX:+PrintOptoAssembly |
Display the generated assembly code, not the byte code, the CPU-specific
assembly code generated by HotSpot. |
| -XX:xxxx |
There are many extended
esotoric options |
| -debug |
enable remote JAVA debugging. For ordinary debugging, you probably want -verbose
or -g instead. |
| -g |
include debug code to create stack traces with variable names and line
numbers. |
| -javaagent:myagent.jar |
define a jar containing a java.lang.instrument agent to use for monitoring
code. JDK 1.5+. Note the quirky extra colon. |
| -Xincgc |
Use incremental garbage collection. You have shorter pauses, but it takes 10%
more overhead. |
| -XX:+DoEscapeAnalysis |
The option directs HotSpot to look for objects that are created and
referenced by a single thread within the scope of a method compilation.
Allocation is omitted for such non-escaping objects, and their fields are
treated as local variables, often residing in machine registers. Synchronization
on non-escaping objects is also elided. |
| -XX:+UseCompressedOops |
The option can improve performance of the 64-bit JRE when the Java object
heap is less than 32 gigabytes in size. In this case, HotSpot compresses object
references to 32 bits, reducing the amount of data that it must process. |
| -XX:+UseParNewGC |
Use concurrent garbage collection to avoid pauses. |
| -verbosegc |
print a message when garbage collection occurs. |
| -noclassgc |
disable class garbage collection. |
| -Xss64k |
set the maximum native stack size for any thread, in 1024 byte chunks. |
| -Xoss300k |
set the maximum Java stack size for any thread, in 1024 byte chunks. |
| -Xms4m |
set the initial Java heap size, in megabytes. You can burn this, and similar java.exe
switches in at compile time with the javac.exe -J
switch. You can also put them into a SET parameter and
reference them on the command line e.g.
set jopts=-Xms4m
...
java.exe %jopts% MyClass |
| -Xmx10m |
set the maximum Java heap size, in megabytes. |
| -cp .;C:\java\classes.zip… |
list directories in which to look for classes. It is sometimes spelled out
longhand -classpath. Infuriatingly, javac.exe won’t
let you use the -cp shortcut. Starting with Java 1.2 you don’t add classes.zip,
(or rt.jar) to the classpath. |
| -jar C:\java\myjar.jar… |
Names jar to look inside for class files. This jar jar must have a manifest Main-Class
which gives the name of the class to execute. You may not specify it on the
commnd line. |
| -prof:java.prof |
output profiling data to .\java.prof. |
| -verify |
verify all classes when read in. |
| -verifyremote |
verify classes read in over the network. |
| -noverify |
do not verify any class. |
| -Xfuture |
Recommended to test all class files for strict conformance with coming
mandatory standards. |
_JAVA_OPTIONS
If you find yourself using the same options over and over on your java.exe
command line, you set up an environment variable to contain your default options.
e.g. In Windows:
set _JAVA_OPTIONS=-Xms64m -Xmx128m -Dawt.useSystemAAFontSettings=lcd
In Linux:
export _JAVA_OPTIONS='-Xms64m -Xmx128m -Dawt.useSystemAAFontSettings=lcd'
Parameters with Embedded Blanks
In Unix, java.exe is just a script. You can
modify the way it passes parameters from the command line into the JVM by
changing this line:
exec $JAVA_HOME/bin/$ARCH/$THREADS_TYPE/$PROG "$@"
Unfortunately every OS’s command processor has its own way of dealing with
passing parameters that contain spaces. To make matters worse, java.exe
then reparses them to pass to your main method. With two cooks, much can go
wrong. The easiest solution is just to avoid blanks or quotes or other
suspicious characters in your parameters. Encode them as _ or some other safe
character and convert them back yourself.
On windows you can enclose your blank-containing parameters in "s and they
will be stripped off before your main program sees them.
Awkward Characters in Command Line Parameters
I have tested the following only in Windows 2000. You may have to experiment
with your own OS to see how much of this applies.
- Parameters cannot begin with - since those are for java.exe
itself. So you must enclose such parameters inside quotes, e.g.
java.exe -jar myjar.jar "-something"
- Since spaces separate parameters, you can’t have spaces inside parameters
unless you surround them in quotes, e.g.
java.exe -jar myjar.jar "new improved blue raspberry flavour"
- Since quotes surround parameters, you can’t have quotes inside parameters
unless you precede them with \, e.g.
java.exe -jar myjar.jar "She said, \"I'm leaving\"."
Backslash in any other context just means plain backslash. Unlike in Java
String literals, you don’t double each
backslash.
- Somebody was asleep at the switch when they devised this convention.
java.exe -jar myjar.jar "F:\Program Files\"
That is illegal! and you can’t specify it another way.
- You can’t have newline characters inside your parameters. If you need them,
you will need to cook up some encoding scheme of your own, perhaps URLEncoder,
and explicitly decode that parameter yourself.
- You can’t have any character you cannot key in the native encoding in
which you write your bat stream. If you need them, you will gain have to roll
your own scheme to pass them through.
- I’m told you can use \\" to stand for ", but I have not tried it.
This is so Mickey Mouse I can’t believe grown companies made it up.
Jars
java.exe is ever so much easier to understand
and use when all the class files are inside a single jar. In that case the
member names are identical to the package names. You can hide the console by
using javaw.exe (java without)
instead of using java.exe.
Multiple java.exes
If you do a search/filefind you will discover more copies of java.exe
than you can shake a stick at. Ther are java.exes for
different JRE/JDK versions you make have installed, and there are at least two java.exes
installed for each JDK version. Which one gets used? It depends on your path.
The one first on the path is the one that gets used, usually the one in C:\WINDOWS\system32
or C:\WINNT\system32. There in one in the JRE at C:\Program Files\java\jre6\bin
and a second in the JDK at J:\Program Files\java\jdk1.6.0_17\bin.
If you have more than on JDK installed you will have yet another extra pair for
each version. Sometime an application that uses Java will install its own
private copy of java.exe as well.
To complicate things further the java.exe in system32
is just a dummy. It looks in the registry and then decides which real java.exe
to use. The last JVM installed gets to be the one used, even if it is older. To
switch JVMs, you must normally reinstall the one you want.
I have found that sometimes, if you just type plain java.exe
you will get the JDK version and sometimes the JRE version. I think Sun may have
switched horses at some point. It used to be the JRE, but now it seems to be the
JDK. You can look at the system property sun.boot.library.path=
C:\Program Files\java\jre6\bin
or sun.boot.library.path=J:\Program Files\java\jdk1.6.0_17\bin
to determine which one is being used. For explicit control, type "C:\Program Files\java\jre6\bin\java.exe"
or "J:\Program Files\java\jdk1.6.0_17\bin\java.exe"
| Java.exe Variants |
|
Java.exe location |
Examines
registry? |
Supports
-server? |
| path |
C:\Windows\System32\java.exe |
|
|
| JRE |
C:\Program Files\java\jre6\bin\java.exe |
|
|
| JDK |
J:\Program Files\java\jdk1.6.0_17\bin\java.exe |
|
|
|---|
The path java.exe is usually
first of the path, or you you type just plain java.exe
it will start. It then looks in the registry to find the official JRE, usually
the one on C:.
If you explicitly invoke the JRE java.exe,
it just executes, without checking the official JRE, since it notices it is
living in a JRE directory.
If you explicitly invoke the JDK java.exe,
it just executes, without checking the official JRE. Further, it has additional
support for the -server option that the JRE java.exe
lacks.
How can you make order of this chaos and manage your choice of JVM with some
finesse?
You could fiddle with the registry to switch JVMs. See the JVM
Manager student project. However, there is a simpler, cruder way.
- Delete the copy of java.exe and javaw.exe
in C:\WINDOWS\system32 or C:\WINNT\system32.
- Define a SET JAVA_HOME=C:\Program Files\java\jre6
(no quotes!) environment variable to point to the
where the \bin directory is containing the java.exe
you want to use.
- Make all references in your bat files to your JVM use %JAVA_HOME%\bin\java.exe,
ditto for javaw.exe and javac.exe.
- Change JAVA_HOME to switch JVMs. Unfortunately, IE, Opera and Netscape won’t
pay any attention to you.
Instead of using java.exe
repeatedly in a batch file, it is much more efficient (i.e. faster) to write a
tiny Java program that just invokes the main methods of the various steps in
turn. That way you only have to load the JVM once. You can use exec
to handle that which you still want to do in BAT files. You are reversing the
roles, Java calling BAT files rather than BAT files calling Java. You will find
many task are easier in Java that BAT
language.
Aborting
You can abort java.exe by hitting ctrl-C.
You can abort and get a dump of what was going on at the time with the threads
with Ctrl+Shift+Break. For anything fancier, you need
a debugger.
Under the Hood
If you are curious how java.exe works, you can examine
the c source code for launcher/java.c in src.zip.
You can see how it finds the correct JVM to load.
Learning More
Sun’s JDK Tool Guide to
Java.exe : available: