gmoniey
asked on
using ant to define multiple jars in classpath with manifest tag
I have searched high and low and I still cant seem to figure out how to define multiple jar files (or even one for that matter) within the manifest file using ant.
I am trying to determine what is the best choice for deployment, so I want to try to package the dependencies within my jar file, and well as put them in an external directory.
If my dependencies are located in an external directory, I have the following (which doesnt want to work):
<target name="Myjar" depends="dist, compile, filename" description="generate jar" >
<jar destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="${Main_Class}"/>
<attribute name="Class-Path" value=".;c:/test/comm.jar; c:/test/db 4o5.5jar" />
</manifest>
</jar>
</target>
I have tried tons of combinations, using different slashes, using spaces, or commands instead of colons, nothing seems to work with respect to the Class-Path attribute. The rest is working fine.
thanks in advance.
I am trying to determine what is the best choice for deployment, so I want to try to package the dependencies within my jar file, and well as put them in an external directory.
If my dependencies are located in an external directory, I have the following (which doesnt want to work):
<target name="Myjar" depends="dist, compile, filename" description="generate jar" >
<jar destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="${Main_Class}"/>
<attribute name="Class-Path" value=".;c:/test/comm.jar;
</manifest>
</jar>
</target>
I have tried tons of combinations, using different slashes, using spaces, or commands instead of colons, nothing seems to work with respect to the Class-Path attribute. The rest is working fine.
thanks in advance.
*But* afaik, you can't use absolute paths
ASKER
that doesnt work. I tried using spaces already. Why can't i use absolute paths? I know exactly where the jars will be on my deployment machines
this should do it. you will have to tweak the 'depends', ${lib.dir}.
The following takes all of the jar files found in ${lib.dir} and adds them to the 'Class-Path' part of the manifest.
<target name="jar" depends="your_compile_depe nds"
description="Create a jar file">
<dirname property="build.lib.dir" file="${lib.dir}"/>
<!-- dirsep may not be portable -->
<pathconvert pathsep=" " dirsep="/" property="build.manifest.c lasspath">
<map from="${build.lib.dir}" to="."/>
<path>
<fileset dir="${lib.dir}" excludes="dir/to/exclude/* *" includes="*.jar"/>
</path>
</pathconvert>
<jar destfile="${build.lib}/You rFileNameH ere.jar">
<fileset dir="${build.classes}" includes="package/that/is/ included/h ere/**"/>
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Class-Path" value="${build.manifest.cl asspath}"/ >
<attribute name="Main-Class" value="your.package.declar ation.Main "/>
</manifest>
</jar>
</target>
The following takes all of the jar files found in ${lib.dir} and adds them to the 'Class-Path' part of the manifest.
<target name="jar" depends="your_compile_depe
description="Create a jar file">
<dirname property="build.lib.dir" file="${lib.dir}"/>
<!-- dirsep may not be portable -->
<pathconvert pathsep=" " dirsep="/" property="build.manifest.c
<map from="${build.lib.dir}" to="."/>
<path>
<fileset dir="${lib.dir}" excludes="dir/to/exclude/*
</path>
</pathconvert>
<jar destfile="${build.lib}/You
<fileset dir="${build.classes}" includes="package/that/is/
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Class-Path" value="${build.manifest.cl
<attribute name="Main-Class" value="your.package.declar
</manifest>
</jar>
</target>
ASKER
Hi kawas,
I havent tried your solution yet, because I honestly don't understand all of it. I don't see why i have to tweak my 'depends' (is it because I need to ensure that the ${lib.dir} exists? also, is the ${lib.dir} variable a system variable, or one that I define.
Also, is your example packing the depndency jars with the jar I am creating? or are they assumed to be external dependencies (I am actually looking to implement both of these solutions, as I want to determine which is most feasible)
Lastly, I how it isn't too much to ask, but could you break down the "pathconvert" section? That is primarily where I am lost (as from what i gather the lines before that simply assign the ${build.lib.dir} variable to be the file path of the ${lib.dir} variable)
thanks!
I havent tried your solution yet, because I honestly don't understand all of it. I don't see why i have to tweak my 'depends' (is it because I need to ensure that the ${lib.dir} exists? also, is the ${lib.dir} variable a system variable, or one that I define.
Also, is your example packing the depndency jars with the jar I am creating? or are they assumed to be external dependencies (I am actually looking to implement both of these solutions, as I want to determine which is most feasible)
Lastly, I how it isn't too much to ask, but could you break down the "pathconvert" section? That is primarily where I am lost (as from what i gather the lines before that simply assign the ${build.lib.dir} variable to be the file path of the ${lib.dir} variable)
thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi kawas,
It didn't work, and I believe I know why. Your solution assumes that my jar file will be in the lib directory. Unfortunately, that is not the case here. The dependencies will be in a shared directory, which i do not want to place the jar file within. (This dependency directory will always be available)
I want to jar file to be portable...i.e. the end user can move it around, and the manifest will point to an absolute path where the dependencies can be found.
It didn't work, and I believe I know why. Your solution assumes that my jar file will be in the lib directory. Unfortunately, that is not the case here. The dependencies will be in a shared directory, which i do not want to place the jar file within. (This dependency directory will always be available)
I want to jar file to be portable...i.e. the end user can move it around, and the manifest will point to an absolute path where the dependencies can be found.
ASKER
I figured it out...
if you add a leading slash, and use spaces it works
i.e.
<target name="Myjar" depends="dist, compile, filename" description="generate jar" >
<jar destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="${Main_Class}"/>
<attribute name="Class-Path" value=". /c:/test/comm.jar /c:/test/db4o5.5jar" />
</manifest>
</jar>
</target>
After some searching, it seems that it is not possible to pack jars within a jar, and add them to the classpath without using a custom class loader. If anyone has an example of this, or knows of another way, please let me know. thanks!
if you add a leading slash, and use spaces it works
i.e.
<target name="Myjar" depends="dist, compile, filename" description="generate jar" >
<jar destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="${Main_Class}"/>
<attribute name="Class-Path" value=". /c:/test/comm.jar /c:/test/db4o5.5jar" />
</manifest>
</jar>
</target>
After some searching, it seems that it is not possible to pack jars within a jar, and add them to the classpath without using a custom class loader. If anyone has an example of this, or knows of another way, please let me know. thanks!
>>After some searching, it seems that it is not possible to pack jars within a jar, and add them to the classpath without using a custom class loader. If anyone has an example of this, or knows of another way, please let me know. thanks!
It's perfectly possible with the tool you've got (Ant)
Just use a zipfileset element and specify your jars
It's perfectly possible with the tool you've got (Ant)
Just use a zipfileset element and specify your jars
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Could you explain exactly what that fileset is doing? i am tryin to implement it with my code, but i dont see how is establishes the classpath?
Also, do you happen to know how to embed quotes within an ant variable?
Also, do you happen to know how to embed quotes within an ant variable?
You don't need a classpath as all the classes are in the correct root-relative path
>>Also, do you happen to know how to embed quotes within an ant variable?
Can you show where you need that?
>>Also, do you happen to know how to embed quotes within an ant variable?
Can you show where you need that?
it doesn't incoude the jars, it incudes the classes.
more manageable to keep the jars intact imo
more manageable to keep the jars intact imo
ASKER
I suppose that works. personally i would rather keep the jars in jar form, but i suppose i dont have much of a choice
as for the example of using quotes within a variable.
I cant reference the directory: C:\Program Files because of the space. I can refer to it as C:\Progra~1, but I wanted to know if it would be possible to insert quotes
as for the example of using quotes within a variable.
I cant reference the directory: C:\Program Files because of the space. I can refer to it as C:\Progra~1, but I wanted to know if it would be possible to insert quotes
> personally i would rather keep the jars in jar form
i agree
> but i suppose i dont have much of a choice
u do :)
why don't u distribute all the jars in the one directory to keep it simple?
i agree
> but i suppose i dont have much of a choice
u do :)
why don't u distribute all the jars in the one directory to keep it simple?
>Also, do you happen to know how to embed quotes within an ant variable?
have tried escaping them?
have tried escaping them?
>>I cant reference the directory: C:\Program Files because of the space.
That should be OK as an Ant attribute. Forward slashes can be used too
That should be OK as an Ant attribute. Forward slashes can be used too
You might try
x=""C:/Program Files/X/Y/Z""
x=""C:/Program Files/X/Y/Z""
>>why don't u distribute all the jars in the one directory to keep it simple?
How?
How?
ASKER
well, the " worked, as far as adding the " character, but it didn't resolve the classpath. It seems that i will just have to stick with c:\progra~1 for now.
As for referencing jar files within a jar, I think i would rather use a custom classloader and keep the jars intact. and organized within a lib directory.
As for referencing jar files within a jar, I think i would rather use a custom classloader and keep the jars intact. and organized within a lib directory.
why do your dependant jars need to be in a seperate directory to the application jar, keeping them in the same directory would get rid of your problem.
ASKER
I want to keep the dependent jars in a different directory because I want to jar file to be portable...i.e. drag it to any folder, and it will still work.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The whole reason I am doing this is to remove jars from <jre>/lib/ext. Personally, I think it is bad design to include 3rd party jars in that folder, but that is subject to a whole different argument.
My primary reason for removing jars from the ext directory is that you cant have two versions of the same jar file (i.e. and old version, and a new version). Furthermore, java may use a different class loader for the ext jars, than what is used for your application, resulting in some classes not being loaded.
Why should i create a bat script? its just more work. Maybe a windows shortcut if i wanted to add an icon and such, but for development purposes, i want to be able to move a jar around to whatever machine i wish (provided that machine is setup with the jars i require...which they are)...and run the jar...no creating bat files, and changing the name to match my newly created jars...just point and click
My primary reason for removing jars from the ext directory is that you cant have two versions of the same jar file (i.e. and old version, and a new version). Furthermore, java may use a different class loader for the ext jars, than what is used for your application, resulting in some classes not being loaded.
Why should i create a bat script? its just more work. Maybe a windows shortcut if i wanted to add an icon and such, but for development purposes, i want to be able to move a jar around to whatever machine i wish (provided that machine is setup with the jars i require...which they are)...and run the jar...no creating bat files, and changing the name to match my newly created jars...just point and click
executable jars don't really support that sort of thing.
another option would be to use web start, that way user wouldn't need to worry about jars at all (which you probably don't want them doing anyway).
another option would be to use web start, that way user wouldn't need to worry about jars at all (which you probably don't want them doing anyway).
>>i want to be able to move a jar around to whatever machine i wish
You can only do that when you have one jar
You can only do that when you have one jar
ASKER
From what I have read, it should be possible using a custom classloader...not exactly the solution i want, but i am gonna give it a try
> You can only do that when you have one jar
already been mentioned, no need to always repeat previous comments.
already been mentioned, no need to always repeat previous comments.
>>From what I have read, it should be possible using a custom classloader.
Yes - that's how 'OneJar' works, but you still have one jar. How many jars do you want?
Yes - that's how 'OneJar' works, but you still have one jar. How many jars do you want?
<attribute name="Class-Path" value=". c:/test/comm.jar c:/test/db4o5.5jar" />