aspose file tools*
The moose likes Beginning Java and the fly likes Oh classpath, why do you hate me? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Oh classpath, why do you hate me?" Watch "Oh classpath, why do you hate me?" New topic
Author

Oh classpath, why do you hate me?

David Duran
Ranch Hand

Joined: Feb 11, 2002
Posts: 122
The infamous classpath problem is haunting me. Let me describe the situation:
I have Java SOURCE files (package: Services.Impl) in this directory: c:\Server\Services\Impl
I have a single batch file in c:\Server that compiles the files into c:\ROOT\Services\Impl with this line:
javac -d ..\ROOT\Download\ .\Services\Impl\*.java
That same batch file then executes the program using this line:
java -cp ..\ROOT\Download\ Services.Impl.RunServer
In the main() of RunServer I reference a couple of classes located in a jar file that is specified in the classpath in Environment Variables|System Variables:
Variable: CLASSPATH
Value: C:\jdk1.3.1_01\lib\log4j.jar;
But when I try to run the program I get this error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/PropertyConfigurator
at Services.Impl.RunServer.main(RunServer.java:43)

Here's the kicker:
1) I've got import org.apache.log4j.PropertyConfigurator; and I get NO compile errors telling me that class can't be found or can't resolve symbol. Everything compiles correctly
2) I can get rid of that error if I add the path and filename to the -cp option when I run the program. So the working command looks like this:
java -cp ..\ROOT\Download\;c:\jdk1.3.1_01\lib\log4j.jar; Services.Impl.RunServer
Does anyone have a clue as to why I have to do that? Like I said, I specify that exact same path and filename in my Win2k Environment Variables. This is perplexing...
[ March 06, 2002: Message edited by: David Duran ]
Manfred Leonhardt
Ranch Hand

Joined: Jan 09, 2001
Posts: 1492
Hi David,
My guess would be that supplying the -cp argument to the java command just uses what you specify. Instead of what you think: using environment classpath and adding what you specify.
I think this is the way most Unix commands work ...
To test the theory you should place both the Download and jar paths into your environment variable. If that works, then you have your answer as I stated above.
Regards,
Manfred.
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
On windows, if you want to append to the current CLASSPATH variable, add %CLASSPATH% as one of your path elements.
But I firmly believe no one should be setting a global environment variable. It's much safer and clearer to set the classpath for the particular tool you are using. You can even just create a batch file that sets the classpath, and reference that from your script that compiles and launches. This way, you have a lot more control over your classpath settings, and you don't have to worry about whether you need to update your classpath variable for a new tool.
just say NO to CLASSPATH!


Rob
SCJP 1.4
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
... or put it on extension path. Then you can forget about classpath. This operation, however, makes sense if your jar will be used by several applications, which seems true for log4j. By exploiting extension path I recently get rid of numerous mail.jars that come with every new download
just say NO to CLASSPATH!
--------------------
Map
[ March 06, 2002: Message edited by: Mapraputa Is ]

Uncontrolled vocabularies
"I try my best to make *all* my posts nice, even when I feel upset" -- Philippe Maquet
David Duran
Ranch Hand

Joined: Feb 11, 2002
Posts: 122
Thanks for the responses ranchers. I removed my classpath variable from environment variables and specified the classpath in my .bat files and it works like a charm now. Thank you thank you!
set CLASSPATH=%CLASSPATH%;..\ROOT\Download\
set CLASSPATH=%CLASSPATH%;c:\jdk1.3.1_01\lib\log4j.jar
btw, say NO to classpath!
Carl Trusiak
Sheriff

Joined: Jun 13, 2000
Posts: 3340
What happened is this. When you specified -cp, you set the class path to that. You did NOT add to the classpath. If you had stated
java -cp ..\ROOT\Download\;%classpath% Services.Impl.RunServer
It would have worked.


I Hope This Helps
Carl Trusiak, SCJP2, SCWCD
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
Still, just say NO to CLASSPATH.
I think this should be a new slogan.
Also I would like to nominate this thread for the funniest title of the month!
sarah Marsh
Ranch Hand

Joined: Mar 06, 2001
Posts: 282
Hello,
I got the Exception in thread "main" java.lang.NoClassDefFoundError even I
use:
java -cp ..\ROOT\Download\;c:\jdk1.3.1_01\lib\log4j.jar; Services.Impl.RunServer
on UNIX.
Any suggestion?
Thanks a lot,
Sarah
David Duran
Ranch Hand

Joined: Feb 11, 2002
Posts: 122
On Unix the slashes go the other way and if I'm not mistaken you separate the directories/jars with a colon ":", not semi-colon. To my knowledge the c:\ drive isn't usually mapped on your Unix machine (Unix gurus, correct me if I'm wrong) so refer to the jdk directory using $JAVA_HOME. Try:
java -cp ../ROOT/Download/:$JAVA_HOME/lib/log4j.jar Services.Impl.RunServer
[ March 26, 2002: Message edited by: David Duran ]
Chris-Huisman
Greenhorn

Joined: Jan 25, 2002
Posts: 23
I am having similar problems with a class I am trying to run. I am using Redhat 7.2, and my class is located in $HOME/work/application/classes/com/applicationName/connection/
I have $HOME/work/application/classes in my $CLASSPATH. When I call the program with:
java SchedulePool.
The output is:
Exception in thread "main" java.lang.NoClassDefFoundError: SchedulePool
When I call it with:
java -cp $HOME/work/application/classes/com/application/connectionPool/
The output is:
Exception in thread "main" java.lang.NoClassDefFoundError: SchedulePool (wrong name: com/therezworks/connectionPool/SchedulePool)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:509)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:246)
at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
at java.lang.ClassLoader.loadClass(ClassLoader.java:262)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322)
What am I missing???
Thanks,
Chris.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61662
    
  67

Have you tried specifying the fully qualified class name on the java command?
bear


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Reuben Cleetus
Ranch Hand

Joined: Jul 13, 2001
Posts: 50
Friends don't let friends use Classpaths!
Chris-Huisman
Greenhorn

Joined: Jan 25, 2002
Posts: 23
Yes, I have tried to type out the fully qualified pathname to the class file. It still did not work.
Chris.
David Duran
Ranch Hand

Joined: Feb 11, 2002
Posts: 122
Chris: What package is SchedulePool in?
Chris-Huisman
Greenhorn

Joined: Jan 25, 2002
Posts: 23
SchedulePool is in package com.therezworks.connectionPool.
chris.
Chris-Huisman
Greenhorn

Joined: Jan 25, 2002
Posts: 23
Everything is now fixed. Thanks for the help.
c.
Benjamin Yee
Greenhorn

Joined: Mar 27, 2002
Posts: 2
try including a "." in your classpath variable to denote inclusive of the current directory where your application is running from.
Selvan tiru
Greenhorn

Joined: Jul 12, 2001
Posts: 18
Try expanding the $HOME
Carol Murphy
village idiot
Bartender

Joined: Mar 15, 2001
Posts: 1197
I think I'm going to cry.............
I just don't get this whole Classpath thing at all!
Tito Ortiz
Greenhorn

Joined: Feb 21, 2002
Posts: 12
How would you go about not using classpath on the unix platform? i understand bat files on windows (i think) but how do you do the equivalent on unix?
I've got most of my linux class path defined in .bash_profile and have orion up and running most days everything is cool but lately I've been trying to access classes in xerces and although DOM tree classes are accessible for one reason or other the basic validation piece of the parser;
java sax.SAXCount -v foo.xml
kicks back the infamous no class found error.
Please help me to stop using the classpath!
Thanks
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
Use batch files/shell scripts to invoke any java tools like javac or java.exe that need a classpath. That way, you can supply the needed classpath, but customize it for each application. You could also reference a batch file/shell script that merely creates and initializes a CLASSPATH environment variable. The point is that this variable would be local to one invocation of your command window/shell, and wouldn't have to be global for your entire environment. This gives you much better control over what goes into your classpath for each project you have.
Tito Ortiz
Greenhorn

Joined: Feb 21, 2002
Posts: 12
Rob:
Thanks for the explanation, although I should say I already understand the concepts, really my biggest problem is that I don't know the implementation still being new to linux. Anyone know of a link showing a step by step example of achieving a classpath-less approach to application development in a unix environment?
::thinks to himself "why don't they cover this critical issue in books published about java considering the breadth of ppl running into similar classpath issues"::
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
It's really quite simple. CLASSPATH is to .class files as PATH is to .exe files.
If you want to run a .exe file from your command line, but you haven't added that file to your PATH variable, what happens when you type in the command? You get an error saying that the name is not recognized as a valid command.
It's the same with class files. The java tool you are invoking needs to be told where to search to find the classes it needs; this includes all the classes that your application uses. If you don't tell java where to find a class file by including it in the classpath, then it won't find it and you'll get an error.
What more is confusing you?
David Duran
Ranch Hand

Joined: Feb 11, 2002
Posts: 122
Here's an example of a dos batch script and the corresponding unix/linus shell script:
DOS:

Unix:

Note the differences in the semi-colon separating jars/dirs in DOS with the colon in Unix as well as the direction of the slashes.
I'm using %CLASSPATH%/$CLASSPATH to append the existing classpath set in an environment variable or in the bashrc file. AFAIK, the scripts set the classpath only for the application, once it terminates the classpath remaines unchanged (correct me if I'm wrong).
[ April 01, 2002: Message edited by: David Duran ]
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Oh classpath, why do you hate me?