Link to home
Start Free TrialLog in
Avatar of gmoniey
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/db4o5.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.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Try

<attribute name="Class-Path" value=". c:/test/comm.jar c:/test/db4o5.5jar" />
*But* afaik, you can't use absolute paths
Avatar of gmoniey
gmoniey

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_depends"
  description="Create a jar file">
  <dirname property="build.lib.dir" file="${lib.dir}"/>
  <!-- dirsep may not be portable -->
  <pathconvert pathsep=" " dirsep="/" property="build.manifest.classpath">
    <map from="${build.lib.dir}" to="."/>
    <path>
      <fileset dir="${lib.dir}" excludes="dir/to/exclude/**" includes="*.jar"/>
    </path>
  </pathconvert>       
  <jar destfile="${build.lib}/YourFileNameHere.jar">
    <fileset dir="${build.classes}" includes="package/that/is/included/here/**"/>
    <manifest>
      <attribute name="Built-By" value="${user.name}"/>
      <attribute name="Class-Path" value="${build.manifest.classpath}"/>
      <attribute name="Main-Class" value="your.package.declaration.Main"/>
    </manifest>       
  </jar>
</target>
Avatar of gmoniey

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!
ASKER CERTIFIED SOLUTION
Avatar of kawas
kawas
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gmoniey

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.
Avatar of gmoniey

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!

>>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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gmoniey

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?
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?

it doesn't incoude the jars, it incudes the classes.
more manageable to keep the jars intact imo
Avatar of gmoniey

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
> 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?
>Also, do you happen to know how to embed quotes within an ant variable?

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
You might try

x="&quot;C:/Program Files/X/Y/Z&quot;"
>>why don't u distribute all the jars in the one directory to keep it simple?

How?
Avatar of gmoniey

ASKER

well, the &quot; 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.
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.
Avatar of gmoniey

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
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gmoniey

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
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).
>>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
Avatar of gmoniey

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.
>>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?