NoClassDefFoundError and jars, classpath, and ant newbie question

B

bill turner

I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

src - my source files
class - my class files
lib - external jars, zips to be used by this project (currently my jar
from the other project - util)
jar - my generated jar file
make - build.xml and manifest file

i have tried running both via cygwin bash and dos. The results below
are from the cygwin bash execution (the dos results are identical). The
java.lang.NoClassDefFoundError exception is for a class within the
util.jar, the included jar, not jequire.jar, my current project.

/home/Wizard/bin>sh jequire.sh
Exception in thread "main" java.lang.NoClassDefFoundError:
com/changent/util/ui/ButtonPanel
at
com.changent.jequire.JequireTabs.makeTypeTabs(JequireTabs.java:33)
at com.changent.jequire.JequireTabs.<init>(JequireTabs.java:25)
at com.changent.jequire.Jequire.<init>(Jequire.java:48)
at com.changent.jequire.Jequire.main(Jequire.java:115)

The bash script for executing this is:
#!/usr/bin/bash

cd ${HOME}/jequire

export CLASSPATH=

$JAVA_HOME/bin/java -jar jar/jequire.jar

I realize the classpath should be taken from the manifest. The manifest
from jequire.jar looks like:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
Built-By: Wizard
Main-Class: com/changent/jequire/Jequire
Class-Path: util.jar

My ant script (I am not strong with ant, either), looks like:
<target name="jar_java" depends="compile_java" description="Create
${ant.project.name}.jar java file" >
<manifest file="MANIFEST.MF">
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class"
value="com/changent/jequire/Jequire"/>
<attribute name="Class-Path" value="util.jar" />
</manifest>
<jar destfile = "${jar}/${ant.project.name}.jar"
manifest="MANIFEST.MF">
<fileset dir="${class}"
excludes="**/*.tws"
/>
<fileset dir="${lib}" />
</jar>
</target>

The resultant jar has all the jequire classes, as would be expected,
the manifest, and the util.jar with no path info. I do not know what I
am doing wrong. Should I change the ant script somehow? The way the jar
is executed? Or something else?

Your help is greatly appreciated!
 
M

Mark Space

bill said:
I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

I'm having a similar problem right now with both NetBeans and on the
command line. If I find something I'll let you know, otherwise I may be
posting my own version soon.
 
B

bill turner

Mark said:
I'm having a similar problem right now with both NetBeans and on the
command line. If I find something I'll let you know, otherwise I may be
posting my own version soon.

Okay, I appreciate it. Funny thing is, I have no problems returning to
the code, just getting it to run. :-(
 
L

lordy

I realize the classpath should be taken from the manifest. The manifest
from jequire.jar looks like:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
Built-By: Wizard
Main-Class: com/changent/jequire/Jequire
Class-Path: util.jar
Does it have a blank line at the end?

Lordy
 
L

lordy

To what does it refer?
"It" refers to subject of the quoted paragraph - "the manifest".
Or more correctly - every "section" or group of Name-Value pairs...

http://www.iona.com/support/docs/e2a/asp/5.1/j2ee/petstore/tutorial4.html

From http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html Name-Value
pairs and sections:

section: *header +newline <-[Every section must be followed by a blank line]
nonempty-section: +header +newline
newline: CR LF | LF | CR (not followed by LF)
header: name : value
name: alphanum *headerchar
value: SPACE *otherchar newline *continuation
continuation: SPACE *otherchar newline
alphanum: {A-Z} | {a-z} | {0-9}
headerchar: alphanum | - | _
otherchar: any UTF-8 character except NUL, CR and LF

Lordy
 
B

bill turner

lordy said:
To what does it refer?
"It" refers to subject of the quoted paragraph - "the manifest".
Or more correctly - every "section" or group of Name-Value pairs...

http://www.iona.com/support/docs/e2a/asp/5.1/j2ee/petstore/tutorial4.html

From http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html Name-Value
pairs and sections:

section: *header +newline <-[Every section must be followed by a blank line]
nonempty-section: +header +newline
newline: CR LF | LF | CR (not followed by LF)
header: name : value
name: alphanum *headerchar
value: SPACE *otherchar newline *continuation
continuation: SPACE *otherchar newline
alphanum: {A-Z} | {a-z} | {0-9}
headerchar: alphanum | - | _
otherchar: any UTF-8 character except NUL, CR and LF

Lordy

Okay. Well, I don't know how it would have one. Nor does it seem to
have one. Each line is terminated with CRLF (it is Windows, after all).
My manifest looks exactly as above. So, it seems it conforms to spec.
Hmmmm...
 
C

Chris Uppal

bill said:
Okay. Well, I don't know how it would have one. Nor does it seem to
have one. Each line is terminated with CRLF (it is Windows, after all).
My manifest looks exactly as above. So, it seems it conforms to spec.
Hmmmm...

Just to be sure: is the /last/ line terminated by a CRLF ? Many Windows
editors (correctly for that platform) treat CRLF as a line /separator/ and
don't put one at the end of the last line unless you explicitly type <return>.
The manifest file parser (brokenly. IMO) cannot cope with that, but does not
issue any kind of error message either.

As far as I can see, that problem still remains in 1.5. If the manifest file
(the actual one in the archive) lacks a terminating CRLF (or some variant) then
the launcher's parser will ignore that line silently. The jar creation tool
seems to have a similar problem and doesn't actually copy the last line of the
supplied manifest into the jar-ed manifest unless it is terminated (and again
doesn't report any error). I don't know whether either of those problem could
be affecting you, but it's worth checking a second time.

-- chris
 
L

lordy

lordy said:
lordy wrote:

I realize the classpath should be taken from the manifest. The manifest
from jequire.jar looks like:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
Built-By: Wizard
Main-Class: com/changent/jequire/Jequire
Class-Path: util.jar

Does it have a blank line at the end?
Or more correctly - every "section" or group of Name-Value pairs...

http://www.iona.com/support/docs/e2a/asp/5.1/j2ee/petstore/tutorial4.html

From http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html Name-Value
pairs and sections:

section: *header +newline <-[Every section must be followed by a blank line]
[SNIP]

Okay. Well, I don't know how it would have one. Nor does it seem to
have one. Each line is terminated with CRLF (it is Windows, after all).
My manifest looks exactly as above. So, it seems it conforms to spec.
Hmmmm...
Yes each line should be terminated by a new line but there should be an
*extra* new line at the end - ie a completely empty blank line with nothing
on it. No spaces, no letter, nothing. Does it have this?

Failing that try swapping your 'Built-By' and 'Class-Path' perhaps?

Lordy
 
B

bill turner

lordy said:
lordy said:
lordy wrote:

I realize the classpath should be taken from the manifest. The manifest
from jequire.jar looks like:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
Built-By: Wizard
Main-Class: com/changent/jequire/Jequire
Class-Path: util.jar

Does it have a blank line at the end?

Or more correctly - every "section" or group of Name-Value pairs...

http://www.iona.com/support/docs/e2a/asp/5.1/j2ee/petstore/tutorial4.html

From http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html Name-Value
pairs and sections:

section: *header +newline <-[Every section must be followed by a blank line]
[SNIP]

Okay. Well, I don't know how it would have one. Nor does it seem to
have one. Each line is terminated with CRLF (it is Windows, after all).
My manifest looks exactly as above. So, it seems it conforms to spec.
Hmmmm...
Yes each line should be terminated by a new line but there should be an
*extra* new line at the end - ie a completely empty blank line with nothing
on it. No spaces, no letter, nothing. Does it have this?

Failing that try swapping your 'Built-By' and 'Class-Path' perhaps?

Lordy

Following the word util.jar, viewing a hex editor, are the characters
0D 0A 0D 0A, in other words CRLF, CRLF. This seems to comply with what
you are suggesting. I changed my ant script to look like the following:

<target name="jar_java" depends="compile_java" description="Create
${ant.project.name}.jar java file" >
<manifest file="MANIFEST.MF">
<attribute name="Main-Class" value="com/changent/jequire/Jequire" />
<attribute name="Class-Path" value="util.jar" />
<attribute name="Built-By" value="${user.name}" />
</manifest>
<jar destfile = "${jar}/${ant.project.name}.jar"
manifest="MANIFEST.MF">
<fileset dir="${class}"
excludes="**/*.tws"
/>
<fileset dir="${lib}"
excludes="**/junit.jar"
/>
</jar>
</target>

You'll notice that I have moved "Built-By" to the end of the manifest.
However, this does not create the manifest as expected. Instead,
Built-By still comes before Class-Path. See below. It is still followed
with the requisite CRLF CRLF at the end.

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-b03 (Sun Microsystems Inc.)
Main-Class: com/changent/jequire/Jequire
Built-By: Wizard
Class-Path: util.jar

This still does not work, of course, and still fails with the same
error. I'll try to manually change this, but have to try that later
today. In the meantime, if you have any other thoughts, I sure would
appreciate them.

Bill
 
B

bill turner

Chris said:
Just to be sure: is the /last/ line terminated by a CRLF ? Many Windows
editors (correctly for that platform) treat CRLF as a line /separator/ and
don't put one at the end of the last line unless you explicitly type <return>.
The manifest file parser (brokenly. IMO) cannot cope with that, but does not
issue any kind of error message either.

As far as I can see, that problem still remains in 1.5. If the manifest file
(the actual one in the archive) lacks a terminating CRLF (or some variant) then
the launcher's parser will ignore that line silently. The jar creation tool
seems to have a similar problem and doesn't actually copy the last line of the
supplied manifest into the jar-ed manifest unless it is terminated (and again
doesn't report any error). I don't know whether either of those problem could
be affecting you, but it's worth checking a second time.

-- chris

Yes, it does. See my reply to lordy. I appreciate your jumping in!
 
L

lordy

I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

src - my source files
class - my class files
lib - external jars, zips to be used by this project (currently my jar
from the other project - util)
jar - my generated jar file
make - build.xml and manifest file
[SNIP]

$JAVA_HOME/bin/java -jar jar/jequire.jar

Another attack vector :). Try

EITHER

putting util.jar in the same directory as your application jar file.

OR

ensuring that your Manifest Class-Path has the correct relative path
from your application jar to util.jar

E.g.
Class-Path: lib/util.jar (if lib directory is inside 'jar' directory)
or
Class-Path: ../lib/util.jar (if lib directory is in same directory as
your 'jar' directory)

If thats the fix - sorry about the wild goose chase :(

Lordy
 
B

bill turner

lordy said:
I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

src - my source files
class - my class files
lib - external jars, zips to be used by this project (currently my jar
from the other project - util)
jar - my generated jar file
make - build.xml and manifest file
[SNIP]

$JAVA_HOME/bin/java -jar jar/jequire.jar

Another attack vector :). Try

EITHER

putting util.jar in the same directory as your application jar file.

OR

ensuring that your Manifest Class-Path has the correct relative path
from your application jar to util.jar

E.g.
Class-Path: lib/util.jar (if lib directory is inside 'jar' directory)
or
Class-Path: ../lib/util.jar (if lib directory is in same directory as
your 'jar' directory)

If thats the fix - sorry about the wild goose chase :(

Lordy

Option one does not make sense to me. I do not want to mix my
executable (application) jar with jars imported into the project.

Option two is what I think I already have. The application (executable)
jar contains the util jar. The class path lists util jar without path
information. The application jar has the util jar without class info.
An abbreviated look at the application jar (jequire.jar) looks as
follows when viewed in winzip:

Jequire.class com\changent\jequire
JequireTabs.class com\changent\jequire
Manifest.mf meta-inf\
util.jar

Since the manifest does not specify path info and jequire.jar contains
no path info for util.jar, I do not see why I should change it to do
so. I have no idea to what it should be changed. Can you explain
further?
 
B

bill turner

bill said:
lordy said:
I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

src - my source files
class - my class files
lib - external jars, zips to be used by this project (currently my jar
from the other project - util)
jar - my generated jar file
make - build.xml and manifest file
[SNIP]

$JAVA_HOME/bin/java -jar jar/jequire.jar

Another attack vector :). Try

EITHER

putting util.jar in the same directory as your application jar file.

OR

ensuring that your Manifest Class-Path has the correct relative path
from your application jar to util.jar

E.g.
Class-Path: lib/util.jar (if lib directory is inside 'jar' directory)
or
Class-Path: ../lib/util.jar (if lib directory is in same directory as
your 'jar' directory)

If thats the fix - sorry about the wild goose chase :(

Lordy

Option one does not make sense to me. I do not want to mix my
executable (application) jar with jars imported into the project.

Option two is what I think I already have. The application (executable)
jar contains the util jar. The class path lists util jar without path
information. The application jar has the util jar without class info.
An abbreviated look at the application jar (jequire.jar) looks as
follows when viewed in winzip:

Jequire.class com\changent\jequire
JequireTabs.class com\changent\jequire
Manifest.mf meta-inf\
util.jar

Since the manifest does not specify path info and jequire.jar contains
no path info for util.jar, I do not see why I should change it to do
so. I have no idea to what it should be changed. Can you explain
further?

I have continued to play. I threw in a display of system properties.
The classpath property id below:
java.class.path=Jequire.jar

Since I state in the manifest that util.jar is in the classpath, and it
is at the top level of Jequire.jar, I am wondering if I am
misunderstanding altogether. Does the Class-Path property define the
run time classpath? If so, why isn't that reflected in the System
java.class.path property? FWIW, I've tried specifying -classpath on the
command line and the system classpath property still comes up as above.
Isn't it possible, when executing a jar, to provide further classpath
info? If not, and the manifest Class-Path property doesn't specify the
run time path, how is it determined when executing a jar and how can
one change it?
 
B

bill turner

lordy said:
I have been away from java for awhile and never spent much time with
it. I am having what is a very basic problem that I have not been able
to resolve. I am trying to include a jar from one project into the
classpath of another project. My directory structure is as follows:

src - my source files
class - my class files
lib - external jars, zips to be used by this project (currently my jar
from the other project - util)
jar - my generated jar file
make - build.xml and manifest file
[SNIP]

$JAVA_HOME/bin/java -jar jar/jequire.jar

Another attack vector :). Try

EITHER

putting util.jar in the same directory as your application jar file.

OR

ensuring that your Manifest Class-Path has the correct relative path
from your application jar to util.jar

E.g.
Class-Path: lib/util.jar (if lib directory is inside 'jar' directory)
or
Class-Path: ../lib/util.jar (if lib directory is in same directory as
your 'jar' directory)

If thats the fix - sorry about the wild goose chase :(

Lordy

Okay! I got it! Whew! It was as you suggested, i needed to specify the
class path attribute in ant as follows:

<attribute name="Class-Path" value="../lib/util.jar" />

I also made some changes to the shell script, but the above was the
real kicker. I didn't realize that the classpath was for items
*outside* the application jar, that to load classes from a jar packaged
within a jar needed to be done programmatically. I finally came upon
the explanation at
http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html
which states:

"Note: The Class-Path header points to classes or JAR files on the
local file system, not JAR files within the JAR file or classes on the
network. To load classes in JAR files within a JAR file into the class
path, you must write custom code to load those classes. For example, if
MyJar.jar contains another JAR file called MyUtils.jar, you cannot use
the Class-Path header in MyJar.jar's manifest to load classes in
MyUtils.jar into the class path."

You had put me on to the correct solution, I just didn't have enough
knowledge to properly understand your solution.

Thanks again for your help!
 
L

lordy

lordy said:
[SNIP]
$JAVA_HOME/bin/java -jar jar/jequire.jar

Another attack vector :). Try

EITHER

putting util.jar in the same directory as your application jar file.

OR

ensuring that your Manifest Class-Path has the correct relative path
from your application jar to util.jar

E.g.
Class-Path: lib/util.jar (if lib directory is inside 'jar' directory)
or
Class-Path: ../lib/util.jar (if lib directory is in same directory as
your 'jar' directory)

If thats the fix - sorry about the wild goose chase :(

Lordy

Option one does not make sense to me. I do not want to mix my
executable (application) jar with jars imported into the project.

Option two is what I think I already have. The application (executable)
jar contains the util jar.


AFAIK you should not have your utils jar inside your main jar. That
sounds more like mixing imported jars than simply having them side by
side in the same directory.

Either have

the files <path>/app.jar <path>/util.jar in you distribution out on the
file system And have "Class-Path: util.jar" in your manifest..

OR (but I havent tried it)

have the files <path>/app.jar and <path>/lib/utils.jar
And have Class-Path: lib/util.jar in your manifest..

But dont embed utils.jar in your main .jar. If you want to put the
util.jar inside you main jar then I think this is worse than having the
two jars in the same directory personally, but I'm not sure if Java can
load your util classes directly. You'd have to read up on it. it makes
it awkward if you want to upgrade your 'utils.jar' at a later point.
Most apps (ant etc) have util jars sitting out on the file system
somewhere, not embedded in their own jar.

When you install your application you should simply have ...

<install-path>/your-app.jar
<install-path>/lib/util.jar
As two separate files.

The Manifest of your main app should then contain Class-Path:lib/util.jar

I suspect.

Lordy
 

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

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top