Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2007

Tip: Looking for answers? Try searching our database.

Using mandatory libraries (custom class loading vs. expanding libraries)

Thread view: 
Karsten Wutzke - 28 Jun 2007 10:33 GMT
Hi all!

I was wondering what would be the "best" approach to achieve class
loading flexibility in the case of

a) Running the application/applet via the local class files from the
development tree
b) Running the application/applet via a *single* JAR file?

First have a look at the dev tree

<root>
   +- bin
   +- images
   +- lang
   +- lib
   |  +- bcel.jar
   |  +- forms.jar
   |  +- ...
   +- src
   |- ....

Considering the cases:

a) When launching from local classes in dev tree, all ./lib/*.jar
files can be put on the classpath. Class loading can be performed by
the system class loader (desired).

b) When launching the single JAR file, there are basically two
approaches (affects the packaged JAR)

1. Write a custom class loader that somehow finds JAR's inside the
JAR's and loads classes from there. Disadvantage here is, that I have
to either set the so-called "libraries class loader" for any class
using a library class (to find those classes) OR I have to set my
library class loader to load *ALL* app classes system-wide (e.g. load
my main Controller class via the custom class loader, so subsequent
class loading is deferred to the custom class loader). The advantage
is, I can leave the JAR's as they are, where they are and package the
files.

2. Put *extracted* 3rd party libraries into the distribution JAR file
so that all classes run concurrently (next to the application specfic
code). All classes are always found by the system class loader and
avoids a custom class loader (and class loader headaches, which I
currently have).

The question here is: Is it legit to put extracted 3rd party JAR's
into my packaged JAR, libraries like BCEL or JGoodies for example?

Can anyone make some recommendations on what would be probably be the
best overall approach?

Karsten
Andrew Thompson - 28 Jun 2007 11:17 GMT
The best approach is to ..
- leave external libraries in exactly the same jars
they came in.
- jar the classes of the application and (ideally)
specify a main, and as I understand, the other
'dependant' jars in the manifest.
- distribute the lot of them.  Usually installers
can handle multiple jars, and web start is
optimised for it.

I generally use ant, and compact all that
into a handful of lines in the build task.  
Though admittedly, my builds are usually
for web start deployment - where manifest
files are largely redundant.

Signature

Andrew Thompson
http://www.athompson.info/andrew/

Karsten Wutzke - 28 Jun 2007 14:28 GMT
> The best approach is to ..
> - leave external libraries in exactly the same jars
> they came in.
> - jar the classes of the application and (ideally)
> specify a main, and as I understand, the other
> 'dependant' jars in the manifest.

I've had no luck achieving *anything* with handling the 3rd party
libraries via the Class-Path manifest entry. How does the manifest
line Class-Path look like?

I keep creating the line (via Ant)

Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar

to include the libs on the Class-Path when launched via JAR.

The final MANIFEST.MF is:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.5.0_11-b03 (Sun Microsystems Inc.)
Main-Class: am.Main
Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar

created by the Ant task:

 <target name="create-manifest" depends="init" description="Creates
the distribution and deployment manifest file">
   <manifest file="${manifest.file}">
     <attribute name="Main-Class" value="${main.class.name}"/>
     <attribute name="Class-Path" value="lib/bcel-5.2.jar lib/
forms-1.1.0.jar"/>
   </manifest>
 </target>

To me, this looks all perfect, the JAR contains all the libs, but as I
mentioned above, I am constantly unable to get the Class-Path manifest
entry right to find sub lib classes automatically (by the system class
loader).

What am I doing wrong?

I keep reading

http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html
http://mindprod.com/jgloss/jar.html

but "it" refuses find any of the classes of the respective libs. ->
NoClassDefFoundError /org/apache/bcel/generic/Type

Please help, I probably don't have to write a custom class loader to
just load standard library class files....

Karsten
Thomas Fritsch - 28 Jun 2007 15:08 GMT
Karsten Wutzke schrieb:
> I've had no luck achieving *anything* with handling the 3rd party
> libraries via the Class-Path manifest entry. How does the manifest
[quoted text clipped - 13 lines]
> Main-Class: am.Main
> Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar
These relative URLs in your Class-Path mean that you have to arrange
your jar files in the following directory structure:
    yourMain.jar
    lib/
        bcel-5.2.jar
        forms-1.1.0.jar
Is that the case in your environment?

Signature

Thomas

Karsten Wutzke - 28 Jun 2007 15:48 GMT
On 28 Jun., 16:08, Thomas Fritsch <i.dont.like.s...@invalid.com>
wrote:
> Karsten Wutzke schrieb:
>
[quoted text clipped - 26 lines]
> --
> Thomas

Exactly! This is the structure in my local dev tree. I then create my
distribution JAR file by putting the libs *inside* the JAR, here
yourMain.jar under the lib dir.

This doesn't work, as I've just encountered the sentence:

http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html

First note:
"The Class-Path header points to classes or JAR files on the local
network, *** not JAR files within the JAR file *** or classes
accessible over internet protocols. *** 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."

(If this *really* is the case I know I have to write my custom class
loader... cause I do have JARs inside my app JAR)

So consequently, launching yourMain.jar with the libs inside *can't*
work, no matter what the manifest Class-Path contains.

OK I agree, buuuut...

Every since I create and launch application JARs I put them into my
*root* development dir, where the lib dir is located... So, even if I
create a ("wrong") JAR containing the lib dir with "non-classpath-
recognized" JARs inside and the manifest still contains the entry
"Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar", the libraries
should be found *on the local subdir lib*  when launching the JAR at
all times *anyway*!

The libs inside the JAR are ignored for anything anyway, the Class-
Path lists those entries local to the JAR (System property
"user.dir"?) which are there. If those refer to relative files
"outside" of the launched JAR (user.dir?), I wonder why these lib JARs
were and are *never* found and put on the class path!

Another thing:

When launching the jar (anywhere) I print the Java System property
"java.class.path". It CONSTANTLY only has exactly ONE entry, namely
the name of the launched JAR file. This means, the manifest, no matter
what is written in the Class-Path: ... line has absolutely no effect.

Why aren't the local ./lib/*.jar files found as specified by the
manifest Class-Path entries though they exist?

Karsten
Owen Jacobson - 28 Jun 2007 19:35 GMT
> > Karsten Wutzke schrieb:
> > > The final MANIFEST.MF is:

> > > Manifest-Version: 1.0
> > > Ant-Version: Apache Ant 1.7.0
> > > Created-By: 1.5.0_11-b03 (Sun Microsystems Inc.)
> > > Main-Class: am.Main
> > > Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar

...

> Another thing:
>
[quoted text clipped - 5 lines]
> Why aren't the local ./lib/*.jar files found as specified by the
> manifest Class-Path entries though they exist?

How are you launching the program?

$ java -cp yourMain.jar main.class.Name
or
$ java -jar yourMain.jar

I believe (possibly incorrectly, I haven't had classpath problems in a
long time) that only the latter will use the Class-Path: entries from
the yourMain.jar manifest.  I know for a fact that the latter will
ignore other classpath entries (eg. from the CLASSPATH env var, or the
command line).
Karsten Wutzke - 29 Jun 2007 07:24 GMT
> > > Karsten Wutzke schrieb:
> > > > The final MANIFEST.MF is:
[quoted text clipped - 27 lines]
> ignore other classpath entries (eg. from the CLASSPATH env var, or the
> command line).

"ant run-dist"

But I try it frequently with "java -jar myapp.jar" as well. No
difference. I have no special setup, and I don't use any command line
arguments. The thing is escpecially strange in that I use two
completely different computers to try what I described, both behave in
the same way irgnoring the manifest Class-Path: ... I checked the
created JAR so many times...

Here's what it looks like (I also extracted it):

<root>
 +- am
     +- appspecificpackage1
     +- appspecificpackage2
     +- appspecificpackageN
     +- Main.class
 +- api
     +- ownapipackage1
     +- ownapipackage2
     +- ownapipackage3
 +- images
     +- imageA.jpg
     +- ...
 +- languages
     +- LanguagePack_en_US.properties
     +- LanguagePack_en_DE.properties
     +- ...
 +- META-INF
     +- INDEX.LIST
     +- MANIFEST.MF

Again, the copied MANIFEST.MF from a few mins ago:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.5.4
Created-By: 1.5.0_09-b03 (Sun Microsystems Inc.)
Main-Class: am.Main
Built-By: Karsten Wutzke
Built-On: 2007-06-29 07:57:50
Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar

I'd really like to debug this, as I have absolutely no idea what could
cause all this.

BTW: Putting the lib/bcel-5.2.jar lib/forms-1.1.0.jar JARs on the
classpath and simply run via the not JARred classes works PERFECTLY!

Here's the Ant task that creates my JAR along with the manifest task:

 <target name="create-manifest" depends="init">
   <manifest file="${manifest.file}">
     <attribute name="Main-Class" value="${main.class.name}"/>
     <attribute name="Built-By"   value="${author.name}"/>
     <attribute name="Built-On"   value="${datetime.iso}"/>
     <attribute name="Class-Path" value="lib/bcel-5.2.jar lib/
forms-1.1.0.jar"/>
   </manifest>
 </target>

 <target name="dist" depends="compile,create-manifest">
   <jar destfile="${dist.file}" basedir="${bin.dir}" index="true"
manifest="${manifest.file}">
     <fileset refid="fileset.images"/>
     <fileset refid="fileset.languages"/>
   </jar>
 </target>

Well nothing special at all. In fact I use a good Ant book, so I'm
basically on the right way here. Ah BTW, init task creates an ISO
timestamp and some dirs, compile compiles the classes, again, nothing
special here. The properties are all set, I checked 1000 times.

I'm out of ideas...

Karsten
Andrew Thompson - 29 Jun 2007 08:45 GMT
...
>...irgnoring the manifest Class-Path: ... I checked the
>created JAR so many times...

There was an odd aspect of manifest files, in that
they had to end in a new (blank) line.  Though I..
- thought it had been fixed long ago.
- would expect an ant task that creates manifests
to add the newline.  

OTOH...
..
>Again, the copied MANIFEST.MF from a few mins ago:
>
[quoted text clipped - 5 lines]
>Built-On: 2007-06-29 07:57:50
>Class-Path: lib/bcel-5.2.jar lib/forms-1.1.0.jar

..it is not entirely clear where this file ends.

(And in case I did not mention before, I am no
expert on manifest files.  Not having to write
them anymore is one the benefits of web start,
as I see it!)

Had you ruled out web start deployment?
It seems even if the jars required signing (using
ant), it would be easier to avhieve than get the
manifest working correctly.   ;-)

Signature

Andrew Thompson
http://www.athompson.info/andrew/

Karsten Wutzke - 29 Jun 2007 08:58 GMT
> ..
>
[quoted text clipped - 6 lines]
> - would expect an ant task that creates manifests
> to add the newline.

I know of this critter... I read Roedy's "tuto" thoroughly and even
after having readit many times, I couldn't find anything I'm missing.
The only hope now would be to have other people try my (stripped down)
setup.

> OTOH...
> .
[quoted text clipped - 10 lines]
>
> .it is not entirely clear where this file ends.

There are two more lines... I just checked, there are two 0D0A at the
end, meaning two \n.

> (And in case I did not mention before, I am no
> expert on manifest files.  Not having to write
[quoted text clipped - 10 lines]
>
> Message posted viahttp://www.javakb.com

Well I intend to use WebStart sometime in the future. But thats
another story. For now, I'm only concerned about a setup that finds my
library classes, such as BCEL, JGoodies, Apache Commons... etc. This
is not even something special I try, but it pretty much turns into a
nightmare...

Karsten
Roedy Green - 29 Jun 2007 14:22 GMT
>I know of this critter... I read Roedy's "tuto" thoroughly and even
>after having readit many times, I couldn't find anything I'm missing.
>The only hope now would be to have other people try my (stripped down)
>setup.

let's see your ant script.   You might post it on a website or get
someone (e.g. me) to post in on a website for you so others can have a
look at it.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Karsten Wutzke - 29 Jun 2007 14:33 GMT
On 29 Jun., 15:22, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> >I know of this critter... I read Roedy's "tuto" thoroughly and even
> >after having readit many times, I couldn't find anything I'm missing.
[quoted text clipped - 7 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

There was nothing terribly wrong with my Ant build file, other than
index="true" doesn't produce a correct index file. To create a correct
INDEX.LIST refer to the post in the same thread (as a final note):

http://groups.google.de/group/comp.lang.java.programmer/tree/browse_frm/thread/9
2a8dd8c38f520ea/a7d00521ad1ee8a6?rnum=11&hl=de&_done=%2Fgroup%2Fcomp.lang.java.p
rogrammer%2Fbrowse_frm%2Fthread%2F92a8dd8c38f520ea%2Faad4799913d9165d%3Fhl%3Dde%
26#doc_a24dbada87498bd3


Karsten
Roedy Green - 29 Jun 2007 14:25 GMT
>I know of this critter... I read Roedy's "tuto" thoroughly and even
>after having readit many times, I couldn't find anything I'm missing.
>The only hope now would be to have other people try my (stripped down)
>setup.

Lets have a peek at the result. Look inside the jar for a file called
manifest.mf using Winzip or similar archiver.

it should look something like this:

Manifest-Version: 1.0
Created-By: Jakarta Ant 1.7.0 (December 13 2006)
Main-Class: com.mindprod.canadiantax.CanadianTax

Name: com/mindprod/common13/HybridJ$1.class
Last-Modified: Sat, 16 Jun 2007 01:00:20 PDT
Content-Location: E:\com\mindprod\common13\HybridJ$1.class

--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Thomas Fritsch - 29 Jun 2007 11:44 GMT
> There was an odd aspect of manifest files, in that
> they had to end in a new (blank) line.  Though I..
> - thought it had been fixed long ago.
It isn't, and probably never will :-(
See <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4274235>
> - would expect an ant task that creates manifests
> to add the newline.
[quoted text clipped - 12 lines]
>
> .it is not entirely clear where this file ends.

Signature

Thomas

Karsten Wutzke - 29 Jun 2007 09:45 GMT
snip
> Here's the Ant task that creates my JAR along with the manifest task:

>   <target name="dist" depends="compile,create-manifest">
>     <jar destfile="${dist.file}" basedir="${bin.dir}" index="true"
[quoted text clipped - 6 lines]
> Well nothing special at all. In fact I use a good Ant book, so I'm
> basically on the right way here.

Well, I just tried something as a "last bastion"......

And now, by magic, the manifest setup I HAD *WORKS*!!

But how?

Easy... but extremely hard to find... as far as I remember, the author
of my smart Ant book stated it was good practice to use an index file
in the <jar> task... so I did and never worried.

<jar destfile="${dist.file}" basedir="${bin.dir}" index="true"
manifest="${manifest.file}">

Then I removed the index="true"... to my astonishment this started up
the app with the system class loader finding all library classes as
specific in the manifest! This took me soo many headaches! For such a
banal thing...

I suppose since there are so many Ant users out there and not being
able to get a manifest with lib/libraries setup because of this index
file in the JAR I would consider this a bug on someone's end. I just
can't say who to blame...

Is it Sun?

How do the index file and the manifest file relate to each other? And
why (the "%$?!) does the index file block the manifest's Class-
Path: ... library entries????

Anyway, I just hope other developers find this posting as well... it's
a real relief! (thank god it's almost weekend)

Karsten
Roedy Green - 29 Jun 2007 14:35 GMT
>Then I removed the index="true"... to my astonishment this started up
>the app with the system class loader finding all library classes as
>specific in the manifest! This took me soo many headaches! For such a
>banal thing

does this EVER work, or is there something odd about your situation
that is making it fail?
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Karsten Wutzke - 29 Jun 2007 14:51 GMT
On 29 Jun., 15:35, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> >Then I removed the index="true"... to my astonishment this started up
> >the app with the system class loader finding all library classes as
[quoted text clipped - 6 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

This? What exactly did you mean that could work?

There's absolutely nothing special about my app setup really. I juts
followed a few big steps in the book "Java Development with Ant", 1st
Ed. is from 2003, the 2007 "Ant in Action" is just about to be
published.

The author makes some good points about using an index file
(performance etc.) and concludes the paragraph with the sentence:

"If one line in the build file may deliver a speedup on network
application loading, why not use it?"

I had to grin when I read it... um... not really... :-/

Anyway, don't use index="true" alone when using a manifest that has
Class-Path entries... Ant users should upgrade to at least version
1.6.2. (guess what I'll be doing tonight).

Karsten
Roedy Green - 29 Jun 2007 17:18 GMT
>Ant users should upgrade to at least version
>1.6.2. (guess what I'll be doing tonight).

I am using 1.7.0.  Please let us know if they have fixed it.

--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Karsten Wutzke - 29 Jun 2007 22:07 GMT
On 29 Jun., 18:18, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> >Ant users should upgrade to at least version
> >1.6.2. (guess what I'll be doing tonight).
[quoted text clipped - 4 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

I did. At work I also have v1.7.0 ... it works the way I desribed.
Feel free to update your tutorial, or link to this thread. If you need
further help describing, count me in.

Karsten
Roedy Green - 29 Jun 2007 22:25 GMT
>I did. At work I also have v1.7.0 ... it works the way I desribed.
>Feel free to update your tutorial, or link to this thread. If you need
>further help describing, count me in.

Sorry. I can't follow what you are talking about.  Perhaps I will read
it over and over and it will make sense.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Roedy Green - 28 Jun 2007 21:30 GMT
>Can anyone make some recommendations on what would be probably be the
>best overall approach?

Do an experiment.  The tendency today is ALWAYS to use jars.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Karsten Wutzke - 29 Jun 2007 14:27 GMT
On 28 Jun., 22:30, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:

> >Can anyone make some recommendations on what would be probably be the
> >best overall approach?
[quoted text clipped - 3 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

I decided to do one of my last postings on that topis here.

The problem is with Ant and using index="true" with the <jar> task. An
index list is only created in the JAR for the JAR created, it
basically ignores all entries in the manifest Class-Path.

There are *two* solutions:

1. Run "jar i myapp.jar" *after* having created the (not yet working)
JAR. This will magically create the INDEX.LIST *with* the libs used. I
suppose the MANIFEST.MF Class-Path: ... get resolved...

2. Ant 1.6.2. adds the <indexjars> tag to the <jar> tag to denote a
list of JARs for which an index should be created.

http://ant.apache.org/manual/CoreTasks/jar.html#indexjars

To read a little more:

http://mail-archives.apache.org/mod_mbox/ant-dev/200404.mbox/%3Cm3u0zb56vt.fsf@b
odewig.bost.de%3E


As you can see, this is not really new, just pretty much unknown (and
not in the Ant book I mentioned).

To see it in action:

<!-- create a temporary manifest file -->
<target name="create-manifest" depends="init" description="Creates the
temp manifest file">
 <manifest file="${manifest.file}">
   <attribute name="Class-Path" value="lib/bcel-5.2.jar lib/
forms-1.1.0.jar"/>
   <attribute name="Main-Class" value="${main.class.name}"/>
   <attribute name="Built-By"   value="${author.name}"/>
   <attribute name="Built-On"   value="${datetime.iso}"/>
 </manifest>
</target>

<!-- create a distribution JAR file from the compiled classes -->
<target name="dist" depends="compile,create-manifest"
description="Creates the distribution JAR file">
 <jar destfile="${dist.file}" basedir="${bin.dir}" index="true"
manifest="${manifest.file}">
   <fileset refid="fileset.images"/>
   <fileset refid="fileset.languages"/>
   <indexjars>
     <fileset dir="${lib.dir}"/>
     <!--fileset refid="fileset.libs"/-->
   </indexjars>
 </jar>
</target>

@Roedy:

Maybe you should include this problem into your JAR glossary,
somewhere under the Class-Path: ... , 2. option...

HTH not only me
Karsten
Karsten Wutzke - 29 Jun 2007 14:41 GMT
> On 28 Jun., 22:30, Roedy Green <see_webs...@mindprod.com.invalid>

> To read a little more:
>
> http://mail-archives.apache.org/mod_mbox/ant-dev/200404.mbox/%3Cm3u0zb56vt....@b
odewig.bost.de%3E

*gulp*

Just enter "indexjars" in google...

Karsten


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.