17

Okay, I'm very new to linux and command line, and fairly new to java. I got an internship building a java program. I finally got it done on my machine (windows) and now I have to migrate it to a linux machine to test and then have it run as an executable. I have done much reading and researching on linux and understanding classpaths but it is still all very hard to fully comprehend. It's just not clicking for me yet. Can anyone explain the purpose of classpath in a simplified way using examples? One of the most confusing aspects to me is actually defining the physical path to the jar. Do I start all the way from usr or do I only need to begin from the jvm folder? If it matters, my java program is not located in the jvm folder. Can anyone shed some light for me?

EDIT: thank you guys very much for your help, I can't say that I'm fully in the clear but my understanding of my situation is a lot better.

exit_1
  • 1,100
  • 4
  • 11
  • 30
  • Possible duplicate of [Including all the jars in a directory within the Java classpath](https://stackoverflow.com/questions/219585/including-all-the-jars-in-a-directory-within-the-java-classpath) – Stewart Oct 04 '17 at 11:50

5 Answers5

20

Say you have multiple jar files a.jar,b.jar and c.jar. To add them to classpath while compiling you need to do

$javac -cp .:a.jar:b.jar:c.jar HelloWorld.java

To run do

$java -cp .:a.jar:b.jar:c.jar HelloWorld
noPE
  • 499
  • 7
  • 17
12

You use the -classpath argument. You can use either a relative or absolute path. What that means is you can use a path relative to your current directory, OR you can use an absolute path that starts at the root /.

Example:

bash$ java -classpath path/to/jar/file MyMainClass

In this example the main function is located in MyMainClass and would be included somewhere in the jar file.

For compiling you need to use javac

Example:

bash$ javac -classpath path/to/jar/file MyMainClass.java

You can also specify the classpath via the environment variable, follow this example:

bash$ export CLASSPATH="path/to/jar/file:path/tojar/file2"
bash$ javac MyMainClass.java

For any normally complex java project you should look for the ant script named build.xml

Petriborg
  • 2,719
  • 2
  • 25
  • 48
  • 1
    So if the java program I am trying to compile is named SnortMonitor would your example change to: bash$ java -classpath path/to/jar/file SnortMonitor – exit_1 Jul 12 '12 at 20:22
  • 1
    Ah for compiling you need to call `javac` instead of `java`, but you still use -classpath and the source directory. – Petriborg Jul 12 '12 at 20:24
  • thankyou for your help but could you please be a little more specific? Maybe it's because of my lack of understanding. When I write "javac SnortMonitor.java, I get a list of errors and I know its because I need to include 2 jar files from a directory called jsendnsca. Do I need to include those jars in the classpath each time I compile and run the program? – exit_1 Jul 12 '12 at 20:30
  • 2
    Yes, thats right Pat - just say `javac -classpath jsendnsca.jar:otherjar.jar SnortMonitor.java` – Petriborg Jul 12 '12 at 20:32
  • Thankyou, is there a way that I can set it so that I do not have to define each jar each time I want to compile and run? – exit_1 Jul 12 '12 at 20:36
  • 1
    I believe that if you specify the environment variable `CLASSPATH` it will use that - I'll edit my answer to make it more clear how to do that. – Petriborg Jul 12 '12 at 20:38
5

The classpath is the place(s) where the java compiler (command: javac) and the JVM (command:java) look in order to find classes which your application reference. What does it mean for an application to reference another class ? In simple words it means to use that class somewhere in its code:

Example:

public class MyClass{
    private AnotherClass referenceToAnotherClass;
    .....
}

When you try to compile this (javac) the compiler will need the AnotherClass class. The same when you try to run your application: the JVM will need the AnotherClass class. In order to to find this class the javac and the JVM look in a particular (set of) place(s). Those places are specified by the classpath which on linux is a colon separated list of directories (directories where the javac/JVM should look in order to locate the AnotherClass when they need it).

So in order to compile your class and then to run it, you should make sure that the classpath contains the directory containing the AnotherClass class. Then you invoke it like this:

javac -classpath "dir1;dir2;path/to/AnotherClass;...;dirN" MyClass.java //to compile it
java -classpath "dir1;dir2;path/to/AnotherClass;...;dirN" MyClass //to run it

Usually classes come in the form of "bundles" called jar files/libraries. In this case you have to make sure that the jar containing the AnotherClass class is on your classpaht:

javac -classpath "dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN" MyClass.java //to compile it
java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN" MyClass //to run it

In the examples above you can see how to compile a class (MyClass.java) located in the working directory and then run the compiled class (Note the "." at the begining of the classpath which stands for current directory). This directory has to be added to the classpath too. Otherwise, the JVM won't be able to find it.

If you have your class in a jar file, as you specified in the question, then you have to make sure that jar is in the classpath too , together with the rest of the needed directories.

Example:

java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;path/to/MyClass/jar...;dirN" MyClass //to run it

or more general (assuming some package hierarchy):

java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;path/to/MyClass/jar...;dirN" package.subpackage.MyClass //to run it

In order to avoid setting the classpath everytime you want to run an application you can define an environment variable called CLASSPATH.

In linux, in command prompt:

export CLASSPATH="dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN" 

or edit the ~/.bashrc and add this line somewhere at the end;

However, the class path is subject to frequent changes so, you might want to have the classpath set to a core set of dirs, which you need frequently and then extends the classpath each time you need for that session only. Like this:

export CLASSPATH=$CLASSPATH:"new directories according to your current needs" 
Razvan
  • 9,372
  • 4
  • 35
  • 49
0

Step 1.

vi ~/.bashrc

Step 2. Append this line on the last:

export CLASSPATH=$CLASSPATH:/home/abc/lib/*;  (Assuming the jars are stored in /home/abc/lib) 

Step 3.

source ~/.bashrc

After these steps direct complile and run your programs(e.g. javac xyz.java)

user7294900
  • 47,183
  • 17
  • 74
  • 157
0

For linux users, you should know the following:

  1. $CLASSPATH is specifically what Java uses to look through multiple directories to find all the different classes it needs for your script (unless you explicitly tell it otherwise with the -cp override). Using -cp (--classpath) requires that you keep track of all the directories manually and copy-paste that line every time you run the program (not preferable IMO).

  2. The colon (":") character separates the different directories. There is only one $CLASSPATH and it has all the directories in it. So, when you run "export CLASSPATH=...." you want to include the current value "$CLASSPATH" in order to append to it. For example:

    export CLASSPATH=.
    export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar
    

    In the first line above, you start CLASSPATH out with just a simple 'dot' which is the path to your current working directory. With that, whenever you run java it will look in the current working directory (the one you're in) for classes. In the second line above, $CLASSPATH grabs the value that you previously entered (.) and appends the path to a mysql dirver. Now, java will look for the driver AND for your classes.

  3. echo $CLASSPATH
    

    is super handy, and what it returns should read like a colon-separated list of all the directories you want java looking in for what it needs to run your script.

  4. Tomcat does not use CLASSPATH. Read what to do about that here: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Adam Winter
  • 973
  • 7
  • 19