Linking Jars

R

Roedy Green

Lets say you have two jars and you want to treat them logically as
one. This might happen if your program needs some third party
library. What are your options?

1. mention the second jar in the -classpath

2. install the jar in the ext directory

3. extract the members you need from the library and add them all to
the main jar.

4. extract the members you need from the library and add them to the
main jar. (How do you find out which you need, especially for a
plug-in that dynamically loads classes.)

5. Use JNLP where you can specify secondary jars.

Are there any other options?

Is there anything comparably WORA and free to JNLP for installing
ordinary apps so that they look like C apps to Windows users.
--
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 
R

Roedy Green

Are there any other options?

for example, is there something you can put in the main jar that
points to the second?

I left out changing the global classpath. They are too fragile.
--
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 
L

Lew

Robert said:

I assume your point in using a 1.4 version of the docs is to indicate how long this information has been documented in the standard reference.

Amazing what the documentation can reveal if one were *ACTUALLY TO READ IT*.

I do think one should link to current versions of the docs most of the time, though. For example,
<http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html>

No matter how long you've been programming in Java, the tutorials are valuable and for such elementary questions make a great starting point.

For the "main attributes" of the JAR manifest that you linked, that current version seems to be
http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Main Attributes

I encourage everyone to read the documentation.

Repeatedly. Reviewing the basics is necessary.
 
T

Tom Anderson


The way Roedy's question so perfectly fits the solution makes me wonder if
he's seen this before, but forgotten that he's seen it.

A word of warning about that Class-Path attribute. Say you write a library
Aries which depends on two other libraries, Castor and Pollux. You ship a
distribution with three jars, yours and those of the dependencies:

Aries
|
+- aries.jar
+- castor.jar
\- pollux.jar

In the manifest of aries.jar, you write a Class-Path attribute which
refers to castor.jar and pollux.jar, and all is well.

Now i come along, with a project containing two modules, Odin and Thor,
where Thor depends on Odin (that is, all the classes present in Odin are
made available to Thor by my build and execution processes). Thor uses
Aries. But Odin already uses Castor, for some purpose unrelated to Aries.
My layout needs to look like this:

Odin
|
+- build/classes
| |
| \- Odin's own class files
|
+- lib
|
\- castor.jar

Thor
|
+- build/classes
| |
| \- Thor's own class files
|
+- lib
|
+- aries.jar
\- pollux.jar

Note that Thor does not include castor.jar, because it is supplied by its
dependency on Odin. All the libraries have the classes they need
available, and all is well.

Except that aries.jar has a Class-Path entry saying there should be a
castor.jar right next to it. Which there isn't. So, every time a tool
which cares about Class-Path entries loads that jar, it will notice the
absence, and moan about it. Sun's javac certainly does this - i have
projects, with situations like the above, where half of the output is
javac squawking about path problems which aren't problems at all. Luckily,
i don't think java itself does.

If you think the above setup is overcomplex, how about a simpler one; one
project, but where the different dependencies are kept in different
folders, for clerical convenience:

Krishna
|
\- lib
|
+- Aries
| |
| +- aries.jar
| \- README
|
+- Castor
| |
| +- castor.jar
| \- castor-javadoc.zip
|
+- Pollux
|
+- castor.jar
\- castor-extras.jar

Seems reasonable, right? And yet javac isn't going to like that at all.

The problem is that the Class-Path header expresses the dependency as a
URL; a direct path that can be resolved in the filesystem. That constrains
filesystem layout. It should have been a symbolic reference; perhaps a
pairing of a Specification-Title and a Specification-Version that
identifies what is needed, with the onus then being on the code loading
the jar to go off and find that, by scanning the classpath, exploring the
filesystem, looking in a module repository, etc. I think OSGi does
something a bit like this; the JBoss 7 module system certainly does.

Or an even easier case - my new project Loki uses Aries, but i like naming
my jars with a version number:

Loki
|
+- lib
|
+- aries-1.0.jar
+- castor-1.4.jar
\- pollux-2.2.1.jar

They're in the right place, but they have the wrong names. Cue javac
complaining!

Having pointed out these problems, i feel like i should give some advice
for what you should do. But i don't really know what you should do.
Perhaps you should restrict the use of Class-Path to cases where you can
control or predict the filesystem layout. Two cases spring to mind.

Firstly, where you have a library that is split into multiple jars, but
where these will always be present together; perhaps you have a US tax
rate library, where the code is updated occasionally, but the data for
each state is updated frequently. You might have a jar for the code and a
jar file for each state, containing classpath resources with data in.
There, it would be reasonable to use a Class-Path in the code jar to drag
in the state jars. This still falls over if i want to rename the jars, of
course.

Secondly, where you are packaging for deployment as an application, not
for further reuse. The main jar for an applet, application, or JWS app
would all be good examples of this. Nobody but you will ever incorporate
those jars into a project, so there is no worry about constaining
filesystem layout.

Or just not worry about Class-Path, and rely on consumers to set up a
classpath correctly.

tom
 
M

markspace

The problem is that the Class-Path header expresses the dependency as a
URL; a direct path that can be resolved in the filesystem.


I thought class path entries in the manifest file were always relative
to the location of the containing Jar file? I guess you could specify
an absolute path, but I don't think it's required.

I didn't check the docs, but that's afaik.
 
R

Robert Klemme

I assume your point in using a 1.4 version of the docs is to indicate
how long this information has been documented in the standard
reference.

Actually it was a tad different: I just grabbed the first ref my
favorite search engine turned up - convinced that the classpath
attribute didn't change. :)
Amazing what the documentation can reveal if one were *ACTUALLY TO
READ IT*.
:)

I do think one should link to current versions of the docs most of
the time, though. For example,
<http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html>
Right.

No matter how long you've been programming in Java, the tutorials are
valuable and for such elementary questions make a great starting
point.

For the "main attributes" of the JAR manifest that you linked, that
current version seems to be
http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Main Attributes

Also a good point of reference.
I encourage everyone to read the documentation.

Repeatedly. Reviewing the basics is necessary.

+1

Today everybody seems to be in a rush all the time - no wonder that
software often turns bad... (Which just reminds me of a funny cartoon
of the great Gary Larson where veggies "turn bad" in the fridge - with a
pair of forks as weapons.) ;-)

Kind regards

robert
 
R

Roedy Green

Amazing what the documentation can reveal if one were *ACTUALLY TO READ IT*.

Why do you mean "IT"? The online docs on Java would form a book
several meters thick. You can't read it all. You have to know WHAT to
read. You an almost supernatural skill at knowing where to look,
perhaps because you have read it all and remember where everything is
discussed. Others have not.

You assume everyone has your skill and energy for, and absolute
confidence in one's interpretation at reading documentation.

I had to read that page three times before I noticed the relevant
lines. I only found it because someone had told me it HAD to be
there. I was looking for "jar linking" or some similar phrase. It
wasn't there.

My motive for asking is I was composing an entry in the java glossary
http://mindprod.com/jgloss/jarlinking.html

I did this as a favour to the Java community. I did not do it to
annoy you. When I write such an entry, I often ask a question to
check if there is anything I overlooked or if I harbour some
wrong-headed notion.

If you don't like answering, don't. You are not obligated to respond.
But stop chastising me every time I ask a question.

It is perfectly legit to ask a question even if I am 99% certain of
the answer, just to bring up a topic for discussion and general
education. Stop pretending it is crime to ask a question.

Besides being rude, you are squelching newbies who are afraid of you.
When you attack me, you intimidating the newbies who fear the same
treatment. You are interfering with education. CUT IT OUT!

The alternative would have resulted in a article that failed to
mention the option of OneJar or jar Class-path. That makes me brave
your shower of virtual vegetables almost every time I ask a question
or confirmation. I have to go through this humiliation ritual for the
privilege of consulting the great Lew Oracle.

You have a serious psychological problem, a pathological desire to put
others down. It must poison your whole life. You could not possibly
maintain a relationship if you belittled your partner the way you
daily belittle me.

You are a very clever person, and the information you contribute is
invaluable, but please delete the sarcasm and hectoring. It is a cold
wet blanket on discussion.
--
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 
A

Arne Vajhøj

Why do you mean "IT"? The online docs on Java would form a book
several meters thick. You can't read it all. You have to know WHAT to
read. You an almost supernatural skill at knowing where to look,
perhaps because you have read it all and remember where everything is
discussed. Others have not.

????

This is a question about jar files.

The jar file specification linked to is about 450 lines.

The Java tutorials section about jar files which also
covers this is not that much longer.

I don't think it require supernatural skills to read
the jar file specification and the Java tutorials section
about jar files for a question about jar files!!

Arne
 
T

Tom Anderson

I thought class path entries in the manifest file were always relative to the
location of the containing Jar file?

Yep. They're relative URLs! The spec says

Class-Path: The value of this attribute specifies the relative URLs of
the extensions or libraries that this application or extension needs.
URLs are separated by one or more spaces. The application or extension
class loader uses the value of this attribute to construct its internal
search path.
I guess you could specify an absolute path, but I don't think it's
required.

Indeed it's not. But a relative URL is still a URL.

tom
 
T

Tom Anderson

Thank you. May the hordes of Java programmers come to your site and not
stackoverlow.com.

Oi!

How about, may the hordes of Java programmers come to Roedy's site, and
not to JavaRanch?

tom
 
R

RedGrittyBrick

You have a serious psychological problem, a pathological desire to put
others down. It must poison your whole life. You could not possibly
maintain a relationship if you belittled your partner the way you
daily belittle me.

Don't worry, be happy.


The wizard of Java
==================

Cast
----

The Scarecrow: Roedy
The Tin-man: Lew
The Wizard: Lew
Glinda: Patricia?




Just my ¤0.02 worth.
 

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

Similar Threads

Add *.jars to *.jars possible/recommendend? Eclipse setup for this? 2
Jars 4
Java web start and jars... 8
Custom fonts 11
manifest class-path 0
JNLP error 0
System.exit 11
Thread question 14

Members online

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,733
Latest member
LonaMonzon

Latest Threads

Top