怎么使用ant 创建Manifest.mf的classpath

 

UPDATE It seems this is at least partly outdated, have a look at manifestclasspath .

It is possible to define .jar dependencies in the MANIFEST.MF of the main .jar file, it is just a comma seperated string which looks like this:

Class-Path: lib/log4j.jar lib/commons.jar

In a project I work on, we keep all our dependencies in a lib directory, where we add and remove libraries from time to time, therefore it would be nice if the above text can be generated automatically. Fortunately, this is possible using just Ant . Unfortunately, this is rather cumbersome. (If you want something more powerful and simpler to use, have a look at Rake ).

In a nutshell, this is how I did it:

 

  1. First, let’s define some properties:
    1. <!-- name of the output .jar file -->   
    2. < property   name = "jar.name"   value = "ourjarfile.jar"   />   
    3.   
    4. <!-- base directory for distribution target -->   
    5. < property   name = "dist.home"   value = "dist"   />   
    6.   
    7. <!-- base directory for compilation targets -->   
    8. < property   name = "build.home"   value = "target"   />   
    9.   
    10. <!-- The base directory for all libraries (jar) files -->   
    11. < property   name = "lib.home"   value = "lib"   />   
    <!-- name of the output .jar file -->
    <property name="jar.name" value="ourjarfile.jar" />
    
    <!-- base directory for distribution target -->
    <property name="dist.home" value="dist" />
    
    <!-- base directory for compilation targets -->
    <property name="build.home" value="target" />
    
    <!-- The base directory for all libraries (jar) files -->
    <property name="lib.home" value="lib" />
    
  2. Now to the fun part, create a nice .jar file. This generates the MANIFEST.MF but first generates a property libs.project that contains all .jar files, sperated with space. If you later look at the generated MANIFEST.MF you will notice that the paths are wrapped every 72 character, even in the middle of the word. Although this looks like an error, it works correctly.
    1. < target   name = "jar"   depends = "compile"   description = "Create jar and MANIFEST.MF" >   
    2.   
    3.   <!-- create a property containing all .jar files, prefix lib/, and seperated with a space -->   
    4.   < pathconvert   property = "libs.project"   pathsep = " " >   
    5.     < mapper >   
    6.       < chainedmapper >   
    7.   
    8.         <!-- remove absolute path -->   
    9.         < flattenmapper   />   
    10.   
    11.         <!-- add lib/ prefix -->   
    12.         < globmapper   from = "*"   to = "lib/*"   />   
    13.       </ chainedmapper >   
    14.     </ mapper >   
    15.   
    16.     < path >   
    17.   
    18.       <!-- lib.home contains all jar files, in several subdirectories -->   
    19.       < fileset   dir = "${lib.home}" >   
    20.         < include   name = "**/*.jar"   />   
    21.       </ fileset >   
    22.     </ path >   
    23.   </ pathconvert >   
    24.   
    25.   <!-- create the jar -->   
    26.   < jar   jarfile = "${build.home}/${jar.name}"   basedir = "${build.home}/classes" >   
    27.   
    28.     <!-- define MANIFEST.MF -->   
    29.     < manifest >   
    30.       < attribute   name = "Built-By"   value = "${user.name}"   />   
    31.       < attribute   name = "Main-Class"   value = "my.path.to.the.main.Application"   />   
    32.       < section   name = "common" >   
    33.         < attribute   name = "Specification-Title"   value = "${component.name}"   />   
    34.         < attribute   name = "Specification-Version"   value = "${component.version}"   />   
    35.         < attribute   name = "Specification-Vendor"   value = "${component.vendor}"   />   
    36.         < attribute   name = "Implementation-Title"   value = "${component.name}"   />   
    37.         < attribute   name = "Implementation-Version"   value = "${component.version} ${TODAY}"   />   
    38.         < attribute   name = "Implementation-Vendor"   value = "${component.vendor}"   />   
    39.       </ section >   
    40.   
    41.       <!-- finally, use the magically generated libs path -->   
    42.       < attribute   name = "Class-Path"   value = "${libs.project}"   />   
    43.     </ manifest >   
    44.   </ jar >   
    45. </ target >   
    <target name="jar" depends="compile" description="Create jar and MANIFEST.MF">
    
      <!-- create a property containing all .jar files, prefix lib/, and seperated with a space -->
      <pathconvert property="libs.project" pathsep=" ">
        <mapper>
          <chainedmapper>
    
            <!-- remove absolute path -->
            <flattenmapper />
    
            <!-- add lib/ prefix -->
            <globmapper from="*" to="lib/*" />
          </chainedmapper>
        </mapper>
    
        <path>
    
          <!-- lib.home contains all jar files, in several subdirectories -->
          <fileset dir="${lib.home}">
            <include name="**/*.jar" />
          </fileset>
        </path>
      </pathconvert>
    
      <!-- create the jar -->
      <jar jarfile="${build.home}/${jar.name}" basedir="${build.home}/classes">
    
        <!-- define MANIFEST.MF -->
        <manifest>
          <attribute name="Built-By" value="${user.name}" />
          <attribute name="Main-Class" value="my.path.to.the.main.Application" />
          <section name="common">
            <attribute name="Specification-Title" value="${component.name}" />
            <attribute name="Specification-Version" value="${component.version}" />
            <attribute name="Specification-Vendor" value="${component.vendor}" />
            <attribute name="Implementation-Title" value="${component.name}" />
            <attribute name="Implementation-Version" value="${component.version} ${TODAY}" />
            <attribute name="Implementation-Vendor" value="${component.vendor}" />
          </section>
    
          <!-- finally, use the magically generated libs path -->
          <attribute name="Class-Path" value="${libs.project}" />
        </manifest>
      </jar>
    </target>
    
  3. Finally we need to create a distribution by copying all .jar files into dist/lib while using a flat directory structure:
    1. < target   name = "dist"   depends = "jar"   description = "Create binary distribution" >   
    2.   < delete   dir = "${dist.home}"   />   
    3.   
    4.   <!-- contains all library dependencies -->   
    5.   < mkdir   dir = "${dist.home}/lib"   />   
    6.   
    7.   < copy   todir = "${dist.home}"   file = "${build.home}/${jar.name}"   />   
    8.   
    9.   < copy   todir = "${dist.home}/lib"   filtering = "off" >   
    10.   
    11.     <!-- remove the directory hierarchy: lib contains no subdirectories -->   
    12.     < flattenmapper   />   
    13.     < fileset   dir = "${lib.home}"   includes = "**/*.jar"   />   
    14.   </ copy >   
    15. </ target >   
    <target name="dist" depends="jar" description="Create binary distribution">
      <delete dir="${dist.home}" />
    
      <!-- contains all library dependencies -->
      <mkdir dir="${dist.home}/lib" />
    
      <copy todir="${dist.home}" file="${build.home}/${jar.name}" />
    
      <copy todir="${dist.home}/lib" filtering="off">
    
        <!-- remove the directory hierarchy: lib contains no subdirectories -->
        <flattenmapper />
        <fileset dir="${lib.home}" includes="**/*.jar" />
      </copy>
    </target>
    

I use Ant 1.6.2, and this works perfectly for me. Have fun!

你可能感兴趣的:(log4j,ant)