怎么使用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!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值