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 / First Aid / March 2008

Tip: Looking for answers? Try searching our database.

trivial third party jar dependancy

Thread view: 
thufir - 27 Mar 2008 14:06 GMT
I googled a bit but didn't find anything trivial.  I have a "hello
world" which happens to do a randomly-chosen calculation.  What I would
like to throw into the mix is a third party jar of some sort so that
HelloFibonacci.jar has a dependancy on this third party jar to do
something.

I'm not sure what the something is, but it should be trivial.  This is
strictly to work on packaging rather than anything else at the
moment.

What would be a simple sort of jar file to include in the compiling and
building process, which I could then utilize?  Perhaps instantiate
something from this third party jar, something along those lines --
nothing complex.

thufir@arrakis:~/java$
thufir@arrakis:~/java$ java -jar build/HelloFibonacci.jar

Hello World!
the fibonacci of 9 is:          34

thufir@arrakis:~/java$
thufir@arrakis:~/java$ cat src/thufir/sun/hello/HelloWorldApp.java
package thufir.sun.hello;

import thufir.math.Calculations;

class HelloWorldApp {
       public static void main(String[] args) {
               System.out.println("\nHello World!");
               System.out.print("the fibonacci of 9 is:\t\t");
               System.out.print(Calculations.fibonacci(9));
               System.out.print("\n\n\n");
       }
}
thufir@arrakis:~/java$
thufir@arrakis:~/java$ cat src/thufir/math/Calculations.java
package thufir.math;

//should be an abstract class

public class Calculations {
       public static int fibonacci(int n) {
               if (n <= 2)
                       return 1;
               else
                       return fibonacci(n - 1) + fibonacci(n - 2);
       }
}
thufir@arrakis:~/java$
thufir@arrakis:~/java$

thanks,

thufir
Lew - 27 Mar 2008 14:47 GMT
> I googled a bit but didn't find anything trivial.  I have a "hello
> world" which happens to do a randomly-chosen calculation.  What I would
[quoted text clipped - 10 lines]
> something from this third party jar, something along those lines --
> nothing complex.

Why does it have to be a third-party JAR?  Why not write your own dependency
JAR for this test?  Have it include one test class.

Signature

Lew

Mark Space - 27 Mar 2008 19:07 GMT
> I googled a bit but didn't find anything trivial.  I have a "hello
> world" which happens to do a randomly-chosen calculation.  What I would
> like to throw into the mix is a third party jar of some sort so that
> HelloFibonacci.jar has a dependancy on this third party jar to do
> something.

Are you just asking how to use an external jar?  I didn't include a
third party jar, I just used your thufir.math.Calculations class to make
a "third party" file then ran it like I would if it were external:

Brenden@Homer ~/Dev/misc/thufirTest
$ java -cp "build2;dist/fibonacci.jar" thufir.sun.hello.HelloWorldApp

Hello World!
the fibonacci of 9 is:          34

Brenden@Homer ~/Dev/misc/thufirTest
$ ls build2/thufir/sun/hello/HelloWorldApp.class
build2/thufir/sun/hello/HelloWorldApp.class

Brenden@Homer ~/Dev/misc/thufirTest
$ ls dist/fibonacci.jar
dist/fibonacci.jar

Brenden@Homer ~/Dev/misc/thufirTest
$ jar -tf dist/fibonacci.jar
META-INF/
META-INF/MANIFEST.MF
thufir/
thufir/math/
thufir/math/Calculations.class
thufir - 28 Mar 2008 02:02 GMT
> Are you just asking how to use an external jar?

Yes.

I made a jar of just that Calculations class and now want this "Foo"
class (just HelloWorldApp with a different name in a different package)
to use Calculations as an external jar.  (If I simply import
thufir.math.Calculations everything runs fine, the problem is with using
an external jar.)

thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ pwd
/home/thufir/jrake
thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ java -jar lib/thufir/math/Calculations.jar
Calculations.main
thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ cd src/
thufir@arrakis:~/jrake/src$
thufir@arrakis:~/jrake/src$ javac -d /home/thufir/jrake/prod/ -cp "/home/
thufir/jrake/lib/thufir/math/Calculations.jar" thufir/foo/Foo.java
thufir@arrakis:~/jrake/src$ cd ..
thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ ll src/thufir/foo/Foo.java
-rw-r--r-- 1 thufir thufir 205 2008-03-27 16:30 src/thufir/foo/Foo.java
thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ ll prod/thufir/foo/Foo.class
-rw-r--r-- 1 thufir thufir 722 2008-03-27 17:41 prod/thufir/foo/Foo.class
thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ cd prod/
thufir@arrakis:~/jrake/prod$
thufir@arrakis:~/jrake/prod$ java -cp . thufir.foo.Foo

the fibonacci of 9 is:          Exception in thread "main"
java.lang.NoClassDefFoundError: thufir/math/Calculations
       at thufir.foo.Foo.main(Foo.java:7)
thufir@arrakis:~/jrake/prod$

thanks,

Thufir
thufir - 28 Mar 2008 03:24 GMT
> Brenden@Homer ~/Dev/misc/thufirTest
> $ java -cp "build2;dist/fibonacci.jar" thufir.sun.hello.HelloWorldApp
>
> Hello World!
> the fibonacci of 9 is:          34

Ok, I went back and did what you did and it worked:

thufir@arrakis:~/jrake/prod$
thufir@arrakis:~/jrake/prod$
thufir@arrakis:~/jrake/prod$ java -cp /home/thufir/jrake/lib/thufir/math/
Calculations.jar:. thufir.foo.Foo

the fibonacci of 9 is:          Calculations.fibonacci
Calculations.fibonacci
[...]
Calculations.fibonacci
34

thufir@arrakis:~/jrake/prod$

So, that's pretty cool, and now I know it's just a matter manifests
(yes?).  When Foo.jar is created, the manifest must include a reference
to Calculations.jar as above so that I can:

java -jar Foo.jar

and Foo.jar will find Calculations.jar and run the calculations!

Ok, it's sorta-almost coming together :)

thanks,

Thufir
Mark Space - 28 Mar 2008 04:26 GMT
> So, that's pretty cool, and now I know it's just a matter manifests
> (yes?).  When Foo.jar is created, the manifest must include a reference
> to Calculations.jar as above so that I can:
>
> java -jar Foo.jar

Yes!  Good job.  I just showed you the first part -- with a .class file,
the -classpath on the java command [1] points to the jar files, or other
classes or .zip files, that the .class uses.

With java -jar, you have to set the Class-Path property.  For whatever
reason, java -jar ignores any classpath you specify on the command line.
 This is very counter intuitive to me, but there it is.

To set it, I made a jar file of just your HellowWorldApp and set the
classpath.

Brenden@Homer ~/Dev/misc/thufirTest
$ jar umf build2/classpath.mf dist/hello.jar
Mar 27, 2008 8:20:46 PM java.util.jar.Attributes read
WARNING: Duplicate name in Manifest: Class-Path.
Ensure that the manifest does not have duplicate entries, and
that blank lines separate individual sections in both your
manifest and in the META-INF/MANIFEST.MF entry in the jar file.

Brenden@Homer ~/Dev/misc/thufirTest
$ cat build2/classpath.mf
Class-Path: ./fibonacci.jar

Brenden@Homer ~/Dev/misc/thufirTest
$ java -jar dist/hello.jar

Hello World!
the fibonacci of 9 is:          34

But it helps if you wrestle around with this yourself, if you want to
remember it later.

BTW, you should be able to build on the command line without using so
many cd (change directories).  And you can use relative paths, you don't
need the full path.  But this is not a big deal, it should be seldom
that you need actually do it by hand.  (I did this as an exercise for
myself to see if I remember it all.  I only made a couple of mistakes. :D)
thufir - 28 Mar 2008 05:03 GMT
> But it helps if you wrestle around with this yourself, if you want to
> remember it later.

Yeh.  I think this is the hardest thing about java -- the build process.  
There are plenty of books explaing OOP theory, or books on ANT, but
little that I've found between the two.

Right now I'm actually using rake tasks (ruby) which is only mildly
awkward but easier for me to understand than ANT:

http://code.google.com/p/jrake/

> BTW, you should be able to build on the command line without using so
> many cd (change directories).  And you can use relative paths, you don't
> need the full path.  But this is not a big deal, it should be seldom
> that you need actually do it by hand.  (I did this as an exercise for
> myself to see if I remember it all.  I only made a couple of mistakes.
> :D)

Thanks :)

-Thufir
Lew - 28 Mar 2008 06:45 GMT
> Yeh.  I think this is the hardest thing about java [sic] -- the build process.  
> There are plenty of books explaing OOP theory, or books on ANT, but
> little that I've found between the two.

This is not a Java phenomenon.  There are manuals for deployment and
operations, but less literature outside that.

Fortunately the manuals are online and mostly free, for most Java and
Java-based platforms.

> Right now I'm actually using rake tasks (ruby) which is only mildly
> awkward but easier for me to understand than ANT:
>
> http://code.google.com/p/jrake/

Learn and use Ant.  It's the /de facto/ standard.

Signature

Lew

Mark Space - 28 Mar 2008 07:12 GMT
> Yeh.  I think this is the hardest thing about java -- the build process.  
> There are plenty of books explaing OOP theory, or books on ANT, but
> little that I've found between the two.

Try using the -verbose option on both java and javac commands, it's cool.
thufir - 28 Mar 2008 05:50 GMT
> Yes!  Good job.  I just showed you the first part -- with a .class file,
> the -classpath on the java command [1] points to the jar files, or other
> classes or .zip files, that the .class uses.

Ok, thanks, got it :)

Now, is it "crazy" or does it make sense to (sometimes) perform a
colossal build which would build all the different jar files in one go?  
Of course, theoretically, you don't need to do that, except:

In theory there is no difference between theory and practice. In practice
there is.
Yogi Berra

Just for reference, the (ruby) rake build file:

thufir@arrakis:~/jrake$
thufir@arrakis:~/jrake$ cat rakefile.rb
namespace :java do

       J_ROOT = "/home/thufir/jrake/"

       task :test => :package do
               puts "test"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.cd("package")
               system("java -jar Foo.jar")
       end

       task :package => :jar do
               puts "package"
       end

       task :jar => :compile do
               puts "jar"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.cd("prod")

               system("jar cfm #{J_ROOT}package/Foo.jar manifest.txt
thufir/foo/*.class")
               FileUtils.rm("manifest.txt")
       end

       task :create_manifest => :create_directories do
               puts "create_manifest"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.cd("prod")

               File.open('manifest.txt', 'w') do |manifest|
                       manifest.puts "Main-Class: thufir.foo.Foo\n"
                       manifest.puts "Class-Path: #{J_ROOT}lib/thufir/
math/Calculations.jar\n"
               end
       end

       task :compile => :create_manifest do
               puts "compile"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.cd("src")
               system("javac -d /home/thufir/jrake/prod/ -cp \"/home/
thufir/jrake/lib/thufir/math/Calculations.jar\" thufir/foo/Foo.java")
       end

       task :create_directories => :clobber do
               puts "create_directories"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.mkdir("prod")
               FileUtils.mkdir("package")
       end

       task :clobber do
               puts "clobber"
               FileUtils.cd("#{J_ROOT}")
               FileUtils.rm_rf("prod")
               FileUtils.rm_rf("package")
       end

end
thufir@arrakis:~/jrake$

-Thufir
Lew - 28 Mar 2008 06:49 GMT
> In theory there is no difference between theory and practice. In practice
> there is.
> Yogi Berra

I've also seen this attributed to Albert Einstein:
<http://www.stumbleupon.com/demo/?review=1#url=http://www.ruhanirabin.com/2007/04
/27/famous-quotes-from-albert-einstein/
>

et al.

Misattributions spread through the 'Net as fast as gossip through a small town.

Signature

Lew

thufir - 28 Mar 2008 23:36 GMT
>> In theory there is no difference between theory and practice. In
>> practice there is.
[quoted text clipped - 4 lines]
>
> et al.

That Albert Einstein and Yogi Berra are, in fact, the same person, puts
relativity in a whole new perspective.

-Thufir
Lew - 28 Mar 2008 06:42 GMT
> With java -jar, you have to set the Class-Path property.  For whatever
> reason, java -jar ignores any classpath you specify on the command line.
>  This is very counter intuitive to me, but there it is.

There is a rationale for it.  JARs are how you package your application to run
in a foreign environment (the user's).  You have no control over the user's
CLASSPATH or if they use the -cp option correctly.  To get around that, you
could write a shell script to launch the JAR, but that breaks portability, not
to mention you now have to deal with the PATH and all sorts of crap on the
user machine.  If you package your application as a JAR to be run with "java
-jar" it's independent of the client environment; the application packager has
complete control of the classpath.  Users cannot accidentally or maliciously
change things by substituting alternate classes into the classpath.  The
-classpath option is for the user; the -jar option with manifest control of
the classpath is for the vendor.

Perfectly "intuitive".

Signature

Lew
"The only intuitive interface [for humans] is the nipple."

Mark Space - 28 Mar 2008 07:17 GMT
>> With java -jar, you have to set the Class-Path property.  For whatever
>> reason, java -jar ignores any classpath you specify on the command
[quoted text clipped - 3 lines]
> to run in a foreign environment (the user's).  You have no control over
> the user's CLASSPATH or if they use the -cp option correctly.  To get

For a savvy user, I'd like to see the -cp option used.  It's a way of
making sure stuff is still accessible when an old .jar assumes a library
in one location which have moved to another.  It's a long term
maintenance issue.  For that matter, the CLASSPATH in the environment
should work the same way.  Environment namespace pollution bugs me, but
it's still useful.
Lew - 28 Mar 2008 13:14 GMT
>>> With java -jar, you have to set the Class-Path property.  For
>>> whatever reason, java -jar ignores any classpath you specify on the
[quoted text clipped - 6 lines]
>
> For a savvy user, I'd like to see the -cp option used.  It's a way of

Then they simply invoke the main class without the -jar option.  The choice is
there.

> making sure stuff is still accessible when an old .jar assumes a library
> in one location which have moved to another.  It's a long term

You're supposed to bundle the library /with/ the application.  If the user
moves it after that, well, what can you do?  They've just forced themselves
not to use the -jar option, but they really have no excuse for doing that, do
they?

Assuming a library location on a user system where you didn't install it with
the application is as risky as depending on them to supply the correct classpath.

> maintenance issue.  For that matter, the CLASSPATH in the environment
> should work the same way.  Environment namespace pollution bugs me, but
> it's still useful.

Yes, it is a long-term maintenance issue.  That's why you don't leave it up to
the user, but make them use the -jar option.

Signature

Lew

Lew - 28 Mar 2008 06:37 GMT
> Are you just asking how to use an external jar?  I didn't include a
> third party jar, I just used your thufir.math.Calculations class to make
[quoted text clipped - 21 lines]
> thufir/math/
> thufir/math/Calculations.class

The OP may have been asking how to include library dependencies when executing
java with the "-jar" option, in which case it would ignore the -cp option.

For that scenario one would deploy the libraries with the application JAR and
include them in the application JAR's manifest's "Class-Path" attribute.
<http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html#Main Attributes>

Signature

Lew

thufir - 28 Mar 2008 23:39 GMT
> The OP may have been asking how to include library dependencies when
> executing java with the "-jar" option, in which case it would ignore the
> -cp option.

Yes, that was my question.  It helps to hear the terminology, this gives
an idea of what to google for :)

-Thufir


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.