一個(gè)簡單的Ant的build.xml示例(附:jar包的正確運(yùn)行方法)

               以前在寫作業(yè)時(shí)曾經(jīng)嘗試用過Ant去編譯和運(yùn)行Java程序,不過后來好久沒用,都不怎么會(huì)用了。下邊是前幾天寫的一個(gè)build.xml文件的例子,以后可以拿來當(dāng)參照了,不過有點(diǎn)小問題還不知道怎么改!以前忘了Jar包的正確運(yùn)行方式,導(dǎo)致不能正確運(yùn)行打包以后的jar包,現(xiàn)已更正!

                說明:lib目錄存放第三方類庫,src目錄存放待編譯的Java源文件!

          <?xml version="1.0" encoding="GB2312" ?>

          <!DOCTYPE project>

          <project name="JavaMailClient" default="usage" basedir=".">
                <property name="project-name" value="JavaMailClient"/>

                <property name="build" value="build"/>
                <property name="lib" value="lib"/>
                <property name="src" value="src"/>
                <property name="build.classes"      value="${build}/classes" />
                <property file="build.properties"/>
           

                <property name="jar.dir"     value="jar"/>
                <property name="jar-file-name"      value="${project-name}" />

                <path id="Third-Part Lib">
                      <fileset dir="${lib}">
                            <include name="**/*.jar" />
                      </fileset>
                </path>
           
                <target name="usage" description="Build file usage info (default task)">
                      <echo message=" " />
                      <echo message="${project-name} " />
                      <echo message="-------------------------------------------------------" />
                      <echo message="Available Targets:" />
                      <echo message=" ***" />
                      <echo message=" Compiling:" />
                      <echo message="  compile  - Compiles the source code" />
                      <echo message=" ***" />
                      <echo message=" Cleaning up:" />
                      <echo message="  clean - Delete class files" />
                      <echo message=" ***" />
                      <echo message=" JAR:" />
                      <echo message="  jar  - Generate an .jar for source code" />
                      <echo message=" ***" />
                      <echo message=" Executing:" />
                      <echo message="  run  - Execute the  JavaMail client ! Get email of the latest two days  from server" />
                      <echo message=" ***" />
                      <echo message="-------------------------------------------------------" />
                </target>

                <target name="prepare" >
                      <mkdir dir="${build.classes}" />
                      <mkdir dir="${jar.dir}" />
                </target>

                <target name="clean" >
                      <delete dir="${build}" />
                      <delete dir="${jar.dir}" />
                </target>
           
                <target name="compile" depends="clean,prepare">
                <echo message="Compiling the source code!"/>
                      <javac
                            srcdir="${src}"
                            destdir="${build.classes}"
                            deprecation="true"
                            failonerror="true" debug="true"
                            >
                            <classpath refid="Third-Part Lib"/> 
                      </javac>
                </target>


                <!-- <target name="run" description="Receive email! "  depends="compile"> -->
                <!-- 已經(jīng)可以正確運(yùn)行!注意:classpath="${build.classes}" 一定要加上,否則會(huì)報(bào)"java.lang.NoClassDefFoundError"的錯(cuò)誤!-->
                <!--
                <target name="run" description="Receive email! ">
                      <java classname="POP3MailReceiver" classpath="${build.classes}" fork="true" maxmemory="256m">
                            <classpath refid="Third-Part Lib"/> 
                      </java>
                </target>
                -->

                
                <target name="run"  description="Receive email! ">
                      <java jar="${jar.dir}/${jar-file-name}.jar" fork="true" maxmemory="256m"/>
                </target>

                <target name="jar" depends="compile">
                      <jar destfile="${jar.dir}/${jar-file-name}.jar" basedir="${build.classes}">
                            <manifest>
                                  <!-- 此處需要根據(jù)需要進(jìn)行修改 -->
                                  <attribute name="Main-Class" value="POP3MailReceiver"/>
                                  <attribute name="Class-Path" value="../${lib}/commons-email-1.0.jar ../${lib}/mail.jar ../${lib}/activation.jar"/>
                            </manifest>
                      </jar>
                </target>
          </project>


          附:Jar包的正確運(yùn)行方法(轉(zhuǎn))

          -jar參數(shù)運(yùn)行應(yīng)用時(shí)classpath的設(shè)置方法 

                 你是否在使用java -jar參數(shù)運(yùn)行打包好的jar應(yīng)用程序的時(shí)候發(fā)現(xiàn)應(yīng)用程序無法找到classpath下設(shè)置好的第三方類庫的內(nèi)容?無論怎么設(shè)置classpath參數(shù)都無濟(jì)于事,總是會(huì)報(bào)ClassNotFound的錯(cuò)誤?那么本篇帖子可以幫助你擺脫煩惱 :)
                當(dāng)用java -jar yourJarExe.jar來運(yùn)行一個(gè)經(jīng)過打包的應(yīng)用程序的時(shí)候,你會(huì)發(fā)現(xiàn)如何設(shè)置-classpath參數(shù)應(yīng)用程序都找不到相應(yīng)的第三方類,報(bào)ClassNotFound錯(cuò)誤。實(shí)際上這是由于當(dāng)使用-jar參數(shù)運(yùn)行的時(shí)候,java VM會(huì)屏蔽所有的外部classpath,而只以本身yourJarExe.jar的內(nèi)部class作為類的尋找范圍。

          解決方案

          一 BootStrap class擴(kuò)展方案
                Java 命令行提供了如何擴(kuò)展bootStrap 級別class的簡單方法:
                      -Xbootclasspath:     完全取代基本核心的Java class 搜索路徑.
                                             不常用,否則要重新寫所有Java 核心class
                      -Xbootclasspath/a: 后綴在核心class搜索路徑后面.常用!!
                      -Xbootclasspath/p: 前綴在核心class搜索路徑前面.不常用,避免
                                             引起不必要的沖突.
          語法如下:
           (分隔符與classpath參數(shù)類似,unix使用:號,windows使用;號,這里以unix為例)
           java -Xbootclasspath/a:/usrhome/thirdlib.jar: -jar yourJarExe.jar

          二 extend class 擴(kuò)展方案
                Java exten class 存放在{Java_home}\jre\lib\ext目錄下.當(dāng)調(diào)用Java時(shí),對擴(kuò)展class路徑的搜索是自動(dòng)的.總會(huì)搜索的.這樣,解決的方案就很簡單了,將所有要使用的第三方的jar包都復(fù)制到ext 目錄下.
                (自評:不推薦使用,自適應(yīng)性很差?。?/font>

          三 User class擴(kuò)展方案
               
          當(dāng)使用-jar執(zhí)行可執(zhí)行Jar包時(shí),JVM將Jar包所在目錄設(shè)置為codebase目錄,所有的class搜索都在這個(gè)目錄下開始.所以如果使用了其他第三方的jar包,一個(gè)比較可以接受的可配置方案,就是利用jar包的Manifest擴(kuò)展機(jī)制.
          步驟如下:
          1.將需要的第三方的jar包,復(fù)制在同可執(zhí)行jar所在的目錄或某個(gè)子目錄下. 比如:jar 包在 /usrhome/yourJarExe.jar 那么你可以把所有jar包復(fù)制到/usrhome目錄下或/usrhome/lib 等類似的子目錄下.
          2.修改Manifest 文件
           在Manifest.mf文件里加入如下行
           Class-Path:classes12.jar lib/thirdlib.jar
           Class-Path 是可執(zhí)行jar包運(yùn)行依賴的關(guān)鍵詞.詳細(xì)內(nèi)容可以參考:http://java.sun.com/docs/books/tutorial/ext/index.html


                以上三種方法推薦第一種,擴(kuò)展性好,操作起來也最方便.
                另外編寫自己的ClassLoader,來動(dòng)態(tài)載入class,是更加復(fù)雜和高級技術(shù).限于篇幅,不贅述.有興趣了解可以去google一下custom classloader

                Java的安全機(jī)制隨不同的JDK版本有不同的變化,會(huì)影響很多核心CLASS,比如Thread,所以很多大型商業(yè)軟件,要求JDK的版本很嚴(yán)格.部分原因也在此.這也要求在發(fā)布自己編寫的應(yīng)用時(shí)候,不管大小,都要說明開發(fā)和測試的JDK版本.


          本文所述方法測試基于j2sdk 1.4.2_04-b05

          ----------------------------------------------------------------------------------------------

          附:背景知識(shí)

                自JDK 1.2以后,JVM采用了委托(delegate)模式來載入class.采用這種設(shè)計(jì)的原因可以參考http://java.sun.com/docs/books/tutorial/ext/basics/load.html

                歸納來講:是基于JVM sandbox(沙盒)安裝模型上提供應(yīng)用層的可定制的安全機(jī)制.

                Java虛擬機(jī)(JVM)尋找Class的順序

          1. Bootstrap classes

          屬于Java 平臺(tái)核心的class,比如java.lang.String等.及rt.jar等重要的核心級別的class.這是由JVM Bootstrap class loader來載入的.一般是放置在{java_home}\jre\lib目錄下

          2. Extension classes

          基于Java擴(kuò)展機(jī)制,用來擴(kuò)展Java核心功能模塊.比如Java串口通訊模塊comm.jar.一般放置在{Java_home}\jre\lib\ext目錄下

          3. User classes

          開發(fā)人員或其他第三方開發(fā)的Java程序包.通過命令行的-classpath或-cp,或者通過設(shè)置CLASSPATH環(huán)境變量來引用.JVM通過放置在{java_home}\lib\tools.jar來尋找和調(diào)用用戶級的class.常用的javac也是通過調(diào)用tools.jar來尋找用戶指定的路徑來編譯Java源程序.這樣就引出了User class路徑搜索的順序或優(yōu)先級別的問題.

           3.1 缺省值:調(diào)用Java或javawa的當(dāng)前路徑(.),是開發(fā)的class所存在的當(dāng)前目錄
           3.2 CLASSPATH環(huán)境變量設(shè)置的路徑.如果設(shè)置了CLASSPATH,則CLASSPATH的值會(huì)覆蓋缺省值
           3.3 執(zhí)行Java的命令行-classpath或-cp的值,如果制定了這兩個(gè)命令行參數(shù)之一,它的值會(huì)覆蓋環(huán)境變量CLASSPATH的值
           3.4 -jar 選項(xiàng):如果通過java -jar 來運(yùn)行一個(gè)可執(zhí)行的jar包,這當(dāng)前jar包會(huì)覆蓋上面所有的值.換句話說,-jar 后面所跟的jar包的優(yōu)先級別最高,如果指定了-jar選項(xiàng),所有環(huán)境變量和命令行制定的搜索路徑都將被忽略.JVM APPClassloader將只會(huì)以jar包為搜索范圍.
          有關(guān)可執(zhí)行jar有許多相關(guān)的安全方面的描述,可以參考http://java.sun.com/docs/books/tutorial/jar/ 來全面了解.

          這也是為什么應(yīng)用程序打包成可執(zhí)行的jar包后,不管你怎么設(shè)置classpath都不能引用到第三方j(luò)ar包的東西了.
           

          posted on 2008-01-08 18:43 靈! 閱讀(5597) 評論(1)  編輯  收藏 所屬分類: Java專題-部署打包

          評論

          # re: 一個(gè)簡單的Ant的build.xml示例(附:jar包的正確運(yùn)行方法) 2014-01-22 23:19 xyy

          謝謝  回復(fù)  更多評論   

          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          • 隨筆 - 53
          • 文章 - 0
          • 評論 - 3
          • 引用 - 0

          隨筆分類

          隨筆檔案

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 公安县| 盐边县| 竹山县| 新余市| 宜兰市| 宁化县| 丰宁| 科技| 桑日县| 裕民县| 平顺县| 垦利县| 中牟县| 铅山县| 阳新县| 临颍县| 沾化县| 独山县| 泰安市| 吉林市| 廊坊市| 镇巴县| 都匀市| 南陵县| 吉木萨尔县| 农安县| 龙海市| 葵青区| 来宾市| 舟山市| 金昌市| 汝阳县| 上林县| 安西县| 永康市| 宜丰县| 新干县| 灵宝市| 天台县| 万安县| 萝北县|