Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java "could not find or load main class" with classpath error

I have been facing an issue while compiling with -cp or the -classpath flag in Java. I will try to explain the problem below:

Let's say; I have two files - A.java and B.java. A.java has a simple public class with a private instance variable, one get and one set method. B.java is the driver method for A. It instantiates A; sets some value for A's instance variable and finally prints out the value using the get method in A.

I can compile both A.java and B.java from command line. If both compiled class files are in same folder; the following runs fine:

java B

However; say I keep A.class in a separate folder. Or even better; I make a JAR file of the class file A.class. Now; I should be able to compile B.java with the classpath properly stated.

The compilation works.

javac -cp ..\Lib\A.jar -d ..\Bin B.java

It puts the B.class file in Bin folder as expected. Now; if I go to Bin folder and try to execute the following;

java -cp ..\Lib\A.jar B

I get the error:

Error: Could not find or load main class B

Now; I have been trying in vain to solve this problem for past few days. This is a simple use case to demonstrate the problem; but in reality - I am not being able to link to an existing JAR library using -classpath or -cp flag. The only way I can run my Java programs from command line is if I extract the class files from JAR archive in the same directory as the output class. So, then I would not need to include the classpath flag in the execution command.

But this is something I don't want. I want to keep my JAR archive separate from the output class files of my source code. I know that using an IDE; this is something I won't need to worry about. But I am more interested in the command line solution; to understand what goes behind the hood.

I have gone through all other suggestions on StackOverflow regarding this - but none seems to work. FYI, I am using default package in all cases. No packaging is explicitly specified.

Please help. Thanks in advance!

Update: I have been asked to provide my directory structure in a readable format, so here goes:

$pwd
C:\My\Path\To\Java\Programs\Top
$ls
Source
Bin
Lib
$cd Bin 
$ls
B.class
$ls ..\Source\
A.java
B.java
$ls ..\Lib
A.jar
$jar tf ..\Lib\A.jar
META-INF
META-INF/MANIFEST.MF
A.java
A.class

I hope that clears it. I am using Windows Powershell, so sub-directories are marked with "\". If I were typing in Unix terminal, it would have been "/" instead. By the way, I tried this on Ubuntu 14.04, with no avail. I have also tested this with jdk 1.6 to jdk 1.8 - again, same error.

like image 553
Arijit Layek Avatar asked Jul 11 '14 06:07

Arijit Layek


1 Answers

You are missing out the "classpath" while trying to run your program.

One is mistaken to think that "-cp ..\Lib\A.jar" is to include A.class during the runtime. But the thing is that, "-cp" option is to set the classpath and not include. That way one is missing the classpath for the class "B".

So to run your program, from the "Bin" folder, the correct command (for any Windows system) is : "java -cp .;..\Lib\A.jar B". The "." makes all the difference, referring to the current directory.

For Linux, the command, from the "Bin" folder, becomes : "java -cp .:../Lib/A.jar B".

The main difference is of the separator, ";" is for Windows and ":" is for Linux.

like image 143
Malay Avatar answered Oct 11 '22 08:10

Malay