Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Nigel Wade Newsgroups: comp.lang.java.programmer Subject: Re: Using jar inside a jar Date: Thu, 22 Jan 2015 11:28:31 +0000 Lines: 44 Message-ID: References: <871tmn6qh9.fsf@Equus.decebal.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net M2Hi1gbW23AKcViGR11CvgDYnNtBbhXTAYwE0lL6CLLNTx5+wF Cancel-Lock: sha1:vl/9x6Lv9opq1Bl06pbc97iD09g= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 In-Reply-To: <871tmn6qh9.fsf@Equus.decebal.nl> Xref: csiph.com comp.lang.java.programmer:30785 On 22/01/15 10:48, Cecil Westerhof wrote: > To compile a program I use: > javac -classpath ../ShowMemory/ShowMemory.jar \ > -Xlint:all \ > -Werror \ > PanelTools.java > > To create a jar I use: > jar -cvfm PanelTools.jar \ > MANIFEST.MF \ > images \ > -C ../ShowMemory ShowMemory.jar \ > *.class > > The MANIFEST.MF contains: > Manifest-Version: 1.0 > Main-Class: PanelTools > Class-Path: ShowMemory.jar > > But when I execute the program with: > java -jar PanelTools.jar & > > I get: > Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: nl/decebal/utilities/ShowMemory > > What am I doing wrong? > Java needs to know where to locate ShowMemory.jar. The only information it has is the Class-Path: entry in MANIFEST.MF. This entry only has a bare filename, so Java looks for it in the same directory as the jar file it is executing. You have various options, none of which are perfect. 1) You can embed an absolute path in the manifest. Ok if the dependency jar will always be in the same place. 2) You can use a relative path in the manifest. Better, but still only works if the jar and the dependency will always have the same relative locations. 3) Basically option 2, but during the build process copy all dependency jar's to a fixed location relative to the main jar (e.g. lib/), and use that relative path in the manifest. Best option, as it means you can package the jar and its dependency tree if you need to relocate it. Ok, so I'm sure someone will point out that there is a another option, to do with $JAVA_HOME/lib/ext. But I think it's a bad idea and I won't explain it.