Building .jar distributions

T

Tim

I was trying to learn a bit about JUnit and got it working in a very
basic way through JDeveloper.
So I decided to build a distribution through ant and then try to run the
test I was doing through the DOS prompt.
I kept getting .class not found for various classes in the JUnit jar
file. Of course when I added all of the files from that jar file to the
distribution file, it worked.
What is the best way to determine what classes have to be included in
the distribution or do you just load all of them and save the time of
figuring it out?
 
J

Jose Rubio

Not sure of all the details of what you're doing, but this is what I get
from what you said.

You have a project with a number of Java classes.
You created some test cases to test those Java classes.
You made a jar file that included the real code and the testing code. (Did
you make 1 or did you do a code.jar and a testcases.jar)

IF you want to run the junit test cases from the command line, you will need
to include the code.jar, the testcases.jar (assuming you made two, or just
one distribution.jar), and the junit.jar in the classpath.

How you create your jars for distribution/release should be based on the
architecture of the project. But 3rd party libraries like Junit shouldn't be
included inside a jar you created. They should be kept in a separate jar
like it came in when you downloaded it and just released in your code if
there is any need for it.

BTW. You can use the same ant script to run the test cases. Check the ant
documentation and read on the junit task.

Hope it helps.

Jose
 
C

Chris Smith

Tim said:
I was trying to learn a bit about JUnit and got it working in a very
basic way through JDeveloper.
So I decided to build a distribution through ant and then try to run the
test I was doing through the DOS prompt.
I kept getting .class not found for various classes in the JUnit jar
file. Of course when I added all of the files from that jar file to the
distribution file, it worked.
What is the best way to determine what classes have to be included in
the distribution or do you just load all of them and save the time of
figuring it out?

If you need a third-party library to run your application, it's typical
to distribute the JAR file from the third-party library separately from
your own code. You almost certainly don't want to pick and choose
pieces of it, as this would break most licensing agreements. So I
definitely wouldn't take bits and pieces of someone else's JAR file and
add them to your own.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

Thanks for your reply. I've been doing some development work and have,
for the most part, been doing it inside JDeveloper and Homesite (JSP). I
would then move the beans to the correct Tomcat folder and see if it
would work.
Recently, for my own understanding of things, I've decided to try to
create jar files, use ant and use JUnit although they may not be
appropriate for what I was doing before.
So, I'm just trying to tie some of these things together and compile a
simple program and it's JUnit test program, package them in a jar file
and run it from the command line, out of a jar file.
I was also thinking of sending the file to a friend so he could run it
and see what the output of a JUnit test program was because he has been
hearing that people in his company are using it in other groups and I
thought it may be interesting for him to see it in action, albeit in a
simplified example. Of course, if he had to do too much setting up, he
may not be interested.
Anyway, thanks again.
 
T

Tim

Jose said:
Not sure of all the details of what you're doing, but this is what I get
from what you said.

You have a project with a number of Java classes.
You created some test cases to test those Java classes.
You made a jar file that included the real code and the testing code. (Did
you make 1 or did you do a code.jar and a testcases.jar)

IF you want to run the junit test cases from the command line, you will need
to include the code.jar, the testcases.jar (assuming you made two, or just
one distribution.jar), and the junit.jar in the classpath.
I just tried that and get the NoClassDefFoundError. Do I put the path to
the jar file or include the jar file itself in the classpath?
(ie. C:\JDeveloper\junit or C:\JDeveloper\junit\junit.jar)
 
C

Chris Smith

Tim said:
I just tried that and get the NoClassDefFoundError. Do I put the path to
the jar file or include the jar file itself in the classpath?
(ie. C:\JDeveloper\junit or C:\JDeveloper\junit\junit.jar)

The latter.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

OK, I'm still having some problems so maybe I can give some info and you
can see where I'm screwing up. I'm sure it's some relative path problem.

The class that cannot be found is junit/framework/TestCase

My classpath is set in the autoexec.bat file using

SET CLASSPATH=C:\j2sdk1.4.1_06
SET CLASSPATH=%CLASSPATH%;C:\JDeveloper\junitpart.jar

This checks out when I use the set command at the DOS prompt.

The junitpart.jar file exists and contains a file called TestCase.class
and the path is junit\framework\

Any ideas?

Thanks very much
Tim
 
C

Chris Smith

Tim said:
OK, I'm still having some problems so maybe I can give some info and you
can see where I'm screwing up. I'm sure it's some relative path problem.

The class that cannot be found is junit/framework/TestCase

My classpath is set in the autoexec.bat file using

SET CLASSPATH=C:\j2sdk1.4.1_06
SET CLASSPATH=%CLASSPATH%;C:\JDeveloper\junitpart.jar

Okay, something is fishy here. Why is your JDK install directory (i.e.,
c:\j2sdk1.4.1_06) in your classpath? Also, what about the location of
your actual code? Where is that, since it's not in your classpath
anywhere?

And what's the command you use to run the application?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

The code is a jar file that I have copied to, for convienience sake, the
c:\windows directory, since that's what directory I am in when I open
the DOS prompt.
I use the command java -jar MyProjectX.jar while in C:\windows

Should the JDK install directory not be in the classpath? I've been
trying various things over the years and some stuff might be where it
shouldn't be.
 
T

Tim

Something told me it was being ingnored but I couldn't figure out how or
where to specify it.
 
C

Chris Smith

Tim said:
The code is a jar file that I have copied to, for convienience sake, the
c:\windows directory, since that's what directory I am in when I open
the DOS prompt.
I use the command java -jar MyProjectX.jar while in C:\windows

Ah! That's it. When you use the '-jar' option, the classpath
environment variable is ignored. Instead, the "Class-path" manifest
option is used, and all paths there are relative to the location of the
JAR file. So, you need to place junitpart.jar into the same directory
as MyProjectX.jar, and then add the following line to the global
attributes section of your manifest:

Class-Path: junitpart.jar

HTH,

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

So should my manifest file look like this? Can I add the line manually?

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.5.4
Created-By: 1.4.1_06-b01 (Sun Microsystems Inc.)
Main-Class: junitTest.HelloWorldTest
Class-Path: junitpart.jar

And then I should put the junitpart.jar file in c:\Windows?

I'm still having problems so I obviously am doing something wrong.
It says "Failed to load Main-Class manifest attribute from MyProjectY.jar"
 
C

Chris Smith

Tim said:
Something told me it was being ingnored but I couldn't figure out how or
where to specify it.

Yup, that's by design, and turns out to be a good thing. The point of
executable JARs is to capture everything needed to make the program run
within the JAR file itself, so that the external environment doesn't
matter. This protects you from having your app stop working on some
customer's machine because they changed something. So you put
everything in one place, and all the paths are relative to that place
(not the current working directory, which is more volatile), and
environment variables are intentionally ignored.

Hope that works for you.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Tim said:
So should my manifest file look like this? Can I add the line manually?

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.5.4
Created-By: 1.4.1_06-b01 (Sun Microsystems Inc.)
Main-Class: junitTest.HelloWorldTest
Class-Path: junitpart.jar

The manifest file above looks fine...
I'm still having problems so I obviously am doing something wrong.
It says "Failed to load Main-Class manifest attribute from MyProjectY.jar"

but it doesn't look like it's being included in the JAR file. One quick
way to check is to look at the JAR file in a utility like WinZip, and
ensure that there's an entry called /META-INF/Manifest.mf, and that it
contains the manifest stuff above. Particularly, make sure it contains
the "Main-Class" attribute, since that's what the error message is
referring to.

Assuming you discover that the manifest is either not there or
practically empty, how are you creating the JAR file?
And then I should put the junitpart.jar file in c:\Windows?

Put it in the same directory as the executable JAR file you've created
above, where ever that is... C:\WINDOWS seems like a poor choice to me;
I'd create a subdirectory for this application and change there first,
if I were you.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

Chris said:
Yup, that's by design, and turns out to be a good thing. The point of
executable JARs is to capture everything needed to make the program run
within the JAR file itself, so that the external environment doesn't
matter. This protects you from having your app stop working on some
customer's machine because they changed something. So you put
everything in one place, and all the paths are relative to that place
(not the current working directory, which is more volatile), and
environment variables are intentionally ignored.

Hope that works for you.

I got it working, thanks.
So, back to my original question. Am I supposed to add all the class
files for junit to the jar file in this case or not? Some people say I
shouldn't be doing that.
If so, what files? All of them or do I try to figure out what ones are
needed by my specific program.
Or should I tell them to get a copy of the junit.jar file and copy it to
the same directory as my application, which would only include the two
test classes in this instance?
 
C

Chris Smith

Tim said:
I got it working, thanks.
So, back to my original question. Am I supposed to add all the class
files for junit to the jar file in this case or not? Some people say I
shouldn't be doing that.
If so, what files? All of them or do I try to figure out what ones are
needed by my specific program.
Or should I tell them to get a copy of the junit.jar file and copy it to
the same directory as my application, which would only include the two
test classes in this instance?

What you should do is actually distribute both your own code (in your
executable JAR file), and the JUnit JAR file. Leave them as two
separate files. Then, leave the manifest from the executable JAR file
referencing the JUnit JAR file. Arrange for the two files to end up in
the same directory (whether you have an installation program, or just
tell the user to unzip a file into a directory, you should be able to
arrange that somehow...)

This is subject to the licensing agreement for JUnit. I'm not a lawyer,
and can't give an informed opinion on that... so as with all legal
contracts, you'd be advised to read it yourself, and have a lawyer read
the license if you think it's appropriate, to determine your rights and
potential liability. However, I don't personally see anything that
would prevent using JUnit in that way. If you or your lawyer do see a
potential legal problem there, you could always ask the user to download
a copy of JUnit on their own... really, that's not much to ask if they
want to be running unit tests on your code.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim

Chris said:
What you should do is actually distribute both your own code (in your
executable JAR file), and the JUnit JAR file. Leave them as two
separate files. Then, leave the manifest from the executable JAR file
referencing the JUnit JAR file. Arrange for the two files to end up in
the same directory (whether you have an installation program, or just
tell the user to unzip a file into a directory, you should be able to
arrange that somehow...)

This is subject to the licensing agreement for JUnit. I'm not a lawyer,
and can't give an informed opinion on that... so as with all legal
contracts, you'd be advised to read it yourself, and have a lawyer read
the license if you think it's appropriate, to determine your rights and
potential liability. However, I don't personally see anything that
would prevent using JUnit in that way. If you or your lawyer do see a
potential legal problem there, you could always ask the user to download
a copy of JUnit on their own... really, that's not much to ask if they
want to be running unit tests on your code.

OK. Again, I'm just doing this as a learning experience so it's all
theoretical, anyway.
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top