What are Environment Variables?
Environment variables are global system variables accessible by all the processes running under the Operating System (OS). Environment variables are useful to store system-wide values such as the directories to search for the executable programs (PATH) and the OS version. Examples of environment variables in Windows OS are:
COMPUTENAME,USERNAME: stores the computer and current user name.OS: the operating system.SystemRoot: the system root directory.PATH: stores a list of directories for searching executable programs.
In setting up JDK and Java applications, you will encounter these environment variables: PATH, CLASSPATH, JAVA_HOME and JRE_HOME. In short:
PATH: maintains a list of directories. The OS searches thePATHentries for executable programs, such as Java Compiler (javac) and Java Runtime (java).CLASSPATH: maintain a list of directories (containing many Java class files) and JAR file (a single-file archive of Java classes). The Java Compiler and Java Runtime searches theCLASSPATHentries for Java classes referenced in your program.JAVA_HOMEandJRE_HOME: maintain the locations of JDK and JRE installed directory, respectively.
(Windows) How to Set or Change an Environment Variable
Variables in Windows are NOT case-sensitive (because the legacy DOS is not case-sensitive). Environment variables are typically named in uppercase, with words joined with underscore (_), e.g., JAVA_HOME.
Display Variables and their Values
To list all the variables and their values, start a CMD shell (Click "Start" button ⇒ Run ⇒ Enter "cmd") and issue the command "set". To display a particular variable, use command "set varname". For examples,
// Display all the variables (in NAME=VALUE pairs) prompt> set COMPUTERNAME=xxxxxxx OS=xxxxxxx PATH=xxxxxxx ....... // Display a particular variable prompt> set COMPUTERNAME COMPUTERNAME=xxxxxx // OR use echo command with variable enclosed within a pair of '%'s prompt> echo %COMPUTERNAME% COMPUTERNAME=xxxxxx
Try issuing a set command on your system, and study the environment variables listed. Pay particular attention to the variable called PATH.
Set/Change/Unset a Variable
To set (or change) a variable, use command "set varname=value". There shall be no spaces before and after the '=' sign. To unset an environment variable, use "set varname=", i.e., set it to an empty string.
prompt> set varname prompt> set varname=value prompt> set varname= prompt> set |
Display the value of the variable Set or change the value of the variable (Note: no space before and after '=') Delete the variable by setting to empty string (Note: nothing after '=') Display ALL the environment variables |
For examples,
// Set an environment variable prompt> set MY_VAR=hello // Display prompt> set MY_VAR MY_VAR=hello // Unset an environment variable prompt> set MY_VAR= // Display prompt> set MY_VAR Environment variable MY_VAR not defined
A variable set via the "set" command under CMD is a local variable, available to the current CMD session only.
Set an Environment Variable
To set an environment variable permanently in Windows (so that it is available to all the Windows' processes), start the "Control Panel" ⇒ "System" ⇒ (Vista/7/8) "Advanced system settings" ⇒ Switch to "Advanced" tab ⇒ "Environment variables" ⇒ Choose "System Variables" (for all users) or "User Variables" (for this login user only) ⇒ Choose "Edit" (for modifying an existing variable) or "New" (to create a new variable) ⇒ Enter the variable "Name" and "Value".
Using a Variable
To reference a variable in Windows, use %varname% (with prefix and suffix of '%'). For example, you can use the echo command to print the value of a variable in the form "echo %varname%".
// Display the PATH environment variable prompt> echo %PATH% PATH=xxxxxxx // Append a directory in front of the existing PATH prompt> set PATH=d:\bin;%PATH% PATH=d:\bin;[existing entries]
(Mac OS/Linux) How to Set or Change an Environment Variable
Variables in Unixes are case-sensitive. Global environment variables (available to ALL processes) are named in uppercase, with words joined with underscore (_), e.g., JAVA_HOME. Local variables (available to the current process only) are in lowercase.
Most of the Unixes (Ubuntu and Mac OS X) use the so-called Bash shell. Under bash shell:
- To list all the environment variables, use the command "
env" (or "printenv"). You could use "set" to list all the variables, including all local variables. - To reference a variable, use
$varname, with a prefix'$'(Windows uses%varname%). - To print the value of a particular variable, use the command "
echo $varname". - To set an environment variable, use the command "
export varname=value", which sets the variable and exports it to the global environment (available to other processes). Enclosed the value with double quotes if it contains spaces. - To set a local variable, use the command "
varname=value" (or "setvarname=value"). Local variable is available within this process only. - To unset a local variable, use command "
varname=", i.e., set to empty string (or "unsetvarname").
Set an Environment Variable Permanently
You can set an environment variable permanently by placing an export command in your Bash shell startup script "~/.bashrc" (or "~/.bash_profile", or "~/.profile") of your home directory; or "/etc/profile" for system-wide operations. Take note that files beginning with dot (.) is hidden by default. To display hidden files, use command "ls -a" or "ls -al".
For example, to add a directory to the PATH environment variable, add the following line at the end of "~/.bash_profile" (or "~/.profile"), under your home directory, or "/etc/profile".
export PATH=/usr/local/mysql/bin:$PATH
Similary, You can set the CLASSPATH environment variables by adding the following line. For example,
export CLASSPATH=.:/usr/local/tomcat/lib/servlet-api.jar
Take note that Bash shell uses colon (:) as the path separator; while windows use semi-colon (;).
To refresh the bash shell, issue a "source" command (or re-start the bash shell):
// Refresh the bash shell $ source ~/.bashrc // or $ source ~/.bash_profile // or $ source /etc/profile
(Notes) For the older csh (C-shell) and ksh (Korn-shell)
- Use "
printenv" (or "env") to list all the environment variables. - Use "
setenv varname value" and "unsetenv varname" to set and unset an environment variable. - Use "
set varname=value" and "unset varname" to set and unset a local variable for the current process.
Java Applications and the Environment Variables PATH, CLASSPATH, JAVA_HOME
Many problems in the installation and running of Java applications are caused by incorrect setting of environment variables (global system variables available to all the processes running under the system), in particular, PATH, CLASSPATH and JAVA_HOME.
PATH
When you launch a program from the command line, the operating system uses the PATH environment variable to search for the program in your local file system. In other words, PATH maintains a list of directories for searching executable programs.
PATH (For Windows)
When you launch an executable program (with file extension of ".exe", ".bat" or ".com") from the CMD shell, Windows searches for the executable program in the current working directory, followed by all the directories listed in the PATH environment variable. If the program cannot be found in these directories, you will get the following error:
// (Windows 2000/XP/Vista/7/8) "cmd.exe" prompt> xxxx 'xxxx' is not recognized as an internal or external command, operable program or batch file. // (Windows 95/98) "command.com" prompt> xxxx Bad command or file name
For example, if Java Compiler "javac.exe" is not found in the current directory and all the directories in the PATH, you will receive this error when compiling java source code:
PATH maintains a list of directories. The directories are separated by semi-colon ';'.
For Java applications, PATH must include the following directories:
- JDK's "
bin" directory (e.g., "c:\Program Files\java\jdk1.7.0_{xx}\bin"), which contains JDK programs such as Java Compiler "javac.exe" and Java Runtime "java.exe". - "
c:\windows\system32" and "c:\windows" which contain console programs and commands.
NOTES: The JDK's "bin" directory should be listed before "c:\windows\system32" and "c:\windows" in the PATH. This is because some older Windows systems provide their own Java runtime (which is often outdated) in these directories (try search for "java.exe" in your computer!).
To manipulate the PATH environment variable, you could use command "set PATH" (just like any environment variable). But as PATH is frequently used, a dedicated command called path is provided.
prompt> PATH prompt> PATH=value prompt> PATH= prompt> PATH=D:\bin;D:\bin\java prompt> PATH=D:\bin;%PATH% |
Display all the search paths, same as "set PATH" and "echo %PATH%" Set the value of PATH, same as "set PATH=value" (Note: no space before and after '=') Delete PATH (set it to empty string), same as "set PATH=" Set search paths, separated by semi-colon Insert "D:\bin" in front of the current PATH |
In Windows, the current working directory '.' is automatically included in the PATH, as the first entry. In other words, the current working directory is searched first, before searching the other entries specified in PATH, in a the order specified.
For Windows users, you could set the PATH permanently to include JDK's "bin" directory via "Control Panel" ⇒ "System"⇒ (Vista/7/8) "Advanced system settings" ⇒ Switch to "Advanced" tab ⇒ "Environment variables" ⇒ Under "System Variables" (for all users) ⇒ Select variable "PATH" ⇒ Choose "Edit" (for modifying an existing variable) ⇒ In "Value", INSERT your JDK's "bin" directory (e.g., "c:\Program Files\Java\jdk1.7.0_{xx}\bin"), followed by a semi-colon ';', IN FRONT of all the existing PATH entries. DO NOT remove any existing entry; otherwise, some programs may not run.
PATH (For Mac and Ubuntu)
Most of the Unixes and Mac use the so-called Bash Shell in the "Terminal". When you launch an executable program (with file permission of executable) in a Bash shell, the system searches the program in ALL the directories listed in the PATH. If the program cannot be found, you will get the following error:
$ xxxx
bash: xxxx: command not found
To list the current PATH, issue command:
$ echo $PATH
To add a directory (e.g., /usr/local/mysql/bin) to the existing PATH (referenced as $PATH) permanently, you can add the following line at the end of the .bashrc (or .bash_profile) of the home directory of the user; or /etc/profile for all users.
export PATH=/usr/local/mysql/bin:$PATH
The directories are separated by colon (:) as shown in the above example.
In Bash Shell, the current directory is NOT searched, unless it is included in the PATH. As a result, you have to enter "./programName" to run program stored in the current directory (the '.' denotes the current directory). It is recommended to include the current directory in the PATH by adding this line at the end of the .bashrc or .bash_profile of your home directory; or /etc/profile for all users.
export PATH=.:$PATH
CLASSPATH
Java Archive (JAR) File
For ease of distribution, Java classes are often archived (zipped) together into a so-called JAR file. To use a third-party Java package, you need to place the distributed JAR file in a location that is available to the Java Compiler and Java Runtime.
How Classes are Found?
Java Compiler ("javac"), Java Runtime ("java") and othe Java tools searches for classes used in your program in this order:
- Java platform (bootstrap) classes: include system classes in core packages (
java.*) and extension packages (javax.*) in "rt.jar" (runtime class), "i18n.jar" (internationalization class),charsets.jar,jre/classes, and others. - Java Extension Directories: You can copy the external JAR files into Java Extension Directory.
- For Windows, the Java Extension Directory is located at "
<JAVA_HOME>\jre\lib\ext" (e.g., "c:\Program Files\Java\jdk1.7.0_{xx}\jre\lib\ext"). - For Mac, the JDK extension directories are "
/Library/Java/Extensions" and "/System/Library/Java/Extensions". - For Ubuntu, the JDK extension directories are "
<JAVA_HOME>/jre/lib/ext" (e.g., "/usr/user/java/jdk1.7.0_{xx}/jre/lib/ext") and "/usr/java/packages/lib/ext".
java.ext.dirs". You can print its contents viaSystem.out.println(System.getProperty("java.ext.dirs")). - For Windows, the Java Extension Directory is located at "
- User classes search path (in short, class path): determined in the following order:
- Defaulted to the current working directory (
.). - Entries in the
CLASSPATHenvironment variable, which overrides the default. - Entries in the
-cp(or-classpath) command-line option, which overrides theCLASSPATHenvironment variable. - The runtime command-line option
-jar, which override all the above.
java.class.path".
It is recommended that you use the-cp(or-classpath) command-line option (customized for each of your applications), instead of setting a permanentCLASSPATHenvironment for all the Java applications. IDE (such as Eclipse/NetBeans) manages-cp(-classpath) for each of the applications and does not rely on theCLASSPATHenvironment. - Defaulted to the current working directory (
Cannot Find Classes
If the Java Runtime ("java") cannot find the classes used in your program in all the above places, it will issue error "Could not find or load main class xxxx" (JDK 1.7) or "java.lang.NoClassDefFoundError" (Prior to JDK 1.7).
Similarly, Java Compiler ("javac") will issue compilation errors such as "cannot find symbol", "package does not exist".
Notes: External native libraries (".lib", ".dll", ".a", ".so") are to be found in a path in JRE's Property "java.library.path", which normally but not necessarily includes all the directories in the PATH environment variable. Otherwise, you will get a runtime error "java.lang.UnsatisfiedLinkError: no xxx in java.library.path".
CLASSPATH Environment Variable
The CLASSPATH environment variable could include directories (containing many class files) and JAR files (a single-file archive of class files). If CLASSPATH is not set, it is defaulted to the current directory. If you set the CLASSPATH, it is important to include the current working directory (.). Otherwise, the current directory will not be searched.
A common problem in running hello-world program is: CLASSPATH is set but does not include the current working directory. The current directory is therefore not searched, which results in "Error: Could not find or load main class Hello". You can simply remove the CLASSPATH, and leave the class path defaulted to the current directory.
For a beginner, no explicit CLASSPATH setting is required. The default CLASSPATH setting of current directory is sufficient. Remove all CLASSPATH setting if there is any. However, if you have to set CLASSPATH, make sure that you include the current directory '.'.
The PATH environment variable (for searching the executable programs) is applicable to all applications; while CLASSPATH is used by Java only.
Read JDK documents "Setting the CLASSPATH" and "How Classes are Found" (you can find the hyperlinks from the index page of the JDK documentation, or googling).
CLASSPATH Environment Variable (For Windows)
The CLASSPATH accepts directories and jar-files. Path entries are separated by semi-colon (;).
Example: Displaying and changing CLASSPATH for the current CMD session.
// Display current setting of CLASSPATH prompt> set CLASSPATH // Unset (remove) CLASSPATH prompt> set CLASSPATH= // Set CLASSPATH to the current directory '.' prompt> set CLASSPATH=. // Set CLASSPATH to the current directory and a JAR file prompt> set CLASSPATH=.;d:\tomcat\lib\servlet-api.jar
You can set the CLASSPATH permanently via "Control Panel" ⇒ "System"⇒ (Vista/7/8) "Advanced system settings" ⇒ Switch to "Advanced" tab ⇒ "Environment variables" ⇒ Choose "System Variables" (for all users) or "User Variables" (for this login user only):
- To modify the existing
CLASSPATH, select variable "CLASSPATH" and Choose "Edit" ⇒ In variable "Value", provide the directories and jar-files, separated by semi-colon';'. Make sure that the current directory'.'is included as the first entry. - To create
CLASSPATH⇒ Choose "New" ⇒ In variable "Name", enter "CLASSPATH" ⇒ In variable "Value", provide the directories and jar-files, separated by semi-colon';'. Make sure that the current directory'.'is included as the first entry.
CLASSPATH (for Mac and Ubuntu)
- To set the
CLASSPATHfor the current session, issue this command:export CLASSPATH=.:/usr/local/tomcat/bin/servlet-api.jar
Use colon ':' as the path separator (instead of semi-colon ';' in Windows). - To set the
CLASSPATHpermanently, place the above export command in the bash shell initialization script (.bashrcor.bash_profileof the home directory or/etc/profilefor all users).
JAVA_HOME and JRE_HOME
Set JAVA_HOME to your JDK installation directory (e.g., "c:\Program Files\java\jdk1.7.0_{xx}"). JAVA_HOME is needed for running Tomcat and many other Java applications.
You can optionally set JRE_HOME to the JRE base directory (e.g., "c:\Program Files\java\jre7").
Read the above section on how to set or change environment variable (in Windows, Mac and Unixes).
Notes: Windows vs. Unixes (Mac OS/Ubuntu)
Java is platform independent. Java classes run in Windows as well as Unixes - binary compatible.
- Unixes have many shells, such as the newer
bashand the oldercsh,ksh. Windows have two shells: the newercmd.exeand the oldercommand.com. Each shell come with its own set of commands, utilities, and its own scripting programming language. - Unix's variable name is denoted as
$varname, e.g.,$CLASSPATH. Windows uses%varname%, e,g.,%CLASSPATH%. - Unix uses command "
printenv" (print environment) or "env" to list all the environment variables. Windows uses command "set". - Unix's
PATHis set permanently in the login or shell initialization script (e.g., "~/.login", "~/.profile", "~/.bashrc", "~/.bash_profile", or "/etc/profile"). Windows'PATHis set permanently via Control Panel ⇒ System ⇒ .... - The current directory is NOT included in the Unix's
PATHimplicitly. To run a program in the current directory, you need to issue "./programName" where "." denotes the current directory. It is recommended to include the current direcotry (.) in thePATHexplicitly. On the other hand, current directory is included in Windows'PATHimplicitly. - A Windows' path includes a drive letter and directories. Each drive has a root directory. It uses back-slash
'\'as directory separator (e.g., "c:\jdk1.6\bin"). Linux's paths do not have drive letter. There is a single root. Unix uses forward slash'/'as the directory separator (e.g., "/usr/bin/jdk1.6"). - Windows use semi-colon
';'as path separator (e.g., inPATHenvironment variable), while Unix uses colon':'. - Windows/DOS uses "
0D0AH" (carriage-return plus line-feed) as line-break (or End-of-Line (EOL)). Unix uses "0AH" (line-feed) only. Mac uses "0DH" up to OS 9 and "0AH" from OS X.