views:

315

answers:

4

Hi all,

I have a project that uses ant to build and ivy for dependencies. I would like to generate the start scripts for my project, with the classpath, based on the dependencies configured in Ivy, especially as the order of dependencies may be important and needs to be preserved from the order in the ivy config.

Has anyone done this before? I also need to generate relative paths in the classpath so I can't use absolute paths as this will only work for the machine on which the build is done.

EDIT: Based on feedback if we cut Ivy out the equation (do the resolve to a directory of my choice) I can then probably resolve the list of libs ok. But how would I generate a classpath suitable for a start script, especially with the relative paths (relative to my bin directory)?

e.g.

install
    /bin <-- scripts here
    /lib <-- jars here

So in my bin/start.sh I need to have ../lib/ in front of every jar reference rather than a full absolute path.

Thanks.

A: 

Since Ivy evicts overlapping dependencies and tries to find the best common dependency for all the projects I don't really understand how the order of dependencies would matter at all.

However you should make a standard JAR/WAR/other with Ant for your project and include Ivy dependencies inside that JAR. Basically all you should need to do is to make Ivy's Ant task to resolve the dependencies to a folder, then build tha classes using those dependencies and then consruct the JAR so that you include the library JAR:s to newly created JAR's /lib/ folder.

Esko
Thanks. All true, but it's mainly the start script generation I'm stuck on at the moment.
Mike Q
A: 

Like Esko said, you should create a JAR including all required JAR archives:

<zip destfile="abc.jar">
    <zipgroupfileset dir="lib/distributed" includes="*.jar"/>
    <manifest>
        <attribute name="Main-Class" value="com.acme.MyClass"/>
    </manifest>
</zip>

After that, your start script is simply:

java -jar abc.jar
Vladimir
A: 

If you're using java 1.6 you can use file globs (i.e. java -cp "../lib/*"). If you're using an earlier version of java and you don't want to use Vladimir's solution, you'll need to write a script that figures out what the classpath should be.

So launch.sh looks something like:

cd dirname %0 # change to the bin directory, use %0/.. instead and you can replace ../lib with just /lib
sh set_classpath.sh  # set the classpath
java -cp $CLASSPATH some.package.Main

and set_classpath.sh will have some linux magic that sets CLASSPATH equal to something like "../lib/abc.jar:../lib/def.jar"

export CLASSPATH=`ls *.jar | sed 's/[^.jar].jar/..\/lib\/\0:/'`
Scott Ray
+1  A: 

Since many years (2000?), we had this small script in path ("make_cp")

#!/usr/bin/perl

my $CLASSPATH="";
my $DIR=shift;
$DIR||="lib";

opendir(LIBDIR, $DIR);
while ($file = readdir(LIBDIR)) {
    $CLASSPATH.=":$DIR/$file" if ($file =~ /\.jar$|\.zip$/);
}
closedir(LIBDIR);
$CLASSPATH=~ s/^://g;
print "$CLASSPATH";

Used like this:

export CLASSPATH=`make_cp lib`:`make_cp external-lib`
hennings