Jar in classpath but still class not found

P

Philipp

Sorry, this seems so obvious, but I can't find why it doesn't work.

1. Class MyPrinter in package mytest
package mytest;
public class MyPrinter {
public void print(){
System.out.println("Hello!");
}
}

2. Class PrintTest imports package mytest.MyPrinter and uses it. Note
PrintTest is in default package.
import mytest.MyPrinter;
public class PrintTest {
public static void main(String[] args) {
MyPrinter ps = new MyPrinter();
ps.print();
}
}

I export the package mytest as a Printer.jar file:
META-INF/MANIFEST.MF contains just:
Manifest-Version: 1.0

Printer.jar contains a folder mytest with the compiled class
MyPrinter.class in it.

Now I want to run PrintTest using that compiled file in the jar, so I
compile it:
$ javac -cp Printer.jar PrintTest.java

Compilation succeeds and PrintTest.class is created.

Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
Caused by: java.lang.ClassNotFoundException: PrintTest
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: PrintTest. Program will exit.


But this works!
$ java -Xbootclasspath/a:printer.jar PrintTest
Hello!

What am I doing wrong?

Thanks Phil
 
J

John B. Matthews

[...]
Note PrintTest is in default package. [...]
Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest [...]
What am I doing wrong?

Your classpath omits the current directory:

java -cp .:printer.jar PrintTest
 
P

Philipp

[...]
Note PrintTest is in default package. [...]
Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest [...]
What am I doing wrong?

Your classpath omits the current directory:

java -cp .:printer.jar PrintTest

Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
[...]


I noticed that when compiling:
$ javac -cp Printer.jar PrintTest.java
I end up with a file MyPrinter.class in the folder. This is the one
which should be (and is) in the jar. Where is that file coming from?

If I compile with the classpath set to the current folder as well, I
get a compile error:
$ javac -cp .:printer.jar PrintTest.java
PrintTest.java:1: package mytest does not exist
import mytest.MyPrinter;
^
PrintTest.java:4: cannot find symbol
symbol : class MyPrinter
location: class PrintTest
MyPrinter ps = new MyPrinter();
^
PrintTest.java:4: cannot find symbol
symbol : class MyPrinter
location: class PrintTest
MyPrinter ps = new MyPrinter();
^
3 errors


Should the manifest in the jar contain more details (it's basically
empty now)?

Phil
 
L

Lew

Note PrintTest is in default package. [...]
Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest [...]
What am I doing wrong?
Your classpath omits the current directory:
java -cp .:printer.jar PrintTest

Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
[...]

I noticed that when compiling:
$ javac -cp Printer.jar PrintTest.java
I end up with a file MyPrinter.class in the folder. This is the one
which should be (and is) in the jar. Where is that file coming from?

If I compile with the classpath set to the current folder as well, I
get a compile error:
$ javac -cp .:printer.jar PrintTest.java
PrintTest.java:1: package mytest does not exist
import mytest.MyPrinter;
             ^
PrintTest.java:4: cannot find symbol
symbol  : class MyPrinter
location: class PrintTest
                MyPrinter ps = new MyPrinter();
                ^
PrintTest.java:4: cannot find symbol
symbol  : class MyPrinter
location: class PrintTest
                MyPrinter ps = new MyPrinter();
                                   ^
3 errors

Should the manifest in the jar contain more details (it's basically
empty now)?

What is the output of "jar -tf Printer.jar"?
 
J

John B. Matthews

Philipp said:
[...]
Note PrintTest is in default package. [...]
Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest [...]
What am I doing wrong?

Your classpath omits the current directory:

java -cp .:printer.jar PrintTest

Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest

Hmn, no PrintTest.class in either the current directory or Printer.jar.
Where is it?
I noticed that when compiling:
$ javac -cp Printer.jar PrintTest.java
I end up with a file MyPrinter.class in the folder. This is the one
which should be (and is) in the jar. Where is that file coming from?

I suspect from the compiler. What's in Printer.jar? Try, `jar tf
Printer.jar`
If I compile with the classpath set to the current folder as well, I
get a compile error:
$ javac -cp .:printer.jar PrintTest.java
PrintTest.java:1: package mytest does not exist

Does the directory "mytest" exist?

[...]
Should the manifest in the jar contain more details (it's basically
empty now)?

Empty or non-existent? You can print the manifest, _in_situ_, using a
program like that below; the page also has links to the documentation:

<http://sites.google.com/site/drjohnbmatthews/manifesto>
 
L

Lew

Philipp said:
Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
[...]

It seems to me you are using Windows.  So, you should use a semicolon
(not a colon) as the classpath entries separator.

On what are you basing the idea that the OP is using Windows?

There is absolutely no evidence in this thread that he is.

There's also no proof that he isn't, so the comment might apply. I'm
just curious on what you based your hypothesis.
 
L

Lars Enderin

Lew said:
Philipp said:
Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
[...]
It seems to me you are using Windows. So, you should use a semicolon
(not a colon) as the classpath entries separator.

On what are you basing the idea that the OP is using Windows?

There is absolutely no evidence in this thread that he is.

There's also no proof that he isn't, so the comment might apply. I'm
just curious on what you based your hypothesis.

Philipp uses Opera, a Windows program, to post.
 
L

Lars Enderin

Martin said:
What makes you think Opera is a Windows-only program?

I don't. I was a little unclear and realized too late that somebody
would interpret my message like you did. A header line from one of his
posts shows that he used Windows:

X-HTTP-UserAgent: Opera/9.64 (Windows NT 5.1; U; en)
Presto/2.1.1,gzip(gfe),gzip(gfe)

He posts via Google Groups.
 
L

Lew

Putting the jar in one of the directories on the classpath is not
sufficient. The name of the jar itself must be on the classpath or the
jar must be in the ext directory.


Good point, although it doesn't apply to the OP's specific situation
since he did put the JAR itself into the classpath.
 
L

Lew

Lars said:
A header line from one of his posts shows that he used Windows:

It shows that he used Windows to post his message. It doesn't prove
that he used Windows to run his Java program.

If he did, then your comment certainly applies - he'd need to use
semicolons to separate classpath elements.
 
L

Lars Enderin

Lew said:
It shows that he used Windows to post his message. It doesn't prove
that he used Windows to run his Java program.

If he did, then your comment certainly applies - he'd need to use
semicolons to separate classpath elements.
I just offered a possible clue, no proof, and I did not make the
original suggestion about Windows.
 
P

Philipp

Hello and sorry for the late answer,

<[email protected]>,
[...]
Note PrintTest is in default package.
[...]
Now executing:
$ java -cp Printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest
[...]
What am I doing wrong?
Your classpath omits the current directory:
java -cp .:printer.jar PrintTest
Thanks for the ansnwer, but this does not solve the problem! I still
get
$ java -cp .:printer.jar PrintTest
Exception in thread "main" java.lang.NoClassDefFoundError: PrintTest

Hmn, no PrintTest.class in either the current directory or Printer.jar.
Where is it?
[...]
I noticed that when compiling:
$ javac -cp Printer.jar PrintTest.java
I end up with a file MyPrinter.class in the folder. This is the one
which should be (and is) in the jar. Where is that file coming from?

What's in Printer.jar?  Try, `jar tf
Printer.jar`

Thanks to all, it is working now. Piotr pointed out the ";" separator,
which was in fact the problem. But this did not fix the thing
immediately as I'm trying this in cygwin on WinXP. The ; in the
command line was interpreted as an end of command by bash. So I got an
error, java not parsing the arguments correctly:

$ java -cp .;Printer.jar PrintTest
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)
[...]

The correct version being (note the quotes):
$ java -cp ".;Printer.jar" PrintTest
Hello!

A thing I still don't understand is why MyPrinter.class gets created
from the source in the jar. Here's the state:

$ which java
/cygdrive/c/WINDOWS/system32/java

$ ls
PrintTest.java Printer.jar

$ jar -tf Printer.jar
META-INF/MANIFEST.MF
mytest/MyPrinter.class
mytest/MyPrinter.java

Then compiling
$ javac -cp Printer.jar PrintTest.java

$ ls
MyPrinter.class PrintTest.class PrintTest.java Printer.jar

Why is MyPrinter.class created?

Phil
 
L

Lew

Philipp said:
Thanks to all, it is working now. Piotr pointed out the ";" separator,
which was in fact the problem. But this did not fix the thing
immediately as I'm trying this in cygwin on WinXP. The ; in the
command line was interpreted as an end of command by bash. So I got an
error, java not parsing the arguments correctly:

Well, duh.
The correct version being (note the quotes):
$ java -cp ".;Printer.jar" PrintTest

Alternatively,
$ java -cp .\;Printer.jar PrintTest

Single quotes are also an option.

This is basic bash.

$ man bash

You have to know your shell.
 
J

John B. Matthews

[...]
Thanks to all, it is working now.
Excellent.

[...]
A thing I still don't understand is why MyPrinter.class gets created
from the source in the jar. Here's the state:

$ which java
/cygdrive/c/WINDOWS/system32/java

$ ls
PrintTest.java Printer.jar

$ jar -tf Printer.jar
META-INF/MANIFEST.MF
mytest/MyPrinter.class
mytest/MyPrinter.java

Then compiling
$ javac -cp Printer.jar PrintTest.java

$ ls
MyPrinter.class PrintTest.class PrintTest.java Printer.jar

Why is MyPrinter.class created?

"If the -sourcepath option is not specified, the user class path is also
searched for source files."

<http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html>
 
J

John B. Matthews

Lew said:
Well, duh.

Proper quotes sometimes escape me, for which I am surely to be punished.
Alternatively,
$ java -cp .\;Printer.jar PrintTest

Single quotes are also an option.

This is basic bash.

$ man bash

You have to know your shell.

I spent enough time reading Cooper's "Advanced Bash-Scripting Guide" to
understand how much I needed to start with Garrels' "Bash Guide for
Beginners."

<http://tldp.org/guides.html>
 
J

John B. Matthews

[QUOTE="Lew said:
Proper quotes sometimes escape me, for which I am surely to be punished.

You can avoid quotes with proper escapes, which I state rather punnishly.[/QUOTE]

I was abashed that my joke might be too obscure. My faith is re-Bourne.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top