<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
    maven很強大,但是總有些事情干起來不是得心應手,沒有使用ant時那種想怎么干就怎么干的流暢感。尤其當要打包一個特殊(相對maven的標準架構而且)時,常有不知所措的感覺。當然這個應該和自己對maven的了解不夠有關,畢竟,“初學maven”嘛。

        但是maven在依賴管理方面實在是太強大了,太喜歡,退回原來的ant方式完全不可能,我想用過maven的人,一般是不會有回到原來在cvs,subversion中checkin/checkout n個jar包的時代,僅此一項理由就足夠繼續堅持使用maven了。

        然而ant的靈活又難于忘懷,尤其是從ant的build.xml一路走來的人,總是回不知不覺間想到ant的美好。魚與熊掌,我都想要。最近想打包一個java應用,很簡單但即不是標準的j2ee appication也不是web application, 用maven完全不知道該怎么打包,package出來的完全不是我想要的,在網上四處google maven資料的時候,總有用回ant拉倒的沖動。

        先交代一下背景吧,我要打包的程序,是這個樣子:

        demo1
        |____lib
        |_____demo1.jar
        |_____*****.jar
        |_____*****.jar
        |____config
        |_____*****.properties
        |_____*****.xml
        |____log
        |_____*****.log
        |____run.bat
        |____run.sh

        這個應用的打包模式很簡單,一個bat或者sh腳本用來執行,lib目錄下存放所有的jar包,包括自己的源代碼編譯打包的jar和第三方包。config下是配置文件,這些文件需要在安裝時或者運行前修改,比如監聽的端口啊,數據庫信息之類的。log目錄存放日志文件。最后打包的產物是一個zip包(或者tar,tar.gz)。

        遇到的問題,就是maven標準的打包方式中根本不考慮類似的情況,什么jar,ear,war完全不適用。而且maven有些理念也詫異,比如maven標準的config目錄是src/main/config,但是這個目錄里面的配置文件默認會打包到jar包中,暈,都在jar里面了還讓人怎么改啊?
       
        本著盡量只用maven不用ant的想法,我在maven的資料中看了好久,沒有找到解決的方法。暈,難道大家都只打包標準的ear,jar,war,只有我這樣無聊的人才會有這種打包的需求?

        幾經尋覓和探索,最后發現,maven ant tasks似乎是一個不錯的選擇。帶著mavenanttasks的官方文檔和google上搜到的幾篇文章,開始嘗試,成功實現功能。現在將過程和方法share給大家。

        首先建立java項目anttaskdemo1,按照maven的推薦,文件結構如下:

        anttaskdemo1
        |____src/main/java
        |____src/main/config
        |____src/main/bin
        |____src/main/resources
        |____src/test/java
        |____src/test/resources
        |____target
        |____build.properties
        |____build.xml
        |____pom.xml

        其中src/main/java下放java代碼;src/main/resources下放一個*.properties文件,這個資源文件是打包到jar中,內容打包之后不需要改變的。src/main/config下放一個標準的log4j.xml,這個是有在安裝運行前臨時修改的需要的。src/main/bin下放置可執行文件。

        1. 首先看pom.xml,標準內容,很簡單,象征性的加入幾個依賴
          
    <dependency>
                
    <groupId>commons-codec</groupId>
                
    <artifactId>commons-codec</artifactId>
                
    <version>1.3</version>
            
    </dependency>
            
    <dependency>
                
    <groupId>log4j</groupId>
                
    <artifactId>log4j</artifactId>
                
    <version>1.2.13</version>
                
    <scope>compile</scope>
            
    </dependency>
            
    <dependency>
                
    <groupId>org.testng</groupId>
                
    <artifactId>testng</artifactId>
                
    <version>5.8</version>
                
    <scope>test</scope>
                
    <classifier>jdk15</classifier>
            
    </dependency>

        其中commons-codec,log4j是需要打包到lib中的,運行時需要。testng(或者更一般的junit)是用來單元測試的,不需要打包到lib中。請注意它的設置"<scope>test</scope>"。

        2. 然后看看build.properties文件,這個內容不多:
       
    M2_REPO=G:/soft/maven/localRepository

    path.package=package
    path.target.name=anttaskdemo1
    path.package.lib=lib
    path.package.log=log
    path.package.config=config
    path.package.bin=

       
        M2_REPO稍后再詳談,后面的path.package之類的是最終打包時使用的幾個目錄名稱,對應于最終打包的結構。

        3. build.xml,這個內容比較多。

       
    <?xml version="1.0" encoding="UTF-8"?>
    <project name="demo" default="all" xmlns:artifact="urn:maven-artifact-ant">
        
    <description>
        
    </description>
        
    <property file="build.properties" />

        
    <target name="init_maven">
            
    <!--
            remember to set M2_REPO before use this build.xml, for example in eclispe:
            "Window→Preferences→Ant→Runtime", add a new property named "M2_REPO" and set it value point to the path of your maven
            local repository; Or you can set it in build.properties.  You need do one (and only one) of them.
            
    -->
            
    <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
            
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />

            
    <artifact:pom id="maven.project" file="pom.xml" />
            
    <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
                
    <pom refid="maven.project" />
            
    </artifact:dependencies>
            
    <artifact:dependencies pathId="classpath.runtime" filesetid="maven.fileset.runtime" useScope="runtime">
                
    <pom refid="maven.project" />
            
    </artifact:dependencies>
        
    </target>

        
    <target name="all" depends="init_path, compile, jar, package, zip" description="do all">
            
    <echo>begin to do all target to build the result package.</echo>
        
    </target>

        
    <target name="maven_info" depends="init_maven">
            
    <echo>Maven build directory is ${maven.project.build.directory}</echo>
            
    <echo>Maven build finalName is ${maven.project.build.finalName}</echo>
            
    <echo>Maven build sourceDirectory directory is ${maven.project.build.sourceDirectory}</echo>
            
    <echo>Maven build outputDirectory directory is ${maven.project.build.outputDirectory}</echo>
            
    <echo>Maven build scriptSourceDirectory directory is ${maven.project.build.testSourceDirectory}</echo>
            
    <echo>Maven build testOutputDirectory directory is ${maven.project.build.testOutputDirectory}</echo>
            
    <echo>Maven build scriptSourceDirectory directory is ${maven.project.build.scriptSourceDirectory}</echo>
            
    <echo>Maven build resourceDirectory directory is ${maven.project.build.resources}</echo>

            
    <property name="target.jar.name" value="${maven.project.build.directory}/${maven.project.build.finalName}.jar" />
            
    <echo>Maven build scriptSourceDirectory directory is ${target.jar.name}</echo>
        
    </target>

        
    <target name="clean" depends="init_maven">
            
    <echo>clean build directory : ${maven.project.build.directory}</echo>
            
    <delete dir="${maven.project.build.directory}" includes="**/*" />
        
    </target>

        
    <target name="init_path" depends="maven_info, clean">
            
    <echo>make dir for java compile: ${maven.project.build.outputDirectory}</echo>
            
    <mkdir dir="${maven.project.build.outputDirectory}" />
        
    </target>

        
    <target name="compile" description="description" depends="init_maven">
            
    <javac srcdir="${maven.project.build.sourceDirectory}" destdir="${maven.project.build.outputDirectory}" classpathref="classpath.build" />
        
    </target>
        
    <target name="copyResource" depends="init_maven">
            
    <copy todir="${maven.project.build.outputDirectory}">
                
    <fileset dir="src/main/resources">
                
    </fileset>
            
    </copy>
        
    </target>

        
    <target name="jar" depends="compile, copyResource">
            
    <delete file="${maven.project.build.directory}/${maven.project.build.finalName}.jar"  failonerror="false" />
            
    <jar destfile="${maven.project.build.directory}/${maven.project.build.finalName}.jar" basedir="${maven.project.build.outputDirectory}">
            
    </jar>
        
    </target>

        
    <target name="package" depends="package_prepare, copyLib, copyConfig, copyBin">
        
    </target>

        
    <target name="package_prepare" depends="init_maven">
            
    <echo>clean package directory : ${maven.project.build.directory}/${path.package}</echo>
            
    <delete dir="${maven.project.build.directory}/${path.package}" />
            
    <mkdir dir="${maven.project.build.directory}/${path.package}" />
            
    <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}" />
            
    <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}" />
            
    <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}" />
            
    <mkdir dir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.log}" />
        
    </target>

        
    <target name="copyLib" depends="init_maven">
            
    <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}">
                
    <fileset refid="maven.fileset.runtime" />
                
    <mapper type="flatten" />
            
    </copy>
            
    <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.lib}"
                file
    ="${maven.project.build.directory}/${maven.project.build.finalName}.jar">

            
    </copy>
        
    </target>
        
    <target name="copyConfig" depends="init_maven">
            
    <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.config}">
                
    <fileset dir="src/main/config">
                
    </fileset>
            
    </copy>
        
    </target>
        
    <target name="copyBin" depends="init_maven">
            
    <copy todir="${maven.project.build.directory}/${path.package}/${path.target.name}/${path.package.bin}">
                
    <fileset dir="src/main/bin">
                
    </fileset>
            
    </copy>
        
    </target>
        
    <target name="zip" depends="init_maven">
            
    <zip destfile="${maven.project.build.directory}/${path.package}/${path.target.name}.zip">
                
    <fileset dir="${maven.project.build.directory}/${path.package}/${path.target.name}"></fileset>
            
    </zip>
        
    </target>
    </project>

        一步一步來講吧:

        3.1 最重要的一步,init_maven

        <target name="init_maven">
            
    <!--
            remember to set M2_REPO before use this build.xml, for example in eclispe:
            "Window→Preferences→Ant→Runtime", add a new property named "M2_REPO" and set it value point to the path of your maven
            local repository; Or you can set it in build.properties.  You need do one (and only one) of them.
            
    -->
            
    <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
            
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />

            
    <artifact:pom id="maven.project" file="pom.xml" />
            
    <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
                
    <pom refid="maven.project" />
            
    </artifact:dependencies>
            
    <artifact:dependencies pathId="classpath.runtime" filesetid="maven.fileset.runtime" useScope="runtime">
                
    <pom refid="maven.project" />
            
    </artifact:dependencies>
        
    </target>


        在ant中使用maven-ant-tasks,就需要裝載maven-ant-tasks的jar包,方法有兩種,一種是直接將maven-ant-tasks-2.0.9.jar放到ant的lib下,自然就可以直接使用。但是個人感覺不怎么喜歡這種方式,我采用的是第二種,在ant的build.xml文件中裝載:

            <path id="maven-ant-tasks.classpath" path="${M2_REPO}/org/apache/maven/maven-ant-tasks/2.0.9/maven-ant-tasks-2.0.9.jar" />
            
    <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />


        這樣就可以在后面使用maven-ant-tasks的task,比如artifact:pom,artifact:dependencies。<path />用于指定maven-ant-tasks-2.0.9.jar的路徑,這里就有點麻煩了:maven-ant-tasks-2.0.9.jar這個東西放哪里好呢?直接放到項目中,然后存放到cvs/svn?顯然不是一個好辦法。考慮到maven本來就是干保存jar這行的,交給maven好了。maven-ant-tasks-2.0.9.jar本來就是一個依賴,可以在http://mvnrepository.com/找到:
        http://mvnrepository.com/artifact/org.apache.maven/maven-ant-tasks
        pom內容如下:
        <dependency>
        
    <groupId>org.apache.maven</groupId>
        
    <artifactId>maven-ant-tasks</artifactId>
        
    <version>2.0.9</version>
    </dependency>

        將這個內容隨便找個空項目,加入后update一下dependency,在本地的maven repository中就會有它的jar文件。然后就可以直接使用它。
        ${M2_REPO},這個是eclipse中通用的指向maven local repository的變量,大家使用maven命令建立eclipse項目時會遇到它。我們在這里可以直接使用這個變量來訪問maven local repository。如果沒有建立這個變量,請自行建立,上面注釋中有詳細說明。如果在eclispe之外比如命令行直接運行ant打包,則可以通過設置build.properties文件中的“M2_REPO=G:/soft/maven/localRepository”來指定。(這里用到ant的一個特性,屬性一旦被賦值就不能修改,因此第一次賦值有效,在eclispe中運行,M2_REPO會使用eclispe中設置的值,如果eclispe沒有設置或者命令行直接運行,M2_REPO屬性會在build.properties文件裝載時設置。)

        裝載ok后,接著是調用artifact:pom和artifact:dependencies 任務來指定pom.xml文件,再得到dependencies信息,后面的編譯打包會使用到。注意useScope="runtime",這個是為了最后打包時使用,只復制runtie時需要的jar包。

        <target name="maven_info" />是用來打印maven相關的一些信息的,比如maven下的幾個build目錄。artifact:pom任務裝載了整個pom,因此在后面可以訪問到pom的信息,比如${maven.project.build.sourceDirectory}是java源代碼目錄,${maven.project.build.finalName}是最終的名稱。

        pom的內容可以參考這兩個官方資料:

        1) maven model
            http://maven.apache.org/ref/2.0.9/maven-model/maven.html

        2) Introduction to the POM
            http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

        標準目錄布局可以參考這個官方資料:

            http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

        3.2 compile

            這里是maven ant task的精髓所在,
        <target name="compile" description="description" depends="init_maven">
            
    <javac srcdir="${maven.project.build.sourceDirectory}" destdir="${maven.project.build.outputDirectory}" classpathref="classpath.build" />
        
    </target>

            結合之前maven初始化時的情況:
            <artifact:pom id="maven.project" file="pom.xml" />
            
    <artifact:dependencies pathId="classpath.build" filesetid="maven.fileset.build">
                
    <pom refid="maven.project" />
            
    </artifact:dependencies>


        可以看到,我們的項目完全遵循maven的標準做法,然后ant通過訪問pom來得到相關的路徑信息和classpath信息,完美結合。
        target copyResource 完成了將resource copy到outputDirectory的任務,這里的resource都是classpath resource。
        注: 這個有個問題,就是我沒有找到通過pom得到resouce目錄的方法,${maven.project.build.resources 只能得到pom文件中<resources/>, 對于里面包含的<resource>不知道該用什么方式來訪問,如默認的:
        <resources>
          
    <resource>
            
    <directory>src/main/resources</directory>
          
    </resource>
        
    </resources>

        我試過用${maven.project.build.resources[0];${maven.project.build.resources(0), ${maven.project.build.resources.0,${maven.project.build.resources.resource
    等都無效。找了很久都沒有找到資料,只好作罷。直接寫死src/main/resources吧。

        3.3 jar
            和compile類似,標準的ant jar,然后通過訪問pom來得到相關的路徑信息和打包文件名。注意這里的文件名和路徑和maven的做法一致,也就是說和執行maven的compile命令結果是一樣的。
        <target name="jar" depends="compile, copyResource">
            
    <delete file="${maven.project.build.directory}/${maven.project.build.finalName}.jar"  failonerror="false" />
            
    <jar destfile="${maven.project.build.directory}/${maven.project.build.finalName}.jar" basedir="${maven.project.build.outputDirectory}">
            
    </jar>
        
    </target>


        3.4 package, zip
        package_prepare, copyLib, copyConfig, copyBin 這幾個target都簡單,體力活而已。zip也是。

       
        4. 總結
       
            上面的內容雖多,但是總結起來就只有兩點:
        1. maven ant task可以將maven的功能和ant的靈活性統一起來,對于非標準的打包情況非常適用
        2. maven ant task的使用并不難,不過需要掌握不少maven的基本知識,比如pom,標準目錄布局等。

            另外,似乎,ant + Ivy會是更好的選擇?
    posted on 2009-01-05 23:27 禮物 閱讀(2018) 評論(0)  編輯  收藏 所屬分類: Maven2
    主站蜘蛛池模板: 亚洲av永久无码| 亚洲综合国产精品| 曰批视频免费40分钟试看天天| 精品亚洲福利一区二区| 免费一级毛片正在播放| 成年大片免费视频播放一级| 亚洲国产日韩女人aaaaaa毛片在线| 亚洲天堂免费在线视频| 成人A片产无码免费视频在线观看| 亚洲日韩精品A∨片无码加勒比| 久久精品7亚洲午夜a| 久久精品国产亚洲Aⅴ蜜臀色欲| 成人片黄网站色大片免费观看cn| 亚洲国产精品精华液| 亚洲精品国产成人影院| 午夜一级免费视频| 久久免费99精品国产自在现线 | 久久久久亚洲AV无码专区体验| 亚洲午夜无码AV毛片久久| 啊灬啊灬别停啊灬用力啊免费看| 亚洲免费福利在线视频| 亚洲三级在线免费观看| 男人免费视频一区二区在线观看| 亚洲欧美日韩中文二区| 亚洲精品国产日韩| 亚洲无吗在线视频| 亚洲人成亚洲人成在线观看| www.亚洲色图.com| 免费a在线观看播放| 又粗又硬又黄又爽的免费视频| 国内自产拍自a免费毛片| 性感美女视频免费网站午夜 | 国产亚洲综合网曝门系列| 久久久久国产亚洲AV麻豆| 亚洲一本大道无码av天堂| 亚洲一区二区高清| 亚洲人成网77777色在线播放| 亚洲热线99精品视频| 亚洲国产精品国自产拍电影| 亚洲高清免费视频| 日韩精品福利片午夜免费观着|