java.exe is the JVM (Java Virtual Machine)
runtime or JIT (Just In Time)
that lets you execute your class files. It comes bundled with the JDK. If you install Java 1.8.0_131
in the default directory you should find it in J:\Program Files\java\jdk1.8.0_131\
\bin\java.exe. The java.exe that comes in the
stripped down JRE (Java Runtime Environment) install for end users that does not include the
compiler etc. is used to be called jre.exe. In
Java version 1.3 or later, 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
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 Java version 1.1 or later. Configure your SET
SET CLASSPATH= to clear it out. Avoid
JDK (Java Development Kit) 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 -ea -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
- To run a HelloWorld.class app in
J:\com\mindprod\mypackage\, in package com.mindprod.mypackage, use
CD \
java.exe -ea -classpath . com.mindprod.mypackage.HelloWorld
- The following will not work to run a HelloWorld.class app in
J:\com\mindprod\mypackage\, in package com.mindprod.mypackage:
CD E:\com\mindprod\mypackage
java.exe -ea -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
The following will work to run a HelloWorld.class
app in
CD \AnyDir
java.exe -ea -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 (Hypertext Markup Language)
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.
Java.exe command line switches |
Option |
effect |
-client |
This is the default. Use the version of the JVM
optimised for client apps |
-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 version 1.2
you don’t add classes.zip, (or rt.jar) to the classpath. |
-d32 |
use 32 bit JVM if possible. |
-d64 |
use 64 bit JVM if possible. |
-debug |
enable remote JAVA debugging. For ordinary debugging, you probably want
-verbose or -g
instead. |
-ea |
Turn on assertion checking. |
-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. Java version 1.5 or later. Note the quirky extra
colon. |
-help |
print out info on options. Trust what it says over what I say here.
Knowledge keeps no better than fish. |
-jar C:\java\myjar.jar… |
Names jar to look inside for class files. This jar must have a manifest
Main-Class which gives the name of the class to
execute. You may not specify it on the command line. |
-noclassgc |
disable class garbage collection. |
-noverify |
do not verify any class. |
-prof:java.prof |
output profiling data to .\java.prof. |
-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.8.0_131\
/bin/java.exe, not the public JRE
in C:\Program Files\java\jre1.8.0_131\
/bin/java.exe. |
-showOptions |
This option does not yet exist. I have requested it with
Oracle RFE number JI-9013765 : java.exe -showOptions
. It displays the values of all the options,
showing the resulting merge of specified options, defaults and computer
defaults. |
-verbose |
turn on verbose mode. |
-version |
print out the build version. Can also be used to specify the version you
want. |
-verbose:class |
display the name of each class as it is loaded. |
-verbosegc |
print a message when garbage collection occurs. |
-verify |
verify all classes when read in. |
-verifyremote |
verify classes read in over the network. |
-Xfuture |
Recommended to test all class files for strict conformance with coming
mandatory standards. |
-Xms2000m |
set the initial Java heap size, in megabytes. g/gigabytes are not supported.
The default is computed based on the system configuration. 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 set jopts=-Xms4m
...
java.exe %jopts% MyClass |
-Xincgc |
Use incremental garbage collection. You have shorter pauses, but it takes
10% more overhead. |
-Xint |
Use a pure interpreter, not the Hotspot JIT
. |
-Xmx5000m |
set the maximum Java heap size, in megabytes. g/gigabytes are not supported.
The default is computed based on the system configuration.
When tweaking the memory configuration options, try a variety of
constellations of options to discover which actually works better. Bigger
is not necessarily better. What is best depends on your hardware and what
else in running in your machine at the time. It would be nice if there were
some utility that could automatically tweak these parameters depending on
the current conditions and past history. |
-Xoss300k |
set the maximum Java stack size for any thread, in 1024 byte chunks. |
-Xss64k |
set the maximum native stack size for any thread, in 1024 byte chunks. |
-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:+PrintOptoAssembly |
Display the generated assembly code, not the byte code, the CPU-specific
assembly code generated by HotSpot. |
-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. |
-XX:MaxPermSize=64m |
Size of the permanent generation memory pool in megabytes for long lived
objects. |
-XX:xxxx |
There are many
extended esoteric options |
There is no command line option to set the locale or language or even the default
encoding. You can however, set
system
properties with the
-D option.
_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'
You still have to manually insert that SET parm on the java.exe command line. e.g.
java.exe %_JAVA_OPTIONS -jar some.jar
_JAVA_OPTIONS is just an arbitrary name. It has no
special meaning to java.exe.
Here are the settings that IntelliJ suggests for 64-bit java.exe. If you have plenty of RAM (Random Access Memory) you might experiment bumping up some
of the memory values.
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 (Operating System) ’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 -ea -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 -ea -jar myjar.jar "new improved blue raspberry flavour"
- Since quotes surround parameters, you can’t have quotes inside parameters
unless you precede them with
java.exe -ea -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 -ea -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.
Neither
java.net.URLEncoder.encode nor
java.net.URLDecoder.decode
are for encoding/decoding URLs (Uniform Resource Locators). They are for encoding/decoding
application/x-www-form-urlencoded form data.
- 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.
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. There 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\jre1.8.0_131\\bin and
a second in the JDK at J:\Program Files\java\jdk1.8.0_131\
\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
JVM
s, 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 Oracle 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\jre1.8.0_131\
\bin or sun.boot.library.path= J:\Program Files\java\jdk1.8.0_131\
\bin to determine which one is being used. For explicit control, type
"C:\Program Files\java\jre1.8.0_131\\bin\java.exe" or "
J:\Program Files\java\jdk1.8.0_131\\bin\java.exe"
Java.exe variants
Java.exe Variants |
|
Java.exe location |
Examines
registry? |
Supports
-server? |
path |
C:\Windows\System32\java.exe |
|
|
JRE |
C:\Program Files\java\jre1.8.0_131\\bin\java.exe |
|
|
JDK |
J:\Program Files\java\jdk1.8.0_131\\bin\java.exe |
|
|
---|
The path java.exe is
usually first of the path, or 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 do you select which java.exe to run?
Here are some possible ways:
- Put the java.exe you want first on the path.
- Explicitly invoke the Java.exe you want e.g. J:\Program Files\java\jdk1.8.0_131\
\bin\java.exe.
- Fiddle with the Java control panel to hide the Javas you do not want to
use.
- Use the java.exe -d32 and
-d64 options to guide it to right java.exe
- Use the java.exe -version
option.
- You could fiddle with the registry to switch JVMs (Java Virtual Machines)
. 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\jre1.8.0_131\
(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 (Internet Explorer), 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 (Batch)
files. You are reversing the rôle s, 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