Running java programs from class files

M

mark13.pl

Hello,

I have created two class: ClassOne & ClassTwo (with main) in MyClass
package. When I run it in eclipse everything goes okay. When I create
jar and choose ClassTwo as Main everything goes okay.
But now I am interested in running it just from class files. What is a
correct syntax for such example?!?
I tried:
"java -classpath . ClassTwo" and similar but never run it getting all
the time: NoClassDefFoundError.

Regards, mark
 
K

Knute Johnson

Hello,

I have created two class: ClassOne & ClassTwo (with main) in MyClass
package. When I run it in eclipse everything goes okay. When I create
jar and choose ClassTwo as Main everything goes okay.
But now I am interested in running it just from class files. What is a
correct syntax for such example?!?
I tried:
"java -classpath . ClassTwo" and similar but never run it getting all
the time: NoClassDefFoundError.

Regards, mark

If your classes are in a package, then you must be in the directory
above the package to run from class files. So if you package is called
MyPackage, your class file is called MyClass.class and the MyPackage
directory is located in /xyz/abc then you must be in /xyz/abc. To
execute your program then you must type java MyPackage.MyClass.
 
M

Matt Rose

Hello,

I have created two class: ClassOne & ClassTwo (with main) in MyClass
package. When I run it in eclipse everything goes okay. When I create
jar and choose ClassTwo as Main everything goes okay.
But now I am interested in running it just from class files. What is a
correct syntax for such example?!?
I tried:
"java -classpath . ClassTwo" and similar but never run it getting all
the time: NoClassDefFoundError.

Regards, mark

Your class files need to live in directory structures that mimic the
package names, tokenised along dots, e.g. java.lang.String would be in
java/lang/String.class. Whichever directory has the java directory (in
the above example) as a child is the only one that needs to be in the
classpath to find that class.

In your example,

mkdir MyClass
mv ClassOne.class ClassTwo.class MyClass/
java -classpath . ClassTwo

should do the trick.

Matt
 
B

Babu Kalakrishnan

Knute said:
If your classes are in a package, then you must be in the directory
above the package to run from class files. So if you package is called
MyPackage, your class file is called MyClass.class and the MyPackage
directory is located in /xyz/abc then you must be in /xyz/abc. To
execute your program then you must type java MyPackage.MyClass.

Not 100% correct - though that is indeed the easiest way to do it. One
could actually be in any working directory as long as your commandline
while executing the "java" command also includes a -classpath argument
that points to the base of your package hierarchy.,

The commandline for the above example in that case would be :

java -classpath /xyz/abc MyPackage.MyClass


BK
 
M

Matt Rose

Matt said:
Your class files need to live in directory structures that mimic the
package names, tokenised along dots, e.g. java.lang.String would be in
java/lang/String.class. Whichever directory has the java directory (in
the above example) as a child is the only one that needs to be in the
classpath to find that class.

In your example,

mkdir MyClass
mv ClassOne.class ClassTwo.class MyClass/
java -classpath . ClassTwo

should do the trick.

Matt

Oops, you'll need to qualify the name of your class when you invoke it.
The last line should read:

java -classpath . MyClass.ClassTwo

Matt
 
K

Knute Johnson

Babu said:
Not 100% correct - though that is indeed the easiest way to do it. One
could actually be in any working directory as long as your commandline
while executing the "java" command also includes a -classpath argument
that points to the base of your package hierarchy.,

The commandline for the above example in that case would be :

java -classpath /xyz/abc MyPackage.MyClass


BK

That doesn't work for me although I have seen reference to it before
like that. Could it be that it doesn't work on Windows like that?
 
O

Oliver Wong

Knute Johnson said:
That doesn't work for me although I have seen reference to it before like
that. Could it be that it doesn't work on Windows like that?

It works for me on WinXP SP2:

java -cp "D:\Oliver's Documents\Workspace\Test\bin" D

to run a class called "D" with no package whose classfile is in
"D:\Oliver's Documents\Workspace\Test\bin"

- Oliver
 
K

Knute Johnson

Oliver said:
It works for me on WinXP SP2:

java -cp "D:\Oliver's Documents\Workspace\Test\bin" D

to run a class called "D" with no package whose classfile is in
"D:\Oliver's Documents\Workspace\Test\bin"

- Oliver

That does for me too. But put it in a package and it won't.
 
B

Babu Kalakrishnan

Knute said:
That does for me too. But put it in a package and it won't.

Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2

BK
 
K

Knute Johnson

Babu said:
Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2

BK

package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

C:\>java test.Test
It works!

C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\test>java -cp /test test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\test>java test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\test>java -cp "C:/test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\test>cd \

C:\>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\>java -cp /test test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\>java -cp test test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

C:\>

What am I doing wrong here?
 
A

Andrew Thompson

Knute said:
Babu said:
Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2
....
package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

C:\>java test.Test
It works!

C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Here you need to add the 'test' package to the classpath,
as opposed to ..anything it contains.

So on my system -

C:\test>java -cp .. test.Test
It works!

___

Note that in your original post, there was a *slight* wording
mistake (AFAIU). I did not point it out at the time, since I
felt the OP had enough to mull over, but since I've jumped
into this thread..

Initially you said that a test.Test dould be run from the
'parent directory'.. OK that *is* correct, but I feel it would
have been better to say that it could be run from the
'root of the package structure'.

In your example, of course, they *are* the same place.

BUT.. if you consider the class test.junit.Test,
the latter advice is correct, while the 'parent' directory
of the test.junit.Test class is also a package, rather
than the 'root' and will not work (in the same way).

Andrew T.
 
B

Babu Kalakrishnan

Knute said:
Babu said:
Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2

BK

package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

I'd assume that you now have Test.java and Test.class inside C:\test.
C:\>java test.Test
It works!

OK - here the default classpath assumed by the JVM is "." (which is
"C:\"), so it works
C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Your commandline here should be :

java -cp "C:\" test.Test

because the classpath is to be set to the root of the package hierarchy
- which is C:\ in your case.

With the commandline you used, the class file is expected to be
C:\test\test\Test.class


BK
 
K

Knute Johnson

Babu said:
Knute said:
Babu said:
Knute Johnson wrote:

Oliver Wong wrote:


Babu Kalakrishnan wrote:

The commandline for the above example in that case would be :

java -classpath /xyz/abc MyPackage.MyClass

That doesn't work for me although I have seen reference to it before
like that. Could it be that it doesn't work on Windows like that?

It works for me on WinXP SP2:

java -cp "D:\Oliver's Documents\Workspace\Test\bin" D

to run a class called "D" with no package whose classfile is in
"D:\Oliver's Documents\Workspace\Test\bin"

- Oliver

That does for me too. But put it in a package and it won't.


Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2

BK

package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

I'd assume that you now have Test.java and Test.class inside C:\test.
C:\>java test.Test
It works!

OK - here the default classpath assumed by the JVM is "." (which is
"C:\"), so it works
C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Your commandline here should be :

java -cp "C:\" test.Test

because the classpath is to be set to the root of the package hierarchy
- which is C:\ in your case.

With the commandline you used, the class file is expected to be
C:\test\test\Test.class


BK

Thank you so much guys, this has confused the s**t out of me for years.
I think the most confusing part is the root business.

So now that you solved that one, show me how to use a jar library on the
command line when I run a java program. I can make it compile but I
can't make it run. I can get it to work if I put the jar file in the
Class-Path: line in the manifest and put the jar file in the same
directory as the program jar file but not from the command line.

Test is my slightly modified class that calls a static method in
lib.Lib. The Lib class has been compiled and put into a jar file,
lib.jar in the /lib directory. I then compile Test.java from the /test
directory and run the .class file with no problems. You will see that
the lib.Lib class can't be found once I jar it.

package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
lib.Lib.lib();
}
}

package lib;

public class Lib {
public static void lib() {
System.out.println("lib");
}
}

C:\lib>dir
Volume in drive C has no label.
Volume Serial Number is 7C27-9663

Directory of C:\lib

08/30/2006 12:15 PM <DIR> .
08/30/2006 12:15 PM <DIR> ..
08/30/2006 11:06 AM 728 Lib.jar
08/30/2006 10:46 AM 116 Lib.java
2 File(s) 844 bytes
2 Dir(s) 62,081,531,904 bytes free

C:\lib>

C:\test>dir
Volume in drive C has no label.
Volume Serial Number is 7C27-9663

Directory of C:\test

08/30/2006 12:12 PM <DIR> .
08/30/2006 12:12 PM <DIR> ..
08/30/2006 11:51 AM 162 Test.java
1 File(s) 162 bytes
2 Dir(s) 62,081,544,192 bytes free

C:\test>javac -cp /lib/Lib.jar Test.java

C:\test>java -cp /lib/Lib.jar;/ test.Test
It works!
lib

C:\test>cd \

C:\>jar cvfe test/Test.jar test.Test test/*.class
added manifest
adding: test/Test.class(in = 452) (out= 310)(deflated 31%)

C:\>java -cp /lib/Lib.jar -jar test/Test.jar
It works!
Exception in thread "main" java.lang.NoClassDefFoundError: lib/Lib
at test.Test.main(Test.java:6)

C:\>
 
K

Knute Johnson

Andrew said:
Knute said:
Babu said:
Knute Johnson wrote:
Oliver Wong wrote:
Babu Kalakrishnan wrote:
The commandline for the above example in that case would be :

java -classpath /xyz/abc MyPackage.MyClass

That doesn't work for me although I have seen reference to it before
like that. Could it be that it doesn't work on Windows like that?
It works for me on WinXP SP2:

java -cp "D:\Oliver's Documents\Workspace\Test\bin" D

to run a class called "D" with no package whose classfile is in
"D:\Oliver's Documents\Workspace\Test\bin"

- Oliver
That does for me too. But put it in a package and it won't.

Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2
...
package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

C:\>java test.Test
It works!

C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Here you need to add the 'test' package to the classpath,
as opposed to ..anything it contains.

So on my system -

C:\test>java -cp .. test.Test
It works!

___

Note that in your original post, there was a *slight* wording
mistake (AFAIU). I did not point it out at the time, since I
felt the OP had enough to mull over, but since I've jumped
into this thread..

Initially you said that a test.Test dould be run from the
'parent directory'.. OK that *is* correct, but I feel it would
have been better to say that it could be run from the
'root of the package structure'.

In your example, of course, they *are* the same place.

BUT.. if you consider the class test.junit.Test,
the latter advice is correct, while the 'parent' directory
of the test.junit.Test class is also a package, rather
than the 'root' and will not work (in the same way).

Andrew T.

Andrew:

Thanks very much. Please see my response to Babu (and you).
 
A

Andrew Thompson

Knute Johnson wrote:
....
So now that you solved that one, show me how to use a jar library on the
command line when I run a java program.

I'll have a closer look at the rest if needed, but for starters,
could you give us the output of ..
jar -tf Test.jar
?

I suspect it will reveal the problem.

Andrew T.
 
K

Knute Johnson

Andrew said:
Knute Johnson wrote:
...

I'll have a closer look at the rest if needed, but for starters,
could you give us the output of ..
jar -tf Test.jar
?

I suspect it will reveal the problem.

Andrew T.

C:\test>jar tf Test.jar
META-INF/
META-INF/MANIFEST.MF
test/Test.class



I know what you are looking for and it's not here!

When I get this all figured out, I'm going to write a paper on how to do
these things because I know that I won't remember and that there must be
more idiots out there than just me :).
 
A

Andrew Thompson

Knute said:
.....
C:\test>jar tf Test.jar
META-INF/
META-INF/MANIFEST.MF
test/Test.class



I know what you are looking for

Yep. Just wanted to check the internal structure,
specifically the directory sstructure.
....and it's not here!

OK.. I was wrong! I'll look more closely into the
details you posted.

Andrew T.
 
A

Andrew Thompson

Knute Johnson wrote:
....
C:\test>cd \

C:\>jar cvfe test/Test.jar test.Test test/*.class

Aha! I did miss thid command that makes the Jar when I
first read (OK.. skimmed) this, but...

'e'? 'cvfe' as the options, what is 'e'?

I don't see it in the options for either the Win or *nix
version of the jar command.

And, while I'm here, I understand the meaning of 'test/Test.jar'
as the output file, and 'test/*.class' as the input file(s), but what
is 'test.Test' doing in there?

Andrew T.
 
B

Babu Kalakrishnan

Knute said:
So now that you solved that one, show me how to use a jar library on the
command line when I run a java program. I can make it compile but I
can't make it run. I can get it to work if I put the jar file in the
Class-Path: line in the manifest and put the jar file in the same
directory as the program jar file but not from the command line.

Test is my slightly modified class that calls a static method in
lib.Lib. The Lib class has been compiled and put into a jar file,
lib.jar in the /lib directory. I then compile Test.java from the /test
directory and run the .class file with no problems. You will see that
the lib.Lib class can't be found once I jar it.

I don't think it is possible to achieve that if you're using -jar option
of java. Once the -jar option is specified, whatever you specify as a
-classpath or -cp option is essentially ignored, and the effective user
classpath of the JVM becomes the specified jar file and the jars
specified in that jar's manifest.

An alternative would be to not use the -jar option, but to run it as :

java -cp /path_to_lib_jar/lib.jar:/path_to_test_jar/test.jar test.Test

(i.e by explicitly specifying the main class to invoke, and specifying
all the jar files in the classpath option)

BK
 
N

Nigel Wade

Knute said:
Babu said:
Knute said:
Babu Kalakrishnan wrote:

Knute Johnson wrote:

Oliver Wong wrote:


Babu Kalakrishnan wrote:

The commandline for the above example in that case would be :

java -classpath /xyz/abc MyPackage.MyClass

That doesn't work for me although I have seen reference to it before
like that. Could it be that it doesn't work on Windows like that?

It works for me on WinXP SP2:

java -cp "D:\Oliver's Documents\Workspace\Test\bin" D

to run a class called "D" with no package whose classfile is in
"D:\Oliver's Documents\Workspace\Test\bin"

- Oliver

That does for me too. But put it in a package and it won't.


Interesting - Seems to work for me even with classes within a package -

Running TCPServer.class in package test :

java -classpath "C;\Documents and
Settings\Babu\workspace\TestServer\classes" test.TCPServer
Main: Listening for connections on port 2345

Testing on XP Home SP2

BK


package test;

public class Test {
public static void main(String[] args) {
System.out.println("It works!");
}
}

C:\>javac test/Test.java

I'd assume that you now have Test.java and Test.class inside C:\test.
C:\>java test.Test
It works!

OK - here the default classpath assumed by the JVM is "." (which is
"C:\"), so it works
C:\>cd test

C:\test>java -cp "C:\test" test.Test
Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Your commandline here should be :

java -cp "C:\" test.Test

because the classpath is to be set to the root of the package hierarchy
- which is C:\ in your case.

With the commandline you used, the class file is expected to be
C:\test\test\Test.class


BK

Thank you so much guys, this has confused the s**t out of me for years.
I think the most confusing part is the root business.

So now that you solved that one, show me how to use a jar library on the
command line when I run a java program. I can make it compile but I
can't make it run. I can get it to work if I put the jar file in the
Class-Path: line in the manifest and put the jar file in the same
directory as the program jar file but not from the command line.

You can't. It is specifically mentioned in the java man page. When running a jar
with the java -jar command syntax, the -cp flag is ignored. The jar file is the
sole definition of the classpath.

If your executable jar requires classes from other jars, those jars must be
added to the Class-Path: section of the executable jar's manifest. To further
annoy you the paths in Class-Path: should be relative paths (although absolute
paths do work, at least on Linux). I'm not surprised you're confused, you're
not the only one. I suppose it does offer some measure of security in that a
user of your application can't change the classpath to inject their own jar's
to intercept private information from within the application. Although there's
nothing to stop them unpacking the jar, and re-packaging it with a different
manifest. So what the purpose really is, other than to annoy and confuse,
escapes me.
 

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,774
Messages
2,569,596
Members
45,140
Latest member
SweetcalmCBDreview
Top