How to set the classpath correctly in java - java

I need to compile and run simple code using the gson library, but I can't use Maven, Gradle or the IDE.
The directory contains Main.java and gson-2.9.0.jar
javac -cp gson-2.9.0.jar Main.java works correctly and creates Main.class
But when I run java -cp ./*: Main, I get
Error: Could not find or load main class Main.
Caused by: java.lang.ClassNotFoundException: Main
I also tried the following commands:
java -cp gson-2.9.0.jar Main
java -cp gson-2.9.0.jar: Main
java -cp ./gson-2.9.0.jar:./* Main
But all these commands give the same result. I've never had to run code from the command line without Maven or IDEA before, so I think it's the classpath specification that's the problem. What am i doing wrong here?

If your main class is in a package (has a package ... declaration), you need to include the package name in the java call, e.g. java -cp ... mypackage.Main.
Additionally, the java documentation says about -cp / --class-path:
As a special convenience, a class path element that contains a base name of an asterisk (*) is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR.
Therefore, using * for .class files does not work; instead you have to specify the directory name. Based on your question it looks like you are using Linux, and that the .class file and the JAR are in the same directory, so the following should work in your case:
java -cp gson-2.9.0.jar:. Main
(note the . after the :, indicating to include the current directory for the classpath)

Related

run java file in windows command prompt

I want to run a java project in windows. I first compiled the .class file in linux. Copy back to windows. Now under the path H:\deletefiles has delete.class, delete.java, a.jar, b.jar. The package for class delete is deleteFiles.
My java class path is C:\program Files\Java\jre7\bin, Where I have no access to write.
I run in command prompt C:\program Files\Java\jre7\bin>
java -cp H:\deleteFiles\deleteFiles.delete
always has the problem could not find or load main class, what's the problem? thanks
You are missing the actual class to be run. The -cp H:\deleteFiles\deleteFiles.delete only defines the classpath to be used, but not which class you want to run (and you limit the classpath to a single class as well).
What you want is:
java -cp H:\deleteFiles\deleteFiles delete
Note the blank (space) between H:\deleteFiles\deleteFiles which means you are passing two parameters to the java command:
-cp H:\deleteFiles\deleteFiles - the classpath to use
delete - the class to run
If you need the classes that are part of the jar files, you need to add them to the classpath as well:
java -cp H:\deleteFiles\deleteFiles;H:\deleteFiles\deleteFiles\a.jar;H:\deleteFiles\deleteFiles\b.jar delete
You need to set the classpath to the location which contains the package hierarchy. If your package is named deleteFiles the location needs to contain a directory named deleteFiles which contains the class file.
In your example you would run it with
java -cp H:\ deleteFiles.delete
you should call delete.class in your java command line, like this:
java -cp H:\deleteFiles\delete
To execute a Java program you have two options. Using a class file or using a jar file.
If your program only contains a single source file, executing the class file would be fine. But if you have multiple sources, you would have to copy all of them. Then a jar would be more practicable.
For class:
java -cp <class path> <class name>
For jar (if the main class is set):
java -jar <jar file>

Using JAR Files

So I'm still a noob in Java and I'm experimenting around with a few things.
I recently created a .jar file for my class using jar cvf <name>.jar <source files> and then used that jar to compile my driver class (javac -cp <name>.jar Driver.java) though how do I now run that class using the jar?
I've tried the following 2 commands:
java Driver and,
java -cp <name>.jar Driver.
The first gives me a NoClassDefFoundError for the class used, whereas the latter just gave me a single line error.
Error: Could not find or load man class Driver
What am I doing wrong? Is it possible I'm confusing this for something else?
I'm trying to do as much as I can without the use of any IDE.
You should put jar file and compiler output into classpath and specify main class:
java -classpath "<name.jar>;classes" Driver
EDIT (thanks to Kayaman):
If you are running command from linux/unix you have to use ":" as separator (in Windows works ";"). "classes" is a path to folder containing compiler output.
When creating an executable jar ( jar which contain a class with the main method) you should tell the jar which is the mainClass to be executed and for that you should create a file called 'Manifest.mf'.
The file should contain this:
Main-Class: MyPackage.MyClass
And when creating the jar you should use this to include your manifest:
jar cfm MyJar.jar Manifest.mf MyPackage/*.class
And for launching your jar :
java -jar MyJar.jar

What does "Exception in thread \"main\" java.lang.NoClassDefFoundError" mean when executing java .class file?

Java and Gradle beginner's question.
I made a project directory for java and gradle test:
The directory hierarchy :
HelloWorld.java:
package foo.bar;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
build.gradle:
apply plugin:'java'
Then,gradle build this project and generated what i need.
As you see above, my problem is why doesn't this execute correctly? Even through I cd to .class path.
======================================================================
While, if I remove package foo.bar; in HelloWorld.java, and repeat gradle commands and execute at he.bak directory then the error remained the same.
But when I cd to the directory where HelloWorld.java placed. everything goes OK!Why? something related with CLASSPATH environment variables or other causes?
////////////////////////////////////////////////////////////////////
UPDATE
////////////////////////////////////////////////////////////////////
Thought you guys' warm replies, I know that I should combine the CLASSPATH and the period-separated executable .class file to figure out what's going on when executing java class file.
I experiment my thought resulting in 2 point to this question:
The -cp option path parameter A/B plus the executable file c.d.e.class finally form the A/B/c.d.e.class full path where the class is actually located.
If I specify the package in source code file with package d,I must split the full path in the form of java -cp A/B/c/d e.class. split in other ways all will result in errors.
something I am not sure here is :
When I specify my package path in my source code file, It determined the only classpath when executing corresponding executable, right?
If it is the truth, How does a project with lots of package and sources files work?
What's the root principle?
When in build/classes/main try java foo.bar.HelloWorld instead of java HelloWorld
The reason you need to specify foo.bar.HelloWorld is because you specified package foo.bar;. This tells java that the class should be in foo/bar/HelloWorld and the fully qualified name for HelloWorld is foo.bar.HelloWorld. If you want to execute the class from a different working directory however, you can specify the classpath explicitly using the -cp option, e.g., java -cp c:\myproject\build\classes\main foo.bar.HelloWorld.
By the way, the classpath default is the current working directory (i.e., .) but java -cp c:\myproject\build\classes\main foo.bar.HelloWorld will NOT have the classpath set to the current working directory if it is explicitly set using the -cp option. If you want to include the current working directory but explicitly set it, or even add more directories, you can chain them using semicolons like this: java -cp .;c:\myproject\build\classes\main foo.bar.HelloWorld. So this will include both the current working directory and the directory I specified.

Having trouble setting the Java classpath from terminal

My directories are structured as follows: /User/JAVA/MyProject/
In the MyProject folder, I have my Main.java and Helper.java files
In the JAVA folder, I have two JAR files: jar1.jar and jar2.jar
I would like to set my classpath to these two JARs so I can use them in my Main.java and Helper.java files. Very simple.
To do this, I have tried the following (as well as numerous other variations) from my terminal:
user:MyProject$ javac -cp "/User/JAVA/jar1.jar:/User/JAVA/jar2.jar:." Main.java
EDIT: I am now using this command, as suggested, and receiving the same errors
user:MyProject$ javac -cp "/User/JAVA/jar1.jar:/User/JAVA/jar2.jar:." Helper.java Main.java
From what I've read, this should work. I have specified the absolute locations of the two JARs, I have separated them by a colon : (I am on OSX), and I have also included my current directory .. Then I have specified the file containing my main method with Main.java.
Unfortunately, I keep receiving a "Cannot find symbol" for the classes' methods in the JARs when I try to compile.
Furthermore, when I try System.out.println(System.getProperty("java.class.path"));, I receive the following output ., indicating my classpath is still set to my current directory.
My error is this:
/User/JAVA/MyProject/Helper.java:13 cannot find symbol
symbol: variable StdOut
location: class Helper
To note:
When I opened my project up in Eclipse and added the classpath via the IDE, everything worked as expected and no error messages appeared during compilation. Nevertheless, I still would like to figure out how to do this from terminal and without the IDE.
What am I doing wrong, and how do I fix this?
Thanks.
Using -cp when compiling or running sets the classpath. That overrides (ignores) anything you would have put in the env variable CLASSPATH.
Since you didn't post the actual error you're receiving I'm going to guess the missing symbol is from your other class that Main is referencing. Add it to the command:
javac -cp "/User/JAVA/jar1.jar:/User/JAVA/jar2.jar:." Helper.java Main.java
Edit due to the OP posting the actual error: You have a an error in your class that makes it uncompilable. It has nothing to do with jar files or classpaths. You are attempting to use / reference a variable named StdOut that doesn't exist.
You should use the semicolon paths separator (;), as discribed in Setting the classpath document.
But you are using colon instead (:).
Try to use the following command (copy and paste it):
javac -cp /User/JAVA/jar1.jar;/User/JAVA/jar2.jar Helper.java Main.java
from your /User/JAVA/MyProject directory.
EDIT:
All above is for Windows.
The problem is in paths themselves.

default classpath current directory anomaly

I am trying to compile and run simple Java program. This program basically prints out hello world phrase. I am not specifying -cp option and I don't have CLASSPATH environment variable. Hence the user classpath is limited only to current directory.
Now, compilation works beautifully.
rustam#rustam-laptop:~/temp/bird_test$ javac Sparrow.java
This command produces needed .class file. The weird stuff happens when I try to run .class file. The following command works good.
rustam#rustam-laptop:~/temp/bird_test$ java Sparrow
But when I try the following command
rustam#rustam-laptop:~/temp/bird_test$ java ./Sparrow
I receive the following error:
Error: Could not find or load main class ..Sparrow
WTF! i thought that symbol ./ refers to current directory.
java takes a class name as argument. It doesn't take a file path. The class name (Sparrow) is then resolved by the java class loader to a .class file based on the classpath, i.e. it looks for a Sparrow.class file in every directory and jar listed in the classpath.
Let's take an example that respects good practices, and thus doesn't use the default package:
package foo.bar;
public class Baz {
...
}
The class name of the above class is foo.bar.Baz. To execute it, you must use
java foo.bar.Baz
and java will look for a foo/bar/Baz.class in all the directories listed in the classpath. So if the classpath is set to /hello/world, it will look for the file /hello/world/foo/bar/Baz.class.

Categories

Resources