日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Ant 下载、安装、使用、教程全面了解「建议收藏」

發布時間:2023/12/24 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 Ant 下载、安装、使用、教程全面了解「建议收藏」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Eclipse 內置了 Ant 。 Ant 是一種類似于批處理程序的軟件包,它主要繁瑣的工作是編寫和調試自動處理腳本(一個 XML 文件),但只要有了這個腳本,我們就可以一鍵完成所有的設定工作。
本節還是以 myswt 這個應用程序項目的打包為例,用 Ant 來完成“編譯->打成 JAR 包->復制項目引用庫->復制本地化文件 swt-win32-3063.dll ->輸出 API 文檔”這五步。
1 、在 myswt 項目根目錄下,創建最主要的 build.xml 文件
<?xml version=1.0?>
<project name=myswt project default=api_doc>
<!– 定義目錄變量 –>
<property name=src.dir value=src />
<property name=bin.dir value=bin />
<property name=eclipse_plugins.dir value=c:/eclipse/plugins />
<property name=dist.dir value=d:/dist />
<property name=doc.dir value=${dist.dir}/api />
<property name=swt.dll value=swt-win32-3063.dll />
<!– 定義編譯文件時所引用的庫 –>
<path id=master-classpath>
<fileset dir=${eclipse_plugins.dir} id=project_lib>
<include name=org.eclipse.ui.workbench_3.0.1/workbench.jar/>
<include name=org.eclipse.swt.win32_3.0.1/ws/win32/swt.jar/>
<include name=org.eclipse.jface_3.0.0/jface.jar/>
<include name=org.eclipse.osgi_3.0.1/osgi.jar/>
<include name=org.eclipse.osgi_3.0.1/core.jar/>
<include name=org.eclipse.osgi_3.0.1/resolver.jar/>
<include name=org.eclipse.osgi_3.0.1/defaultAdaptor.jar/>
<include name=org.eclipse.osgi_3.0.1/eclipseAdaptor.jar/>
<include name=org.eclipse.osgi_3.0.1/console.jar/>
<include name=org.eclipse.core.runtime_3.0.1/runtime.jar/>
<include name=org.eclipse.jface.text_3.0.1/jfacetext.jar/>
<include name=org.eclipse.ui.workbench.compatibility_3.0.0/compatibility.jar/>
</fileset>
</path>

<!– 首任務(空) –>
<target name=init/>
<!– 編譯 –>
<target name=compile depends=init>
<delete dir=${bin.dir}/>
<mkdir dir=${bin.dir}/>
<!– 編譯源程序 –>
<javac srcdir=${src.dir} destdir=${bin.dir} target=1.4>
<classpath refid=master-classpath/>
</javac>
<!– 復制圖標目錄 –>
<mkdir dir=${bin.dir}/icons/>
<copy todir=${bin.dir}/icons>
<fileset dir=icons/>
</copy>
</target>
<!– 打包 –>
<target name=pack depends=compile>
<!– bin 目錄壓縮成 JAR 包 –>
<delete dir=${dist.dir}/>
<mkdir dir=${dist.dir} />
<jar basedir=${bin.dir} destfile=${dist.dir}/myswt.jar manifest=ant_manifes.txt>
<exclude name=**/*Test.* />
<exclude name=**/Test*.* />
</jar>
<!– 復制用到的庫 –>
<mkdir dir=${dist.dir}/lib />
<copy todir=${dist.dir}/lib>
<fileset refid=project_lib/>
</copy>
<!– 復制本地化文件 –>
<copy todir=${dist.dir} file=${swt.dll}/>
</target>
<!– 輸出 api 文檔 –>
<target name=api_doc depends=pack>
<delete dir=${doc.dir}/>
<mkdir dir=${doc.dir} />
<javadoc destdir=${doc.dir} author=true version=true use=true windowtitle=MySWT API>
<packageset dir=${src.dir} defaultexcludes=yes/>
<doctitle><![CDATA[<h1>MySWT Project</h1>]]></doctitle>
<bottom><![CDATA[<i>Document by ChenGang 2005.</i>]]></bottom>
</javadoc>
</target>
</project>
代碼說明:
( 1 ) property 項是定義變量,比如 <property name=swt.dll value=swt-win32-3063.dll /> ,就是定義一個變量: swt.dll=swt-win32-3063.dll 。以后用這個變量則是這樣: ${swt.dll} 。
一般盡量將今后可能會變動的目錄、文件等定義成變量,以方便維護。不象 Java 變量有類型的區分, Ant 變量是不區別目錄、文件等的,所以為了見名知意,在取變量名時,目錄都加“ dir ”后綴,這個后綴是可以任取名的。
下面給出本例用到的變量的含義:
l src.dir - Java 源文件路徑。 value=src 的 src 是一個相對路徑,它相對的是 build.xml 的所在目錄位置(即項目根目錄)。
l bin.dir - Java 編譯文件的輸出路徑
l eclipse_plugins.dir - eclipse 的 plugins 目錄
l dist.dir - 打包文件的存放目錄
l doc.dir - API 文檔的存放目錄,這里用到了 dist.dir 變量,直接寫 value=d:/dist/api 也未嘗不可。
l swt.dll - SWT 本地化文件。
( 2 ) <path id=master-classpath> ,定義編譯文件時所引用的庫,相當于 classpath 。 <fileset> 項表示一個文件集,再深入一層的 <include> 項,則表示此文件集下的文件,它們的路徑定位相對于 <fileset> 的 dir 屬性。 <fileset> 還有一個 id 屬性,在后面復制引用庫時會用到。
也許有讀者會問:“你是怎么知道要引用這些文件的?”回答:看項目根目錄下的“ .classpath ”文件,就可以知道本項目要引用那些庫了。實際上筆者是把 .classpath 復制一份后,然后用 Editplus 編輯而得。
( 3 )接下來開始定義一些任務。首任務一般都讓它為空(沒有具體任務內容): <target name=init/> 。
( 4 ) Ant 中的任務有著相互的依賴( depends )關系,這些依賴關系是通過 depends 屬性來定義的。當要執行一個任務時, Ant 先去執行這個任務的 depends 任務,……, Ant 就這樣一直往回找下去。比如:在本例的第二行 default=api_doc ,它定義了缺省任務是 api_doc (輸出 api 文檔)->此任務的 depends = pack (打包)-> pack 的 depends = compile (編譯)-> compile 的 depends=init (首任務), init 沒有 depends 。于是, Ant 就從 init 開始依次往回執行任務: init -> compile -> pack -> api_doc 。
如果你不想“輸出 api 文檔”,則將第二行的缺省任務定義成 default=pack 即可,這時整個任務鏈就拋開了 api_doc 。
( 5 ) <delete dir=${bin.dir}/> 刪除目錄。 <mkdir dir=${bin.dir}/> 新建目錄
( 6 )編譯源程序,如下
<javac srcdir=${src.dir} destdir=${bin.dir} target=1.4>
<classpath refid=master-classpath/>
</javac>
l srcdir - 源文件目錄,其子目錄中的源文件也會被 javac.exe 編譯。
l destdir - 編譯文件輸出目錄。
l target - 以 JDK1.4 為編譯目標。
l classpath - 編譯的 classpath 設置, refid 是指引用前面設定的 master-classpath 。
( 7 )將 icons (即 myswt/icons )目錄的文件,復制到 myswt/bin/icons 目錄中,如下:
<copy todir=${bin.dir}/icons>
<fileset dir=icons/>
</copy>
( 8 )將文件打成 JAR 包
<jar basedir=${bin.dir} destfile=${dist.dir}/myswt.jar manifest=ant_manifes.txt>
<exclude name=**/*Test.* />
<exclude name=**/Test*.* />
</jar>
l basedir - 源目錄。
l destfile - 目標目錄和打成 JAR 包名。
l manifest - 打包清單文件(后面給出其內容)。
l exclude - 使用了通配符將某一些文件排除不打包(主要是一些測試文件)。
( 9 )如下,將 project_lib 的文件復制到 d:/dist/lib 目錄中。 project_lib 是前面“定義編譯文件時所引用的庫”中的文件集的 id 。結果參數下圖 21.25
<copy todir=${dist.dir}/lib>
<fileset refid=project_lib/>
</copy>
( 10 )將本地化文件復制到 d:/dist 目錄中,如下:
<copy todir=${dist.dir} file=${swt.dll}/>
( 11 )輸出 API 文檔(結果參數下圖 21.26 )
<javadoc destdir=${doc.dir} author=true version=true use=true windowtitle=MySWT API>
<packageset dir=${src.dir} defaultexcludes=yes/>
<doctitle><![CDATA[<h1>MySWT Project</h1>]]></doctitle>
<bottom><![CDATA[<i>Document by ChenGang 2005.</i>]]></bottom>
</javadoc>
l destdir - 目標路徑 d:/dist/api
l packageset - 源文件目錄
l doctitle - 標題
l bottom - 標尾。
2 、創建打包清單
為了避免和原來的 manifes.txt 同名,在項目根目錄建立一個名為 ant_manifes.txt 的文件。這個文件內容中最長的是 Class-Path 項,沒有必要一個個字符的敲入,它可以由項目根目錄下的“ .classpath ”編輯而得。
ant_manifes.txt 內容如下:
Manifest-Version: 1.0
Main-Class: jface.dialog.wizard.WizardDialog1
Class-Path: ./lib/org.eclipse.ui.workbench_3.0.1/workbench.jar ./lib/org.eclipse.swt.win32_3.0.1/ws/win32/swt.jar
./lib/org.eclipse.jface_3.0.0/jface.jar ./lib/org.eclipse.osgi_3.0.1/osgi.jar ./lib/org.eclipse.osgi_
3.0.1/core.jar ./lib/org.eclipse.osgi_3.0.1/resolver.jar ./lib/org.eclipse.osgi_3.0.1/defaultAdaptor.ja
r ./lib/org.eclipse.osgi_3.0.1/eclipseAdaptor.jar ./lib/org.eclipse.osgi_3.0.1/console.jar ./lib/org.ecl
ipse.core.runtime_3.0.1/runtime.jar ./lib/org.eclipse.jface.text_3.0.1/jfacetext.jar ./lib/org.eclipse.u
i.workbench.compatibility_3.0.0/compatibility.jar
3 、如下圖 21.23 所示,選擇“ Ant 構建”來運行 Ant 。

圖 21.23 運行“ Ant 構建”
運行“ Ant 構建”后的結果如下圖 21.23 - 26 所示。

圖 21.24 控制臺的輸出

圖 21.25 輸出文件的目錄結構圖

圖 21.26 輸出的 API 文檔效果圖
4 、運行打包結果
除了清單文件 MANIFEST.MF 之外, myswt.jar 文件和 21.1 節所得的 myswt.jar 一樣。本節沒有創建 run.bat 批處理文件,而是用下圖 21.27 所示的“右擊 myswt.jar ->打開方式-> javaw ”的方式來運行 myswt.jar 。

圖 21.27 運行 myswt.jar

ant命令總結

1Ant是什么
ApacheAnt是一個基于Java的生成工具。
生成工具在軟件開發中用來將源代碼和其他輸入文件轉換為可執行文件的形式(也有可能轉換為可安裝的產品映像形式)。隨著應用程序的生成過程變得更加復雜,確保在每次生成期間都使用精確相同的生成步驟,同時實現盡可能多的自動化,以便及時產生一致的生成版本
2下載、安裝Ant
安裝Ant
下載.zip文件,解壓縮到c:/ant1.3(后面引用為%ANT_HOME%)

2.1在你運行Ant之前需要做一些配置工作。
?將bin目錄加入PATH環境變量。
?設定ANT_HOME環境變量,指向你安裝Ant的目錄。在一些OS上,Ant的腳本可以猜測ANT_HOME(Unix和WindosNT/2000)-但最好不要依賴這一特性。
?可選地,設定JAVA_HOME環境變量(參考下面的高級小節),該變量應該指向你安裝JDK的目錄。
注意:不要將Ant的ant.jar文件放到JDK/JRE的lib/ext目錄下。Ant是個應用程序,而lib/ext目錄是為JDK擴展使用的(如JCE,JSSE擴展)。而且通過擴展裝入的類會有安全方面的限制。
2.2運行Ant

運行Ant非常簡單,當你正確地安裝Ant后,只要輸入ant就可以了。

? 沒有指定任何參數時,Ant會在當前目錄下查詢build.xml文件。如果找到了就用該文件作為buildfile。如果你用-find選項。 Ant就會在上級目錄中尋找buildfile,直至到達文件系統的根。要想讓Ant使用其他的buildfile,可以用參數– buildfilefile,這里file指定了你想使用的buildfile。

?可以指定執行一個或多個target。當省略target時,Ant使用標簽<project>的default屬性所指定的target。

命令行選項總結:
ant[options][target[target2[target3]…]]
Options:
-helpprintthismessage
-projecthelpprintprojecthelpinformation
-versionprinttheversioninformationandexit
-quietbeextraquiet
-verbosebeextraverbose
-debugprintdebugginginformation
-emacsproducelogginginformationwithoutadornments
-logfilefileusegivenfileforlogoutput
-loggerclassnametheclassthatistoperformlogging
-listenerclassnameaddaninstanceofclassasaprojectlistener
-buildfilefileusespecifiedbuildfile
-findfilesearchforbuildfiletowardstherootofthefilesystemandusethefirstonefound
-Dproperty=valuesetpropertytovalue
例子
ant
使用當前目錄下的build.xml運行Ant,執行缺省的target。
ant-buildfiletest.xml
使用當前目錄下的test.xml運行Ant,執行缺省的target。
ant-buildfiletest.xmldist
使用當前目錄下的test.xml運行Ant,執行一個叫做dist的target。
ant-buildfiletest.xml-Dbuild=build/classesdist
使用當前目錄下的test.xml運行Ant,執行一個叫做dist的target,并設定build屬性的值為build/classes。

3編寫build.xml

Ant的buildfile是用XML寫的。每個buildfile含有一個project。

buildfile中每個task元素可以有一個id屬性,可以用這個id值引用指定的任務。這個值必須是唯一的。(詳情請參考下面的Task小節)

3.1Projects

project有下面的屬性:
AttributeDescriptionRequired
name項目名稱.No
default當沒有指定target時使用的缺省targetYes
basedir用于計算所有其他路徑的基路徑。該屬性可以被basedirproperty覆蓋。當覆蓋時,該屬性被忽略。如果屬性和basedirproperty都沒有設定,就使用buildfile文件的父目錄。No
項目的描述以一個頂級的<description>元素的形式出現(參看description小節)。

一個項目可以定義一個或多個target。一個target是一系列你想要執行的。執行Ant時,你可以選擇執行那個target。當沒有給定target時,使用project的default屬性所確定的target。

3.2Targets

一個target可以依賴于其他的target。例如,你可能會有一個target用于編譯程序,一個target用于生成可執行文件。你在生成可執行文件之前必須先編譯通過,所以生成可執行文件的target依賴于編譯target。Ant會處理這種依賴關系。

然而,應當注意到,Ant的depends屬性只指定了target應該被執行的順序-如果被依賴的target無法運行,這種depends對于指定了依賴關系的target就沒有影響。

Ant會依照depends屬性中target出現的順序(從左到右)依次執行每個target。然而,要記住的是只要某個target依賴于一個target,后者就會被先執行。
<targetname=”A”/>
<targetname=”B”depends=”A”/>
<targetname=”C”depends=”B”/>
<targetname=”D”depends=”C,B,A”/>
假定我們要執行targetD。從它的依賴屬性來看,你可能認為先執行C,然后B,最后A被執行。錯了,C依賴于B,B依賴于A,所以先執行A,然后B,然后C,最后D被執行。

一個target只能被執行一次,即時有多個target依賴于它(看上面的例子)。

如果(或如果不)某些屬性被設定,才執行某個target。這樣,允許根據系統的狀態(javaversion,OS,命令行屬性定義等等)來更好地控制build的過程。要想讓一個target這樣做,你就應該在target元素中,加入if(或unless)屬性,帶上target因該有所判斷的屬性。例如:
<targetname=”build-module-A”if=”module-A-present”/>
<targetname=”build-own-fake-module-A”unless=”module-A-present”/>
如果沒有if或unless屬性,target總會被執行。

可選的description屬性可用來提供關于target的一行描述,這些描述可由-projecthelp命令行選項輸出。

將你的tstamptask在一個所謂的初始化target是很好的做法,其他的target依賴這個初始化target。要確保初始化target是出現在其他target依賴表中的第一個target。在本手冊中大多數的初始化target的名字是”init”。

target有下面的屬性:
AttributeDescriptionRequired
nametarget的名字Yes
depends用逗號分隔的target的名字列表,也就是依賴表。No
if執行target所需要設定的屬性名。No
unless執行target需要清除設定的屬性名。No
description關于target功能的簡短描述。No

3.3Tasks

一個task是一段可執行的代碼。

一個task可以有多個屬性(如果你愿意的話,可以將其稱之為變量)。屬性只可能包含對property的引用。這些引用會在task執行前被解析。

下面是Task的一般構造形式:
<nameattribute1=”value1″attribute2=”value2″…/>
這里name是task的名字,attributeN是屬性名,valueN是屬性值。

有一套內置的(built-in)task,以及一些可選task,但你也可以編寫自己的task。

所有的task都有一個task名字屬性。Ant用屬性值來產生日志信息。

可以給task賦一個id屬性:
<tasknameid=”taskID”…/>
這里taskname是task的名字,而taskID是這個task的唯一標識符。通過這個標識符,你可以在腳本中引用相應的task。例如,在腳本中你可以這樣:
<script…>
task1.setFoo(“bar”);
</script>
設定某個task實例的foo屬性。在另一個task中(用java編寫),你可以利用下面的語句存取相應的實例。
project.getReference(“task1”).
注意1:如果task1還沒有運行,就不會被生效(例如:不設定屬性),如果你在隨后配置它,你所作的一切都會被覆蓋。

注意2:未來的Ant版本可能不會兼容這里所提的屬性,因為很有可能根本沒有task實例,只有proxies。

3.4Properties

一個project可以有很多的properties??梢栽赽uildfile中用propertytask來設定,或在Ant之外設定。一個 property有一個名字和一個值。property可用于task的屬性值。這是通過將屬性名放在”${“和”}”之間并放在屬性值的位置來實現的。例如如果有一個propertybuilddir的值是”build”,這個property就可用于屬性值:${builddir} /classes。這個值就可被解析為build/classes。

內置屬性

如果你使用了<property>task定義了所有的系統屬性,Ant允許你使用這些屬性。例如,${os.name}對應操作系統的名字。

要想得到系統屬性的列表可參考theJavadocofSystem.getProperties。

除了Java的系統屬性,Ant還定義了一些自己的內置屬性:
basedirproject基目錄的絕對路徑(與<project>的basedir屬性一樣)。
ant.filebuildfile的絕對路徑。
ant.versionAnt的版本。
ant.project.name當前執行的project的名字;由<project>的name屬性設定.
ant.java.versionAnt檢測到的JVM的版本;目前的值有”1.1″,“1.2”,“1.3”and“1.4”.

例子
<projectname=”MyProject”default=”dist”basedir=”.”>

<!–setglobalpropertiesforthisbuild–>
<propertyname=”src”value=”.”/>
<propertyname=”build”value=”build”/>
<propertyname=”dist”value=”dist”/>

<targetname=”init”>
<!–Createthetimestamp–>
<tstamp/>
<!–Createthebuilddirectorystructureusedbycompile–>
<mkdirdir=”${build}”/>
</target>

<targetname=”compile”depends=”init”>
<!–Compilethejavacodefrom${src}into${build}–>
<javacsrcdir=”${src}”destdir=”${build}”/>
</target>

<targetname=”dist”depends=”compile”>
<!–Createthedistributiondirectory–>
<mkdirdir=”${dist}/lib”/>
<!–Puteverythingin${build}intotheMyProject-${DSTAMP}.jarfile–>
<jarjarfile=”${dist}/lib/MyProject-${DSTAMP}.jar”basedir=”${build}”/>
</target>

<targetname=”clean”>
<!–Deletethe${build}and${dist}directorytrees–>
<deletedir=”${build}”/>
<deletedir=”${dist}”/>
</target>

</project>
3.5Path-likeStructures
你可以用”:”和”;”作為分隔符,指定類似PATH和CLASSPATH的引用。Ant會把分隔符轉換為當前系統所用的分隔符。

當需要指定類似路徑的值時,可以使用嵌套元素。一般的形式是
<classpath>
<pathelementpath=”${classpath}”/>
<pathelementlocation=”lib/helper.jar”/>
</classpath>
location屬性指定了相對于project基目錄的一個文件和目錄,而path屬性接受逗號或分號分隔的一個位置列表。path屬性一般用作預定義的路徑--其他情況下,應該用多個location屬性。

為簡潔起見,classpath標簽支持自己的path和location屬性。所以:
<classpath>
<pathelementpath=”${classpath}”/>
</classpath>
可以被簡寫作:
<classpathpath=”${classpath}”/>
也可通過<fileset>元素指定路徑。構成一個fileset的多個文件加入path-likestructure的順序是未定的。
<classpath>
<pathelementpath=”${classpath}”/>
<filesetdir=”lib”>
<includename=”**/*.jar”/>
</fileset>
<pathelementlocation=”classes”/>
</classpath>
上面的例子構造了一個路徑值包括:${classpath}的路徑,跟著lib目錄下的所有jar文件,接著是classes目錄。

如果你想在多個task中使用相同的path-likestructure,你可以用<path>元素定義他們(與target同級),然后通過id屬性引用--參考Referencs例子。

path-likestructure可能包括對另一個path-likestructurede的引用(通過嵌套<path>元素):
<pathid=”base.path”>
<pathelementpath=”${classpath}”/>
<filesetdir=”lib”>
<includename=”**/*.jar”/>
</fileset>
<pathelementlocation=”classes”/>
</path>
<pathid=”tests.path”>
<pathrefid=”base.path”/>
<pathelementlocation=”testclasses”/>
</path>
前面所提的關于<classpath>的簡潔寫法對于<path>也是有效的,如:
<pathid=”tests.path”>
<pathrefid=”base.path”/>
<pathelementlocation=”testclasses”/>
</path>
可寫成:
<pathid=”base.path”path=”${classpath}”/>
命令行變量

有些task可接受參數,并將其傳遞給另一個進程。為了能在變量中包含空格字符,可使用嵌套的arg元素。
AttributeDescriptionRequired
value一個命令行變量;可包含空格字符。只能用一個
line空格分隔的命令行變量列表。
file作為命令行變量的文件名;會被文件的絕對名替代。
path一個作為單個命令行變量的path-like的字符串;或作為分隔符,Ant會將其轉變為特定平臺的分隔符。

例子
<argvalue=”-l-a”/>
是一個含有空格的單個的命令行變量。
<argline=”-l-a”/>
是兩個空格分隔的命令行變量。
<argpath=”/dir;/dir2:/dir3″/>
是一個命令行變量,其值在DOS系統上為/dir;/dir2;/dir3;在Unix系統上為/dir:/dir2:/dir3。

References

buildfile元素的id屬性可用來引用這些元素。如果你需要一遍遍的復制相同的XML代碼塊,這一屬性就很有用--如多次使用<classpath>結構。

下面的例子:
<project…>
<target…>
<rmic…>
<classpath>
<pathelementlocation=”lib/”/>
<pathelementpath=”${java.class.path}/”/>
<pathelementpath=”${additional.path}”/>
</classpath>
</rmic>
</target>
<target…>
<javac…>
<classpath>
<pathelementlocation=”lib/”/>
<pathelementpath=”${java.class.path}/”/>
<pathelementpath=”${additional.path}”/>
</classpath>
</javac>
</target>
</project>
可以寫成如下形式:
<project…>
<pathid=”project.class.path”>
<pathelementlocation=”lib/”/>
<pathelementpath=”${java.class.path}/”/>
<pathelementpath=”${additional.path}”/>
</path>
<target…>
<rmic…>
<classpathrefid=”project.class.path”/>
</rmic>
</target>
<target…>
<javac…>
<classpathrefid=”project.class.path”/>
</javac>
</target>
</project>
所有使用PatternSets,FileSets或path-likestructures嵌套元素的task也接受這種類型的引用。



4.1File(Directory)類
4.1.1Mkdir
?創建一個目錄,如果他的父目錄不存在,也會被同時創建。
?例子:
<mkdirdir=”build/classes”/>
?說明:如果build不存在,也會被同時創建
4.1.2Copy
?拷貝一個(組)文件、目錄
?例子:
1.拷貝單個的文件:
<copyfile=”myfile.txt”tofile=”mycopy.txt”/>
2.拷貝單個的文件到指定目錄下
<copyfile=”myfile.txt”todir=”../some/other/dir”/>
3.拷貝一個目錄到另外一個目錄下
<copytodir=”../new/dir”>
<filesetdir=”src_dir”/>
</copy>
4.拷貝一批文件到指定目錄下
<copytodir=”../dest/dir”>
<filesetdir=”src_dir”>
<excludename=”**/*.java”/>
</fileset>
</copy>

<copytodir=”../dest/dir”>
<filesetdir=”src_dir”excludes=”**/*.java”/>
</copy>
5.拷貝一批文件到指定目錄下,將文件名后增加。Bak后綴
<copytodir=”../backup/dir”>
<filesetdir=”src_dir”/>
<mappertype=”glob”from=”*”to=”*.bak”/>
</copy>
6.拷貝一組文件到指定目錄下,替換其中的@標簽@內容
<copytodir=”../backup/dir”>
<filesetdir=”src_dir”/>
<filterset>
<filtertoken=”TITLE”value=”FooBar”/>
</filterset>
</copy>
4.1.3Delete
?刪除一個(組)文件或者目錄
?例子
1.刪除一個文件
<deletefile=”/lib/ant.jar”/>
2.刪除指定目錄及其子目錄
<deletedir=”lib”/>
3.刪除指定的一組文件
<delete>
<filesetdir=”.”includes=”**/*.bak”/>
</delete>
4.刪除指定目錄及其子目錄,包括他自己
<deleteincludeEmptyDirs=”true”>
<filesetdir=”build”/>
</delete>
4.1.4Move
?移動或重命名一個(組)文件、目錄
?例子:
1.移動或重命名一個文件
<movefile=”file.orig”tofile=”file.moved”/>
2.移動或重命名一個文件到另一個文件夾下面
<movefile=”file.orig”todir=”dir/to/move/to”/>
3.將一個目錄移到另外一個目錄下
<movetodir=”new/dir/to/move/to”>
<filesetdir=”src/dir”/>
</move>
4.將一組文件移動到另外的目錄下
<movetodir=”some/new/dir”>
<filesetdir=”my/src/dir”>
<includename=”**/*.jar”/>
<excludename=”**/ant.jar”/>
</fileset>
</move>
5.移動文件過程中增加。Bak后綴
<movetodir=”my/src/dir”>
<filesetdir=”my/src/dir”>
<excludename=”**/*.bak”/>
</fileset>
<mappertype=”glob”from=”*”to=”*.bak”/>
</move>

4.2Java相關
4.2.1Javac
?編譯java原代碼
?例子
1.<javacsrcdir=”${src}”
destdir=”${build}”
classpath=”xyz.jar”
debug=”on”
/>
編譯${src}目錄及其子目錄下的所有。Java文件,。Class文件將放在${build}指定的目錄下,classpath表示需要用到的類文件或者目錄,debug設置為on表示輸出debug信息
2.<javacsrcdir=”${src}:${src2}”
destdir=”${build}”
includes=”mypackage/p1/**,mypackage/p2/**”
excludes=”mypackage/p1/testpackage/**”
classpath=”xyz.jar”
debug=”on”
/>
編譯${src}和${src2}目錄及其子目錄下的所有。Java文件,但是package/p1/**,mypackage/p2/**將被編譯,而 mypackage/p1/testpackage/**將不會被編譯。Class文件將放在${build}指定的目錄下,classpath表示需要用到的類文件或者目錄,debug設置為on表示輸出debug信息
3.<propertyname=”classpath”value=”.;./xml-apis.jar;../lib/xbean.jar;./easypo.jar”/>

<javacsrcdir=”${src}”
destdir=”${src}”
classpath=”${classpath}”
debug=”on”
/>
路徑是在property中定義的
4.2.2java
?執行指定的java類
?例子:
1.<javaclassname=”test.Main”>
<classpath>
<pathelementlocation=”dist/test.jar”/>
<pathelementpath=”${java.class.path}”/>
</classpath>
</java>
classname中指定要執行的類,classpath設定要使用的環境變量
2.<pathid=”project.class.path”>
<pathelementlocation=”lib/”/>
<pathelementpath=”${java.class.path}/”/>
<pathelementpath=”${additional.path}”/>
</path>

<target…>
<rmic…>
<classpathrefid=”project.class.path”/>
</rmic>
</target>

4.3打包相關
4.3.1jar
?將一組文件打包
?例子:
1.<jardestfile=”${dist}/lib/app.jar”basedir=”${build}/classes”/>
將${build}/classes下面的所有文件打包到${dist}/lib/app.jar中
2.<jardestfile=”${dist}/lib/app.jar”
basedir=”${build}/classes”
includes=”mypackage/test/**”
excludes=”**/Test.class”
/>
將${build}/classes下面的所有文件打包到${dist}/lib/app.jar中,但是包括mypackage/test/所有文件不包括所有的Test.class
3.<jardestfile=”${dist}/lib/app.jar”
basedir=”${build}/classes”
includes=”mypackage/test/**”
excludes=”**/Test.class”
manifest=”my.mf”
/>
manifest屬性指定自己的META-INF/MANIFEST.MF文件,而不是由系統生成
4.3.2war
?對Jar的擴展,用于打包Web應用
?例子:
?假設我們的文件目錄如下:
thirdparty/libs/jdbc1.jar
thirdparty/libs/jdbc2.jar
build/main/com/myco/myapp/Servlet.class
src/metadata/myapp.xml
src/html/myapp/index.html
src/jsp/myapp/front.jsp
src/graphics/images/gifs/small/logo.gif
src/graphics/images/gifs/large/logo.gif
?下面是我們的任務的內容:
<wardestfile=”myapp.war”webxml=”src/metadata/myapp.xml”>
<filesetdir=”src/html/myapp”/>
<filesetdir=”src/jsp/myapp”/>
<libdir=”thirdparty/libs”>
<excludename=”jdbc1.jar”/>
</lib>
<classesdir=”build/main”/>
<zipfilesetdir=”src/graphics/images/gifs”
prefix=”images”/>
</war>
?完成后的結果:
WEB-INF/web.xml
WEB-INF/lib/jdbc2.jar
WEB-INF/classes/com/myco/myapp/Servlet.class
META-INF/MANIFEST.MF
index.html
front.jsp
images/small/logo.gif
images/large/logo.gif
4.3.3ear
?用于打包企業應用
?例子
<eardestfile=”${build.dir}/myapp.ear”appxml=”${src.dir}/metadata/application.xml”>
<filesetdir=”${build.dir}”includes=”*.jar,*.war”/>
</ear>

4.4時間戳
在生成環境中使用當前時間和日期,以某種方式標記某個生成任務的輸出,以便記錄它是何時生成的,這經常是可取的。這可能涉及編輯一個文件,以便插入一個字符串來指定日期和時間,或將這個信息合并到JAR或zip文件的文件名中。
這種需要是通過簡單但是非常有用的tstamp任務來解決的。這個任務通常在某次生成過程開始時調用,比如在一個init目標中。這個任務不需要屬性,許多情況下只需<tstamp/>就足夠了。
tstamp不產生任何輸出;相反,它根據當前系統時間和日期設置Ant屬性。下面是tstamp設置的一些屬性、對每個屬性的說明,以及這些屬性可被設置到的值的例子:
屬性說明例子
DSTAMP設置為當前日期,默認格式為yyyymmdd20031217
TSTAMP設置為當前時間,默認格式為hhmm1603
TODAY設置為當前日期,帶完整的月份2003年12月17日
例如,在前一小節中,我們按如下方式創建了一個JAR文件:

<jardestfile=”package.jar”basedir=”classes”/>

在調用tstamp任務之后,我們能夠根據日期命名該JAR文件,如下所示:

<jardestfile=”package-${DSTAMP}.jar”basedir=”classes”/>

因此,如果這個任務在2003年12月17日調用,該JAR文件將被命名為package-20031217.jar。
還可以配置tstamp任務來設置不同的屬性,應用一個當前時間之前或之后的時間偏移,或以不同的方式格式化該字符串。所有這些都是使用一個嵌套的format元素來完成的,如下所示:

<tstamp>
<formatproperty=”OFFSET_TIME”
pattern=”HH:mm:ss”
offset=”10″unit=”minute”/>
</tstamp>

上面的清單將OFFSET_TIME屬性設置為距離當前時間10分鐘之后的小時數、分鐘數和秒數。
用于定義格式字符串的字符與java.text.SimpleDateFormat類所定義的那些格式字符相同

4.5執行SQL語句
?通過jdbc執行SQL語句
?例子:
1.<sql
driver=”org.gjt.mm.mysql.Driver”
url=”jdbc:mysql://localhost:3306/mydb”
userid=”root”
password=”root”
src=”data.sql”
/>
2.<sql
driver=”org.database.jdbcDriver”
url=”jdbc:database-url”
userid=”sa”
password=”pass”
src=”data.sql”
rdbms=”oracle”
version=”8.1.”
>
</sql>
只有在oracle、版本是8.1的時候才執行



4.6發送郵件
?使用SMTP服務器發送郵件
?例子:
<mailmailhost=”smtp.myisp.com”mailport=”1025″subject=”Testbuild”>
<fromaddress=”me@myisp.com”/>
<toaddress=”all@xyz.com”/>
<message>The${buildname}nightlybuildhascompleted</message>
<filesetdir=”dist”>
<includesname=”**/*.zip”/>
</fileset>
</mail>
?mailhost:SMTP服務器地址
?mailport:服務器端口
?subject:主題
?from:發送人地址
?to:接受人地址
?message:發送的消息
?fileset:設置附件

====================================================================

在ANT 出現之前,編譯和部署Java應用需要使用包括特定平臺的腳本、Make文件、不同的IDE以及手工操作等組成的大雜燴?,F在,幾乎所有的開源Java項目都在使用Ant,許多公司的開發項目也在使用Ant。Ant的大量使用,也自然帶來了對總結Ant最佳實踐的迫切需求。

本文總結了我喜好的Ant最佳實踐,很多是從親身經歷的項目錯誤,或從其他開發者的“恐怖”故事中得到的靈感的。比如,有人告訴我有個項目將XDoclet生成的代碼放入鎖定文件的版本控制工具中。單開發者修改源代碼時,他必須記住手工檢出(Checkout)并鎖定所有將要重生成的文件。然后,手工運行代碼生成器,當他能夠讓Ant編譯代碼時,這一方法還存在一些問題:

生成的代碼無法存儲在版本控制系統中

Ant(本案例中是Xdoclet)應該自動確定下一次構建涉及的源文件,而不應由程序員人工確定。

Ant的構建文件應該定義好正確的任務依賴關系,這樣程序員不必按照特定順序調用任務。

當我開始一個新項目時,我首先編寫Ant構建文件。文件定義構建的過程,并為團隊中的每個程序員都使用。本文所有的最佳實踐假設Ant構建文件是一個必須精心編寫的重要文件,它應在版本控制系統中得到維護,并定期進行重構。下面是我的十五大Ant最佳實踐。

1.采用一致的編碼規范

Ant用戶不管是喜歡還是痛恨XML構建文件的語法,都愿意跳進這一迷人的爭論中。讓我們先看一些保持XML構建文件簡潔的方法。

首先,也是最重要的,化費時間格式化你的XML讓它看上去很清晰。不過XML是否美觀,Ant都可以工作。但是丑陋的XML很難讀懂。倘若你在任務之間留出空行,有規則的縮進,每行文字不超過90列,那么XML令人驚訝的易讀。再加上好的編輯器或IDE高亮相應的語句,你就不會有如何閱讀的麻煩。同樣,精選有意義明確、容易讀懂的詞匯來命名任務和屬性。比如,dir.reports就比rpts好。并不需要特定的編碼規范,只要有一種規范并堅持使用就好。

2.將build.xml放在項目根目錄中

Ant構建文件build.xml可以放在如何位置,但是放在項目頂層目錄中可以保持項目簡潔。這是最普遍的規范,使開發者能夠在根目錄找到它。同時,也能夠容易了解項目中不同目錄之間的邏輯關系。以下是一個典型的項目層次:

[rootdir]|build.xml+–src+–lib(包含第三方JAR包)+–build(由build任務生成)+–dist(由build任務生成)

當build.xml在頂級目錄時,倘若你在項目某個子目錄中,只要輸入:ant-findcompile命令,不需要改變工作目錄就能夠以命令行方式編譯代碼。參數-find告訴Ant尋找存在于上級目錄中的build.xml并執行。

3.使用單一構建文件

有人喜歡將一個大項目分解到幾個小的構建文件,每個構建文件分擔整個構建過程的一小部分工作。但是應該認識到,將構建文件分割會增加對整個構建過程的理解難度。要注意在單一構建文件能夠清楚表現構建層次的情況下,不要過工程化(over-engineer)。

即使你把項目劃分為多個構建文件,也應使程序員能夠在項目根目錄下找到核心build.xml。盡管該文件只是將實際構建工作委派給下級構建文件,也應保證該文件可用。

4.提供良好的幫助說明

應盡量使構建文件自文檔化。增加任務描述是最簡單的方法。當你輸入ant-projecthelp時,你就可以看到帶有描述的任務清單。比如,你可以這樣定義任務:

<targetname=”compile”description=”Compilescode,outputgoestothebuilddir.”>

最簡單的規則是對所有你希望程序員通過命令行直接調用的任務都加上描述。對于一般用來執行中間處理過程的內部任務,比如生成代碼或建立輸出目錄等,就無法使用描述屬性。

這時,可以通過在構建文件中加入XML注釋來處理。或者專門定義一個help任務,當程序員輸入anthelp時來顯示詳細的使用說明。

<targetname=”help”description=”Displaydetailedusageinformation”><echo>Detailedhelp…</echo></target>

5.提供清空任務

每個構建文件都應包含一個清空任務,刪除所有生成的文件和目錄,使系統回到構建文件執行前的初始狀態。執行清空任務后還存在的文件應處在版本控制系統的管理下。

比如:

<targetname=”clean”description=”Destroysallgeneratedfilesanddirs.”><deletedir=”${dir.build}”/><deletedir=”${dir.dist}”/></target>

除非是在產生整個系統版本的特殊任務中,否則不要自動調用clean任務。當程序員僅僅執行編譯任務或其他任務時,他們不需要構建文件事先執行即令人討厭有沒有必要的清空任務。要相信程序員能夠確定何時需要清空所有文件。

6.使用ANT管理任務從屬關系

假設你的應用由SwingGUI組件、Web界面、EJB層和公共應用代碼組成。在大型系統中,你需要清晰地定義Java包屬于系統的哪一層。否則如何一點修改都要重新編譯成千上百個文件。任務從屬關系管理差會導致過度復雜而脆弱的系統。改變GUI面板的設計不應造成Servlet和EJB的重編譯。

當系統變得龐大后,稍不注意就可能將依賴于客戶端的代碼引入到服務端。這是因為IDE在編譯文件時使用單一的classpath。Ant讓你更有效地控制構建活動。

設計你的構建文件編譯大型項目的步驟:首先,編譯公共應用代碼,將編譯結果打成JAR包文件。然后,編譯上一層的項目代碼,編譯時依靠第一步產生的JAR文件。不斷重復這一過程,直到最高層的代碼編譯完成。

分步構建強化了任務從屬關系管理。如果你工作在底層Java框架上,引用高層的GUI模板組件,這時代碼不需要編譯。這是由于構建文件在編譯底層框架時,在源路徑中沒有包含高層GUI面板組件的代碼。

7.定義并重用文件路徑

如果文件路徑在一個地方集中定義,并在整個構建文件中得到重用,那么構建文件更易于理解。以下是這樣做的一個例子:

<projectname=”sample”default=”compile”basedir=”.”><pathid=”classpath.common”><pathelementlocation=”${jdom.jar.withpath}”/>…etc</path><pathid=”classpath.client”><pathelementlocation=”${guistuff.jar.withpath}”/><pathelementlocation=”${another.jar.withpath}”/><!–reusethecommonclasspath–><pathrefid=”classpath.common”/></path><targetname=”compile.common”depends=”prepare”><javacdestdir=”${dir.build}”srcdir=”${dir.src}”><classpathrefid=”classpath.common”/><includename=”com/oreilly/common/**”/></javac></target></project>

當項目不斷增長,構建日益復雜時,這一技術越發體現出其價值。你可能為編譯不同層次的應用定義各自的文件路徑,比如運行單元測試的、運行應用程序的、運行 Xdoclet的、生成JavaDocs的等等不同路徑。這種組件化路徑定義的方法比為每個任務單獨定義路徑要優越得多。否則,很容易丟失任務任務從屬關系的軌跡。

8.定義恰當的任務參數關系

假設dist任務從屬于jar任務,那么哪個任務從屬于compile任務,哪個任務從屬于prepare任務呢?Ant構建文件最終定義了任務的從屬關系圖,它必須被仔細地定義和維護。應該定期檢查任務的從屬關系以保證構建工作得到正確執行。大的構建文件隨著時間推移趨向于增加更多的任務,所以到最后由于不必要的從屬關系導致構建工作非常困難。比如,你可能發現在程序員只是需要編譯一些沒有使用EJB的GUI代碼時,重新生成EJB代碼。

以“優化”的名義忽略任務的從屬關系是另一種常見的錯誤。這種錯誤迫使程序員為了得到恰當的結果必須記住并按照特定的順序調用一串任務。更好的做法是:提供描述清晰的公共任務,這些任務包含正確的任務從屬關系;另外提供一套“專家”任務讓你能夠手工執行個別的構建步驟,這些任務不提供完整的構建過程,但是讓那些專家在快速而惱人的編碼期間跳過某些步驟

9.使用配置屬性

任何需要配置或可能發生變化的信息都應作為Ant屬性定義下來。對于在構建文件中多次出現的值也同樣處理。屬性既可以在構建文件頭部定義,也可以為了更好的靈活性而在單獨的屬性文件中定義。以下是在構建文件中定義屬性的樣式:

<projectname=”sample”default=”compile”basedir=”.”><propertyname=”dir.build”value=”build”/><propertyname=”dir.src”value=”src”/><propertyname=”jdom.home”value=”../java-tools/jdom-b8″/><propertyname=”jdom.jar”value=”jdom.jar”/><propertyname=”jdom.jar.withpath”value=”${jdom.home}/build/${jdom.jar}”/>etc…</project>

或者你可以使用屬性文件:

<projectname=”sample”default=”compile”basedir=”.”><propertyfile=”sample.properties”/>etc…</project>

在屬性文件sample.properties中:

dir.build=builddir.src=srcjdom.home=../java-tools/jdom-b8jdom.jar=jdom.jarjdom.jar.withpath=${jdom.home}/build/${jdom.jar}

用一個獨立的文件定義屬性是有好處的,它可以清晰地定義構建中的可配置部分。另外,在開發者工作在不同操作系統的情況下,你可以在不同的平臺上提供該文件的不同版本。

10.保持構建過程獨立

為了最大限度的擴展性,不要應用外部路徑和庫文件。最重要的是不要依賴于程序員的CLASSPATH設置。取而代之的是,在構建文件中使用相對路徑并定義自己的路徑。如果你引用了絕對路徑如C:/java/tools,其他開發者未必使用與你相同的目錄結構,所以就無法使用你的構建文件

如果你部署開發源碼項目,應該提供包括所有需要的JAR文件的發行版本,當然是在遵守許可協議的基礎上。對于內部項目,相關的JAR文件都應在版本控制系統的管理中,并撿出到大家都知道的位置。

當你不得不應用外部路徑時,應將路徑定義為屬性。使程序員能夠涌適合他們自己的機器的參數重載這些屬性。你也可以使用以下語法引用環境變量:

<propertyenvironment=”env”/><propertyname=”dir.jboss”value=”${env.JBOSS_HOME}”/>

11.使用版本控制系統

構建文件是一個重要的文件,應該象代碼一樣進行版本控制。當你標記你的代碼時,也應用同樣的標簽標記構建文件。這樣當你需要回溯構建舊版本的軟件時,能夠使用相對應的舊版本構建文件。

除構建文件之外,你還應在版本控制中維護第三方JAR文件。同樣,這使你能夠重新構建舊版本的軟件。這也能夠更容易保證所有開發者擁有一致的JAR文件,因為他們都是同構建文件一起從版本控制系統中撿出的。

通常應避免在版本控制系統中存放構建輸出品。倘若你的源代碼很好地得到了版本控制,那么通過構建過程你能夠重新生成任何版本的產品。

12.把Ant作為“最小公分母”

假設你的開發團隊使用IDE,為什么要為程序員通過點擊圖標就能夠構建整個應用而煩惱呢?

IDE 的問題在團隊中是一個關于一致性和重現性的問題。幾乎所有的IDE設計初衷都是為了提高程序員的個人生產率,而不是開發團隊的持續構建。典型的IDE要求每個程序員定義自己的項目文件。程序員可能擁有不同的目錄結構,可能使用不同版本的庫文件,還可能工作在不同的平臺上。這將導致出現這種情況:在A那里運行良好的代碼,到B那里就無法運行。

不管你的開發團隊使用何種IDE,一定要建立所有程序員都能夠使用的Ant構建文件。要建立一個程序員在將新代碼提交版本控制系統前必須執行Ant構建文件的規則。這將確保代碼是經過同一個Ant構建文件構建的。當出現問題時,要使用項目標準的 Ant構建文件,而不是通過某個IDE來執行一個干凈的構建。

程序員可以自由選擇任何他們習慣使用的IDE。但是Ant應作為公共基線以保證永遠是可構建的。

13.使用zipfileset屬性

人們經常使用Ant產生WAR、JAR、ZIP和EAR文件。這些文件通常都要求有一個特定的內部目錄結構,但其往往與你的源代碼和編譯環境的目錄結構不匹配。

一個最常用的方法是寫一個Ant任務按照期望的目錄結構把一大堆文件拷貝到臨時目錄中,然后生成壓縮文件。這不是最有效的方法。使用zipfileset屬性是更好的解決方案。它讓你從任何位置選擇文件,然后把它們按照不同目錄結構放進壓縮文件中。以下是一個例子:

<earearfile=”${dir.dist.server}/payroll.ear”appxml=”${dir.resources}/application.xml”><filesetdir=”${dir.build}”includes=”commonServer.jar”/><filesetdir=”${dir.build}”><includename=”payroll-ejb.jar”/></fileset><zipfilesetdir=”${dir.build}”prefix=”lib”><includename=”hr.jar”/><includename=”billing.jar”/></zipfileset><filesetdir=”.”><includename=”lib/jdom.jar”/><includename=”lib/log4j.jar”/><includename=”lib/ojdbc14.jar”/></fileset><zipfilesetdir=”${dir.generated.src}”prefix=”META-INF”><includename=”jboss-app.xml”/></zipfileset></ear>

在這個例子中,所有JAR文件都放在EAR文件包的lib目錄中。hr.jar和billing.jar是從構建目錄拷貝過來的。因此我們使用zipfileset屬性把它們移動到EAR文件包內部的lib目錄。prefix屬性指定了其在EAR文件中的目標路徑。

14.運行Clean構建任務的測試

假設你的構建文件中有clean和compile的任務,執行以下的測試。第一步,執行antclean;第二步,執行antcompile;第三步,再執行antcompile。第三步應該不作任何事情。如果文件再次被編譯,說明你的構建文件有問題。

構建文件應該只在與輸出文件相關聯的輸入文件發生變化時,才應該執行任務。一個構建文件在不必執行諸如編譯、拷貝或其他工作任務的時候執行這些等任務是低效的。當項目規模增長時,即使是小的低效工作也會成為大的問題。

15.避免特定平臺的Ant包

不管什么原因,有人喜歡用簡單的、名稱叫做compile之類的批文件或腳本裝載他們的產品。當你去看腳本的內容,你會發現以下內容:

antcompile

其實開發人員熟悉Ant,并且完全能夠自己鍵入antcompile。請不要僅僅為了調用Ant而使用特定平臺的腳本。這只會使其他人在首次使用你的腳本時,增加學習和理解的煩擾。除此之外,你不可能提供適用于每個操作系統的腳本,這是真正煩擾其他用戶的地方。

總結

太多的公司依靠手工方法和程序來編譯代碼和生成軟件發布版本。那些不使用Ant或類似工具定義構建過程的開發團隊,花費了令人驚異的時間來捕捉代碼編譯過程中出現的問題,這些在某些開發者那里編譯成功的代碼,到另一些開發者那里卻失敗了。

生成并維護構建腳本不是一項迷人的工作,但卻是一項必需的工作。一個好的Ant構建文件將使你集中到更喜歡的工作——寫代碼中!

無所不能的“螞蟻”–Ant

說他無所不能,好像有點夸張,但是用過Ant之后,感覺真的是只有想不到沒有作不到.Ant,原作者選擇他作為軟件名字的意思是指”令一個簡潔的工具”(Another Neat Tool),而這個真正的名字現在去很少為人所知,但這絲毫不影響他成為最優秀的構建工具.

現在開始我將進入一個”螞蟻”的世界,通過例子,真真正正去了解他!

文章參考資料可以到http://www.manning.com/antbook去下載

Ant的最好學習資料<<使用Ant進行Java開發>>

Ant的官方網站:http://ant.apache.org/

Ant的最新版本:Ant 1.6.5

本文所有的例子運行的環境:JDK1.4.2,Ant1.6.2,eclipse3.0

一.使用Ant運行Java程序

我們先從簡單的Hello學起,目錄結構如下

project–

|src–

| |–org.ant.chapter1.Hello

|bin

|build.xml

以后的例子大多采用此目錄結構,特例會額外聲明

build.xml文件

<?xml version="1.0"?>
<project name="project" default="run">
<target name="compile">
<javac destdir="bin" srcdir="src"></javac>
</target>

<target name="run" depends="compile">
<java classname="org.ant.chapter1.Hello">
</java>
</target>
</project>

從結構來看構建文件很簡單,里面的內容大家也一定能夠看得懂,可以看出Ant的核心任務就是target,一個Ant文件有多個target組成,而這些target之間,又有相互的依賴關系–depends,運行的時候默認運行project中指定的target.

javac–編譯java文件 java–運行java文件

使用eclipse中集成的Ant運行build.xml文件(當然,也可以將ANT_HOME加到Path中,在命令行中運行)

Buildfile: D:/MyEclipse/workspace/sad/build.xml
compile:
run:
 [java] Working directory ignored when same JVM is used.
 [java] Could not find org.ant.chapter1.Hello. Make sure you have it in your classpath
 [java] at org.apache.tools.ant.taskdefs.ExecuteJava.execute(ExecuteJava.java:166)
 [java] at org.apache.tools.ant.taskdefs.Java.run(Java.java:705)
 [java] at org.apache.tools.ant.taskdefs.Java.executeJava(Java.java:177)
 [java] at org.apache.tools.ant.taskdefs.Java.execute(Java.java:83)
 [java] at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
 [java] at org.apache.tools.ant.Task.perform(Task.java:364)
 [java] at org.apache.tools.ant.Target.execute(Target.java:341)
 [java] at org.apache.tools.ant.Target.performTasks(Target.java:369)
 [java] at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
 [java] at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:379)
 [java] at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:135)
BUILD SUCCESSFUL
Total time: 703 milliseconds

,java入門的經典錯誤,ClassNotDefException,可見是classpath設置問題,而觀察得到compile成功運行,所以我們在run-target里面加入classpath的配置

<?xml version="1.0"?>
<project name="project" default="run">
<target name="compile">
<javac destdir="bin" srcdir="src"></javac>
</target>

<target name="run" depends="compile">
<java classname="org.ant.chapter1.Hello">
<classpath path="bin"></classpath>
</java>
</target>
</project>
 

運行

Buildfile: D:/MyEclipse/workspace/sad/build.xml
compile:
run:
 [java] Hello World!
BUILD SUCCESSFUL
Total time: 672 milliseconds

成功!!第一個Ant應用完成,有人會說:用IDE運行豈不是更簡單,但是你要知道運行java程序只是Ant的一個小小的功能,后面我們會看到Ant的更強大的功能!

下一篇文章將介紹java程序運行的擴展及用Ant運行tomcat!

java程序運行的擴展

1.帶有參數的應用程序運行

Ant在<java>任務中提供了<arg>元素,<arg>有四種屬性value,file,line,path

public class Hello {
      
      
 public static void main(String[] args) {
 System.out.println("Hello " + args[0]); 
 File file = new File(args[1]);
 String[] filename = file.list();
 
 for(int i = 0; i < filename.length; i++) {
 System.out.println(filename[i]);
 }
 }
}

build.xml

<?xml version="1.0"?>
<project name="project" default="run">
<property name="run.classpath" value="bin"></property>

<target name="compile">
<javac destdir="bin" srcdir="src"></javac>
</target>

<target name="run" depends="compile">
<java classname="org.ant.chapter1.Hello">
<classpath path="${run.classpath}"></classpath>
<arg value="Ant"/>
<arg file="D:/rag"/>
</java>
</target>
</project>
Buildfile: D:/MyEclipse/workspace/sad/build.xml
compile:
run:
 [java] Hello Ant
 [java] hello.dat
BUILD SUCCESSFUL
Total time: 734 milliseconds

2.控制新的JVM

一般的<java>任務都運行在當前的JVM中,單一些特定的情況下將Ant運行在新的JVM下面,這時只需要將<java>中的一個屬性fork設置為true就可以了.

我們知道,java命令提供了許多的運行參數,用于指定JVM的屬性,同樣在Ant也提供相應的屬性,看例子:

<?xml version="1.0"?>
<project name="project" default="run">
<property name="run.classpath" value="bin"></property>
<property name="Search.JVM.extra.args" value="-Xincgc"></property>

<target name="compile">
<javac destdir="bin" srcdir="src"></javac>
</target>

<target name="run" depends="compile">
<java classname="org.ant.chapter1.Hello" fork="true" 
maxmemory="64m">
<classpath path="${run.classpath}"></classpath> 
<jvmarg line="${Search.JVM.extra.args}"/>
<arg value="Ant"/>
<arg file="D:/rag"/>
</java>
</target>
</project>

3.運行jar文件,使用failonerror處理錯誤

<java>同樣提供了運行jar文件的屬性

MANIFEST.MF

Mainfest-Version: 1.0
Created-By: myth
Sealed: false
Main-Class: org.ant.chapter1.Hello

build.xml

<?xml version="1.0"?>
<project name="project" default="run">
<property name="run.classpath" value="bin"></property>
<property name="Search.JVM.extra.args" value="-Xincgc"></property>

<target name="compile">
<javac destdir="bin" srcdir="src"></javac>
</target>

<target name="jar" depends="compile">
<jar destfile="test.jar" update="true" 
manifest="MANIFEST.MF">
<fileset dir="bin">
<include name="**/*.class"/>
</fileset>
</jar>
</target>

<target name="run" depends="jar">
<java fork="true" maxmemory="64m" jar="test.jar">
<classpath path="${run.classpath}"></classpath> 
<jvmarg line="${Search.JVM.extra.args}"/>
<arg value="Ant"/>
<arg file="D:/rag"/>
</java>
</target>
</project>

Buildfile: D:/MyEclipse/workspace/sad/build.xml
compile:
jar:
 [jar] Updating jar: D:/MyEclipse/workspace/sad/test.jar
run:
 [java] Hello Ant
 [java] hello.dat
BUILD SUCCESSFUL
Total time: 875 milliseconds

在某些情況下,我們不希望由于一些不重要的任務構建失敗,而導致整個構建的失敗,所以Ant提供了一個共同的屬性-failonerror,多數任務的默認值為failοnerrοr=”true”,既當此任務構建失敗時,失敗信息會傳遞給控制臺,并導致build failed,failonerror只支持在新的JVM里運行.

<target name="run" depends="jar">
<java fork="true" maxmemory="64m" jar="test.jar"
failοnerrοr="false" >
<classpath path="${run.classpath}"></classpath> 
<jvmarg line="${Search.JVM.extra.args}"/>
<arg value="Ant"/>
<arg file="D:/rag"/>
</java>
</target>

Buildfile: D:/MyEclipse/workspace/sad/build.xml
compile:
jar:
run:
 [java] java.lang.NullPointerException
 [java] at org.ant.chapter1.Hello.main(Hello.java:27)
 [java] Hello Ant
 [java] Exception in thread "main"
 [java] Java Result: 1
BUILD SUCCESSFUL
Total time: 984 milliseconds

可以看出雖然run構建失敗,但是Ant還是執行了,原來的jar文件,并且BUILD SUCCESSFUL!!

使用Ant運行tomcat

Ant使用<exec>任務運行本地程序,先看一個例子:

<?xml version="1.0"?>
<project name="project" default="run">
<target name="run">
<exec executable="cmd">
<arg value="/C a.bat"/>
</exec>
</target>
</project>

a.bat

@echo off
echo Hello >> a.txt

運行完后,會在根目錄生成a.txt文件,里面內容為Hello

下面我們來運行tomcat

<?xml version="1.0"?>
<project name="project" default="tomcat-start">
<property name="tomcat.dir" value="c:/Tomcat5"></property>

<target name="tomcat-start">
<exec dir="${tomcat.dir}/bin" executable="cmd">
<env key="CATALINA_HOME" path="${tomcat.dir}"/>
<arg value="/C startup.bat"/>
</exec>
</target>
<target name="tomcat-stop">
<exec dir="${tomcat.dir}/bin" executable="cmd">
<env key="CATALINA_HOME" path="${tomcat.dir}"/>
<arg value="/c shutdown.bat"/>
</exec>
</target>
</project>

成功!!

四.使用Ant進行Junit測試

我們除了使用java來直接運行junit之外,我們還可以使用junit提供的junit task與ant結合來運行。涉及的幾個主要的ant task如下:

l <junit>,定義一個junit task

l <batchtest>,位于<junit>中,運行多個TestCase

l <test>,位于<junit>中,運行單個TestCase

l <formatter>,位于<junit>中,定義一個測試結果輸出格式

l <junitreport>,定義一個junitreport task

l <report>,位于<junitreport>中,輸出一個junit report

運行Junit需要jakarta-ant-1.4-optional.jar和Junit.jar包,因為這兩個包用于支持ant task–<junit>的,所以不能在build.xml文件中加載,需要將他們放到ANT_HOME中去.使用eclipse可以按照一下步驟加入:

Windows-Preference-Ant-Runtime-Ant Home Entries

下面看一個Junit測試的例子:

<?xml version="1.0"?>

<project name="project" default="junit">

<property name="run.classpath" value="bin"></property>

<property name="run.srcpath" value="src"></property>

<property name="test.srcpath" value="test"></property>

<property name="lib.dir" value="lib"/>

<path id="compile.path">

<pathelement location="${lib.dir}/junit-3.8.1.jar"/>

<pathelement location="${lib.dir}/log4j-1.2.8.jar"/>

</path>

<target name="compile">

<javac destdir="${run.classpath}" srcdir="${run.srcpath}"

classpathref="compile.path"/>

<javac destdir="${run.classpath}" srcdir="${test.srcpath}"

classpathref="compile.path"/>

</target>

<target name="junit" depends="compile">

<junit printsummary="true">

<classpath path="${run.classpath}"></classpath>

<test name="org.ant.test.Test1"></test>

</junit>

</target>

</project>

可以看出Junit的使用基本和java差不多, printsummary允許輸出junit信息,當然Ant提供formatter屬性支持多樣化的junit信息輸出.Ant包含三種形式的formatter:

brief:以文本格式提供測試失敗的詳細內容;

plain:以文本格式提供測試失敗的詳細內容以及每個測試的運行統計;

xml:以xml格式提供擴展的詳細內容,包括正在測試時的Ant特性,系統輸出,以及每個測試用 例的系統錯誤.

使用formatter時建議將printsummary關閉,因為他可能對formatter的生成結果產生影響,并多生成一份同樣的輸出.當然我們可以使用formatter將輸出結果顯示在console中:

<formatter type=”brief” usefile=”false”/>

Junit支持多個formatter同時存在:

<formatter type=”brief” usefile=”false”/>

<formatter type=”xml”/>

使用xml我們可以得到擴展性更強的信息輸出,這時在<test>中要設定todir來指定xml的輸出路徑.

在通常情況下我們不可能一個一個來處理junit,所以Ant提供了<batchtest>,可以在他里面嵌套文件集(fileset)以包含全部的測試用例.

對于大量的用例,使用控制臺輸出,或者使用文件或xml文件來作為測試結果都是不合適的,Ant提供了<junitreport>任務使用XSLT將xml文件轉換為HTML報告.該任務首先將生成的XML文件整合成單一的XML文件,然后再對他進行轉換,這個整合的文件默認情況下被命名為:TESTS-TestSuites.xml.

<junitreport todir="${test.xml}">

<fileset dir="${test.xml}">

<include name="TEST-*.xml"/>

</fileset>

<report format="frames" todir="${test.report}"/>

</junitreport>

<report>元素指示轉換過程中生成有框架(frames)或者無框架的類似與javadoc格式的文件,并保存到todir所在的目錄下面.(由于xalan對于JDK1.4以上的版本存在問題,所以要生成HTML文件需要以下步驟:現在最新的xalan,在%JAVA_HOME%/jre/lib中建立文件夾endorsed.將xalan中的jar文件copy到里面).

下面看一個完整的例子:

<?xml version="1.0"?>

<projectname="project"default="junit">

<propertyname="run.classpath"value="bin"></property>

<propertyname="run.srcpath"value="src"></property>

<propertyname="test.srcpath"value="test"></property>

<propertyname="test.xml"value="xml"></property>

<propertyname="test.report"value="report"></property>

<propertyname="lib.dir"value="lib"/>

<pathid="compile.path">

<pathelementlocation="${lib.dir}/junit-3.8.1.jar"/>

<pathelementlocation="${lib.dir}/log4j-1.2.8.jar"/>

</path>

<targetname="init">

<deletedir="${test.report}"/>

<mkdirdir="${test.report}"/>

<deletedir="${test.xml}"/>

<mkdirdir="${test.xml}"/>

</target>

<targetname="compile"depends="init">

<javacdestdir="${run.classpath}"srcdir="${run.srcpath}"

classpathref="compile.path"/>

<javacdestdir="${run.classpath}"srcdir="${test.srcpath}"

classpathref="compile.path"/>

</target>

<targetname="junit"depends="compile">

<junitprintsummary="false">

<classpathpath="${run.classpath}"></classpath>

<formattertype="xml"/>

<batchtesttodir="${test.xml}">

<filesetdir="${run.classpath}">

<includename="**/Test*.class"/>

</fileset>

</batchtest>

</junit>

<junitreporttodir="${test.xml}">

<filesetdir="${test.xml}">

<includename="TEST-*.xml"/>

</fileset>

<reportformat="frames"todir="${test.report}"/>

</junitreport>

</target>

</project>

<?xml version="1.0"?>

<projectname="project"default="junit">

<propertyname="run.classpath"value="bin"></property>

<propertyname="run.srcpath"value="src"></property>

<propertyname="test.srcpath"value="test"></property>

<propertyname="test.xml"value="xml"></property>

<propertyname="test.report"value="report"></property>

<propertyname="lib.dir"value="lib"/>

<pathid="compile.path">

<pathelementlocation="${lib.dir}/junit-3.8.1.jar"/>

<pathelementlocation="${lib.dir}/log4j-1.2.8.jar"/>

</path>

<targetname="init">

<deletedir="${test.report}"/>

<mkdirdir="${test.report}"/>

<deletedir="${test.xml}"/>

<mkdirdir="${test.xml}"/>

</target>

<targetname="compile"depends="init">

<javacdestdir="${run.classpath}"srcdir="${run.srcpath}"

classpathref="compile.path"/>

<javacdestdir="${run.classpath}"srcdir="${test.srcpath}"

classpathref="compile.path"/>

</target>

<targetname="junit"depends="compile">

<junitprintsummary="false">

<classpathpath="${run.classpath}"></classpath>

<formattertype="xml"/>

<batchtesttodir="${test.xml}">

<filesetdir="${run.classpath}">

<includename="**/Test*.class"/>

</fileset>

</batchtest>

</junit>

<junitreporttodir="${test.xml}">

<filesetdir="${test.xml}">

<includename="TEST-*.xml"/>

</fileset>

<reportformat="frames"todir="${test.report}"/>

</junitreport>

</target>

</project>

生成的文檔:

點擊Properties超鏈接會彈出一個窗口顯示在測試運行時全部的Ant特性,這對于跟蹤由環境和配置造成的失敗是非常便利的!

五.使用Ant運行本地程序

1.使用Ant運行windows的批處理文件

要在Ant內運行一個外部程序,應使用<exec>任務.它允許你執行下列操作:

l 指定程序名和要傳入的參數.

l 命名運行目錄.

l 使用failonerror標志來控制當應用程序失敗時是否停止構建.

l 指定一個最大程序持續時間,時間超過則中止程序.任務在這時被認為是失敗,但是至少構建會中止,而不是掛起,這對于自動構建是至關重要的.

l 將輸出存到一個文件或特性.

l 指定java調用本地程序時需要預先設定的環境變量.

下面來看一個例子:

批處理文件:

Test.bat

@echo off

echo Hello > test.txt

build.xml

<?xml version="1.0"?>

<project name="batch" default="extract" basedir=".">

<target name="extract">

<exec executable ="cmd">

<arg line="/c a.bat"/>

</exec>

</target>

</project>

使用executable元素標記指定使用的命令,具體用法可以在命令行下面輸入help cmd查看.如果你希望在運行批處理發生錯誤時中止構建需要設定failοnerrοr=”on”.加入你的外部程序在某個時刻掛起,也許是在與遠程站點對話,而你不希望構建永遠被掛起,Ant提供了timeout這個屬性,他是一個以毫秒為單位的數字.下面看一下如何使用Ant來運行tomcat.

啟動tomcat需要兩個環境變量CATALINA_HOME, JAVA_HOME,如果你在環境變量中已經設定,在Ant中就不需要進行處理,如果沒有需要使用<env>屬性來設定,你也可以使用<env>屬性覆蓋你以前的環境變量.

<?xml version="1.0"?>

<projectname="batch"default="tomcat-start"basedir=".">

<propertyname="tomcat.dir"value="C:/Tomcat5"></property>

<targetname="tomcat-start">

<execdir="${tomcat.dir}/bin"executable="cmd">

<envkey="CATALINA_HOME"path="${tomcat.dir}"/>

<argvalue="/C startup.bat"/>

</exec>

</target>

</project>

2.使用Ant運行shell文件

由于windowsXP的cmd默認沒有安裝ps,bash等命令,所以我們需要借助的三方的軟件來實現這個功能,這里使用cgywin,將cgywin的bin目錄加到環境變量的Path里面(下面使用Ant運行cvs也會用到).

<?xml version="1.0"?>

<projectname="batch"default="shell"basedir=".">

<propertyname="tomcat.dir"value="C:/Tomcat5"></property>

<targetname="shell">

<execdir="${tomcat.dir}/bin"executable="bash">

<envkey="CATALINA_HOME"path="${tomcat.dir}"/>

<argvalue="startup.sh"/>

</exec>

</target>

</project>

3.使用Ant運行cvs

Ant內置cvs屬性,可以很方便的使用cvs:

<?xml version="1.0"?>

<projectname="batch"default="shell"basedir=".">

<propertyname="cvs.root"value="..."></property>

<targetname="cvs">

<cvscvsroot="cvs.root"command="checkout ../.."/>

</target>

</project>

如果你的Documents and Settings中有.cvspass文件,那么可以不用設定cvsroot,Ant會自動尋找.

六.工程的打包部署

工程的打包,主要就是文件的操作,下面通過例子簡單介紹一下文件的移動,復制和刪除.

<?xml version="1.0"?>

<projectname="project"default="jar">

<targetname="copy">

<tstamp>

<formatproperty="time.format" pattern="yyyy-mm-dd'T'HH:mm:ss"

locale="en"/>

</tstamp>

<copytofile="dist/readme"file="test.txt">

<filterset>

<filtertoken="TIME"value="${time.format}"/>

</filterset>

</copy>

</target>

<targetname="move">

<movetodir="dist">

<filesetdir="lib">

<includename="*.jar"/>

</fileset>

</move>

</target>

<targetname="delete"depends="copy,move">

<deleteverbose="true"failοnerrοr="false">

<filesetdir="dist">

<includename="*.jar"/>

</fileset>

</delete>

</target>

</project>

需要說明的是文件刪除的時候可能這個文件正在被別人是用而無法刪除,所以要用failonerror來標記,文件的復制是時間戳敏感的,如果拷貝的文件比原文件要老,那么Ant將不會執行copy,解決的辦法是將overwrite屬性設置為true,由于移動文件是復制文件的一個子類,所以它們的原理基本相同.

前面已經例舉過一個jar文件打包的例子,下面主要介紹war文件的打包.Ant提供war文件打包的屬性.<war>任務是<jar>任務的子類,但是他也提供了一些特有的屬性:

<targetname="deploy"depends="init">

<wardestfile="${war.dir}/spring.war"webxml="${web.dir}/web.xml">

<classesdir="${web.dir}/classes"></classes>

<filesetdir="WebContent"excludes="web.xml"></fileset>

<libdir="${web.dir}/lib"></lib>

</war>

</target>

可以看出war任務提供了許多WEB應用程序的特有屬性,只要你指定了這些文件,war任務就會自動將他們放到正確的位置.

部署是項目發布的過程,Ant支持FTP,Email,本地和遠程等幾種部署模式,但是Ant并不內置對一些部署的支持,需要第三方的庫.

optional.jar 也可能是這樣的名字: jakarta-ant-1.4.1.optional.jar

netcomponents.jar <ftp>和<telnet>需要

activation.jar <mail>需要

mail.jar <mail>需要

下面只以本地部署為例,服務器為tomcat.

由于tomcat支持熱部署,可以將webapp文件下的war文件自解壓縮,所以最簡單的部署方式是將工程打成war包后直接copy到webapp目錄下面.另一種方法是使用tomcat的管理員身份,在manager頁面裝載和刪除應用,這種方法比較復雜,也比較正規,他也是遠程部署的基礎.

<?xml version="1.0"?>

<project name="project" default="deploy-local-catalina">

<property name="war.dir" value="dist"></property>

<property name="web.dir" value="WebContent/WEB-INF"></property>

<property name="webapp.name" value="spring"></property>

<property name="catalina.port" value="8080"></property>

<property name="catalina.username" value="admin"></property>

<property name="catalina.password" value="admin"></property>

<target name="init">

<mkdir dir="${war.dir}"/>

</target>

<target name="mkwar" depends="init">

<war destfile="${war.dir}/spring.war" webxml="${web.dir}/web.xml" >

<classes dir="${web.dir}/classes"></classes>

<fileset dir="WebContent" excludes="web.xml"></fileset>

<lib dir="${web.dir}/lib"></lib>

</war>

</target>

<target name="remove-local-catalina">

<property name="deploy.local.remove.url"

value="http://localhost:${catalina.port}/manager/remove"></property>

<get dest="deploy.local.remove.txt"

src="${deploy.local.remove.url}?path=/${webapp.name}"

username="admin" password="admin"/>

<loadfile property="depoly.local.remove.result"

srcfile="depoly.local.remove.txt"></loadfile>

</target>

<target name="deploy-local-catalina" depends="mkwar, remove-local-catalina">

<property name="deploy.local.urlpath"

value="file:///D:/MyEclipse/workspace/springstruts/dist/spring.war"></property>

<property name="deploy.local.url.params"

value="path=/${webapp.name}&amp;war=${deploy.local.urlpath}"></property>

<property name="deploy.local.url"

value="http://localhost:${catalina.port}/manager/install"></property>

<get src="${deploy.local.url}?${deploy.local.url.params}"

dest="deploy-local.txt"

username="admin"

password="admin"/>

<loadfile property="deploy.local.result"

srcfile="deploy-local.txt"></loadfile>

</target>

</project>

可以看出只要將上面的localhost換成目標的ip地址就可以實現tomcat的遠程部署.

ANT打包內存溢出及JDK版本過低編繹失敗解決

,<javac classpathref=”project.class.path” debug=”true” deprecation=”true” destdir=”${dest}” nowarn=”false” target=”1.6″ >在此標簽中增加fork=”true” memoryMaximumSize=”512m”就行了—也可以改更大

ANT編繹時出現以下錯誤:

please download the original output file to see more info—一般是因為JDK版本過低,請在環境變量中設置高版本的JDK的JAVA_HOME及相應的PATH變量.

總結

以上是生活随笔為你收集整理的Ant 下载、安装、使用、教程全面了解「建议收藏」的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

中文字幕 国产专区 | 久久好看免费视频 | 日韩av手机在线看 | 亚洲有 在线 | 久久久免费网站 | www狠狠| 在线观看韩国av | 97热久久免费频精品99 | 国产精品一区二区三区四 | 亚洲精品在线视频网站 | 91mv.cool在线观看| 玖玖在线观看视频 | 91爱看片 | 日韩理论电影在线 | 日韩综合在线观看 | 亚洲人片在线观看 | 五月黄色| 久草在线视频免赞 | 综合色综合色 | 久久精品国产精品亚洲 | 国产小视频在线免费观看 | 欧美一区二区三区不卡 | av亚洲产国偷v产偷v自拍小说 | 国产精品9999| 在线av资源 | 国产极品尤物在线 | 欧美福利在线播放 | 日韩天天操 | 成人教育av | 99在线观看视频 | 色先锋av资源中文字幕 | 国产成人精品一区二区三区在线观看 | 色悠悠久久综合 | 蜜臀久久99精品久久久无需会员 | 久久久久久久久久久网站 | 国产欧美日韩精品一区二区免费 | 在线观看日韩一区 | 丁香久久激情 | 国产成人一区二区精品非洲 | 在线观看精品一区 | 亚洲成av人片 | 亚洲一区二区高潮无套美女 | 在线免费观看视频你懂的 | 日本精品在线视频 | 456免费视频 | 亚洲免费资源 | 国产男女爽爽爽免费视频 | 国产精品久久久久av | 中文字幕av在线电影 | 精品国产一区二区三区在线观看 | 久久久噜噜噜久久久 | 免费激情在线电影 | 香蕉久草 | 欧美在线观看视频一区二区三区 | av一级在线 | 成人a级免费视频 | 午夜视频在线观看一区二区三区 | 99re6热在线精品视频 | 精品久久久久久久久久久院品网 | 欧美日韩aaaa| 日韩a欧美 | ww亚洲ww亚在线观看 | 日韩一二三在线 | 午夜男人影院 | 99久久这里只有精品 | 久久综合成人网 | 国产精品v a免费视频 | 免费观看www7722午夜电影 | 国产黄a三级三级三级三级三级 | 色亚洲激情 | 国产在线精 | 久久久久久久久久久久久国产精品 | 婷婷久久一区二区三区 | 欧洲精品在线视频 | 久久久久成人免费 | 97精品电影院 | av在线观| 91在线视频观看 | 国产成人精品久久二区二区 | 在线欧美小视频 | 在线播放一区二区三区 | 天天添夜夜操 | 久久精品视频99 | 五月精品 | 在线观看日韩中文字幕 | 亚洲精品美女免费 | 日韩在线观看一区二区三区 | 亚洲欧美国产精品 | 国产看片 色 | 成人禁用看黄a在线 | 天天摸天天弄 | 亚洲午夜久久久影院 | 日韩精品久久一区二区三区 | 久久免费精彩视频 | 天天色天天操天天爽 | av在线免费播放 | 色姑娘综合天天 | 欧美亚洲免费在线一区 | 国产视频中文字幕在线观看 | 国产成人一区二 | 九月婷婷人人澡人人添人人爽 | 最近中文字幕大全中文字幕免费 | 精品国产一区二区在线 | 日韩中文字幕亚洲一区二区va在线 | av网站在线免费观看 | 久久成人免费 | 国产大片黄色 | 国产成人综合在线观看 | 91精品国自产在线观看欧美 | 国产亚洲精品无 | 久久er99热精品一区二区三区 | 国产精品xxxx18a99 | 欧美激情xxxx性bbbb | 99久久婷婷| 在线国产一区二区三区 | 深夜国产福利 | 日狠狠 | 亚洲欧美成人网 | 色吊丝在线永久观看最新版本 | 国产亚洲一区 | 欧美日韩精品在线观看视频 | 美女免费视频一区二区 | 91最新在线观看 | 亚洲成av人片在线观看无 | 在线观看视频 | 久久精品国产一区二区 | 国产精品久久久久久一区二区 | 国产精品一区二区中文字幕 | 四虎影视精品 | 97在线观看视频国产 | 欧美在线视频a | 狠狠色伊人亚洲综合网站野外 | 日本高清中文字幕有码在线 | 日韩av快播电影网 | 看片一区二区三区 | 国产伦精品一区二区三区照片91 | 国产免费观看视频 | 808电影| 国产精品一区二区三区久久久 | 天天操天天干天天操天天干 | 亚洲高清激情 | 精品久久久亚洲 | 久草资源在线 | 国产一区二区不卡视频 | 国内精品久久久久久久久 | 国产视频黄| 免费麻豆视频 | 亚洲一片黄 | 中文字幕在线看视频 | 天天做天天看 | 久久久久久99精品 | 天天综合导航 | av网站免费线看精品 | 91中文字幕 | 国产香蕉视频在线播放 | 久久综合狠狠综合久久狠狠色综合 | 免费久草视频 | 免费视频在线观看网站 | 亚洲伦理一区 | 免费福利视频导航 | 久久一区二区三区四区 | 一区二区欧美日韩 | 国产馆在线播放 | 激情一区二区三区欧美 | 亚洲干视频在线观看 | 日韩大陆欧美高清视频区 | 日本久久久久久久久 | 久久国产精品久久精品国产演员表 | 最新av网站在线观看 | 免费av黄色 | 在线 影视 一区 | 久久精品一区二区三区四区 | 91香蕉国产 | 在线观看www视频 | 欧美视频在线二区 | 亚洲在线日韩 | 中文字幕在线观看国产 | 在线免费性生活片 | 国产一级做a | 日韩亚洲国产中文字幕 | 久久久久久久久久久精 | 国产成人精品久久久久蜜臀 | 国内久久久久 | 在线国产欧美 | 国精产品999国精产品视频 | www91在线观看| 天天操天天干天天玩 | 国产亚洲成人网 | 天天干天天综合 | 麻豆国产在线播放 | 天天摸天天舔天天操 | 九九免费精品 | 日韩高清在线一区二区 | 久久一精品 | 一区二区三区动漫 | 九九综合久久 | 中文字幕第一 | 亚洲色图 校园春色 | 国产无遮挡又黄又爽馒头漫画 | 国产美女久久 | 欧美日韩不卡在线观看 | 九九视频在线 | 操处女逼 | 国产精品一区二区免费在线观看 | 日日爽视频 | 日韩资源在线播放 | 91成人在线视频 | 精品国产91亚洲一区二区三区www | 99视频在线| 亚洲国产视频a | 一级片视频在线 | 国产精品ⅴa有声小说 | 在线香蕉视频 | 久久电影色 | 国产精品五月天 | 日韩簧片在线观看 | 午夜av免费 | 国产 一区二区三区 在线 | 欧美三级高清 | 亚洲精品在线免费 | 久久久久亚洲天堂 | 国产精品免费视频观看 | 亚洲视频 一区 | 国产麻豆精品久久一二三 | 国产亚洲视频中文字幕视频 | 在线精品在线 | 久久精品中文字幕少妇 | 成人精品一区二区三区电影免费 | 在线天堂中文www视软件 | 久久草在线视频国产 | 伊人宗合网 | 久久国产午夜精品理论片最新版本 | 欧美在线一级片 | 免费亚洲精品视频 | 国产一级精品视频 | 伊人狠狠色 | 最新超碰| av片子在线观看 | 夜夜操天天干, | 91视频免费看 | bbbb操bbbb| 亚洲夜夜爽 | 国产日韩视频在线观看 | 婷婷久久综合九色综合 | www.狠狠| 最新av电影网址 | 99精品视频中文字幕 | 久久永久免费视频 | 国内精品久久久久国产 | 99精品小视频| 国产精品99蜜臀久久不卡二区 | 国产精品一区二区久久精品 | 亚洲国产中文字幕在线视频综合 | 国产精品免费一区二区 | 日韩精品久久久久久久电影竹菊 | 国产午夜精品一区二区三区在线观看 | 日韩精品在线播放 | 亚洲女人天堂成人av在线 | 日韩精品久久久久久久电影竹菊 | 久久久久亚洲精品国产 | 在线看片中文字幕 | 日韩va亚洲va欧美va久久 | 国产视频1 | 日韩在线观看视频网站 | 久久久久一区二区三区四区 | 国产成人精品亚洲a | 日韩av午夜| 999久久久免费视频 午夜国产在线观看 | 久久久一本精品99久久精品66 | 日韩一三区 | 亚洲成成品网站 | 亚洲国产精品影院 | 蜜臀久久99精品久久久久久网站 | 中文字幕日韩电影 | 国产成人一区二区啪在线观看 | 99在线精品视频在线观看 | 免费国产黄线在线观看视频 | 亚洲电影一级黄 | 91秒拍国产福利一区 | 国产免码va在线观看免费 | 色av男人的天堂免费在线 | 中文字幕在线高清 | 欧美美女视频在线观看 | 久久午夜影视 | 欧美性爽爽 | 99精品国产99久久久久久97 | 久久久久久久久影视 | 久草在线一免费新视频 | 免费av网站观看 | 日本电影黄色 | 国产视频精品久久 | 黄色软件大全网站 | 天天躁日日躁狠狠躁av麻豆 | 亚洲专区欧美专区 | 最近中文字幕在线中文高清版 | 日韩 在线a| 97成人精品视频在线播放 | 超碰在线免费97 | 97精品国自产拍在线观看 | 黄色大片日本免费大片 | 亚洲精品影院在线观看 | 三级av在线| 国产69精品久久久久久久久久 | 久久首页 | 日韩极品视频在线观看 | 片网站| 欧美一区二区三区四区夜夜大片 | 91丨精品丨蝌蚪丨白丝jk | 久草在线费播放视频 | www.天天干.com | 国产麻豆成人传媒免费观看 | 黄色在线观看免费 | 99视频偷窥在线精品国自产拍 | 操操综合网 | 色天天天 | 黄色片视频免费 | 99视频国产精品免费观看 | 婷婷色社区 | 91麻豆视频网站 | 亚洲在线不卡 | 久久久久久不卡 | 樱空桃av | 在线免费观看一区二区三区 | 亚洲免费在线观看视频 | 亚洲乱码精品久久久久 | 超碰在线观看99 | 国产欧美最新羞羞视频在线观看 | 国产96视频 | 久久久久久久久久久久国产精品 | 日本一区二区三区视频在线播放 | 夜夜躁狠狠燥 | 在线观看日本高清mv视频 | 中文字幕国产一区 | 国产在线高清视频 | 日本黄色大片免费 | 天天色综合三 | 奇米影视四色8888 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 日日操天天操夜夜操 | 天天干天天弄 | 成人国产电影在线观看 | 国产小视频你懂的在线 | 在线91观看 | 超碰人人国产 | 日韩成人中文字幕 | 天天干天天操天天搞 | 美女视频网 | 丁香婷婷在线 | 中文字幕丝袜 | 一区二区高清在线 | 亚洲视频在线免费观看 | 麻豆一级视频 | 精品久久国产一区 | 97国产精品一区二区 | 久久国产精品影视 | 免费网站观看www在线观看 | 伊人电影天堂 | 久久久久国产精品视频 | 色黄久久久久久 | 少妇性xxx| 三级黄色免费片 | 一区二区不卡 | 国产精品99久久99久久久二8 | 久久久久成人精品免费播放动漫 | 久久久精品网站 | 精品一区二区免费在线观看 | 在线观看91网站 | 日韩在线视频国产 | 亚洲jizzjizz日本少妇 | 992tv人人草 黄色国产区 | 91黄色免费看 | 欧美日韩综合在线观看 | 狠狠色丁香婷婷综合基地 | 91av资源在线 | 久久久久久久综合色一本 | 国产精品中文字幕av | 97电影院网 | 一区久久久 | 日本动漫做毛片一区二区 | 深爱激情久久 | av福利第一导航 | 日韩理论在线观看 | 国产成人精品亚洲 | 草久热| 香蕉视频免费在线播放 | 日韩电影在线一区 | 免费的黄色的网站 | 亚洲天堂网视频在线观看 | 午夜精品久久久久久 | 国产精品免费视频网站 | 天天插夜夜操 | 天天干天天草 | 日日躁你夜夜躁你av蜜 | 免费在线观看av的网站 | 午夜视频欧美 | 免费看的视频 | 色插综合| 亚洲综合色激情五月 | 99热这里只有精品8 久久综合毛片 | 福利一区二区三区四区 | 国产视频18| 一区二区三区在线观看中文字幕 | 国产精品久久久久永久免费看 | 国产在线第三页 | 丁香婷婷激情啪啪 | 精品视频9999 | 亚洲一区二区天堂 | 久久国产欧美日韩精品 | 狠狠久久综合 | 在线观看韩国av | 日韩a在线播放 | 国产成人99久久亚洲综合精品 | 91精品国产91久久久久福利 | 国产精品一区二区吃奶在线观看 | 激情av在线资源 | 狠日日| 午夜精选视频 | 欧美999| 国产伦理精品一区二区 | 免费在线观看午夜视频 | 天天久久夜夜 | 狠狠躁天天躁 | 激情在线网站 | 懂色av一区二区在线播放 | 97人人模人人爽人人喊网 | 久久精品国产免费观看 | 97精品国产97久久久久久久久久久久 | 成片人卡1卡2卡3手机免费看 | 91九色在线观看视频 | 国产精品久久9 | 欧美一区二区三区免费观看 | 西西4444www大胆艺术 | 深夜男人影院 | 9999精品视频 | 久久久国产一区二区三区四区小说 | 久久综合综合久久综合 | 日韩二区在线 | 91色国产在线 | 99热高清| 久久久久97国产 | 国产黄在线免费观看 | 国产婷婷精品av在线 | 极品美女被弄高潮视频网站 | 国产精品区一区 | 中文字幕一区二区在线观看 | 国产xxxx | 免费看色的网站 | 天天射天天舔天天干 | 91网址在线 | 日韩av在线免费播放 | 国产资源精品在线观看 | 91精品办公室少妇高潮对白 | 国产日韩中文字幕在线 | 蜜臀久久99精品久久久无需会员 | 亚洲精品美女视频 | 91精品在线免费 | 国产色黄网站 | 国内精品99| 美女av电影 | 日韩欧美极品 | 五月天激情电影 | 成人一区影院 | 干天天| 玖玖在线视频观看 | 最新午夜| 久久久久久亚洲精品 | 色干干| 日韩在线激情 | 日韩欧美成 | 最近字幕在线观看第一季 | 91亚洲精品在线 | 亚洲精品国产区 | 99热国内精品 | 久久9视频| 午夜视频在线观看一区二区三区 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 99精品免费久久久久久久久日本 | 久久久久久久久久伊人 | 天天爽天天爽 | 在线观看片 | 91免费在线看片 | 成人毛片在线观看 | 美女久久网站 | 在线观看的av网站 | 天堂av免费看 | 中文字幕免费在线 | 日韩视频免费 | 中文字幕高清免费日韩视频在线 | 成年人免费在线观看网站 | 人人草在线观看 | 国产精品精品视频 | 91禁在线看 | 波多野结衣一区二区三区中文字幕 | 国产亚洲激情视频在线 | av电影在线免费 | 一区二区三区在线免费播放 | 摸阴视频 | 色婷婷av一区二 | 精品中文字幕视频 | 久久久久国产精品视频 | 国产原创av片 | 日本精品小视频 | 狠狠干,狠狠操 | 最近字幕在线观看第一季 | 丁香六月久久综合狠狠色 | 黄色大片av| 97超视频 | 中文字幕一区二区三区精华液 | 国产精品亚洲视频 | 九色porny真实丨国产18 | 亚洲国产精品久久久久婷婷884 | 婷婷在线网 | 国产视频1区2区3区 久久夜视频 | 久久不射影院 | 97精品国产97久久久久久久久久久久 | 亚洲三级精品 | 久草在线资源观看 | 欧美大片mv免费 | 日本视频网 | 色婷婷狠狠18 | 国产香蕉久久精品综合网 | 黄色成年网站 | 高清av免费一区中文字幕 | 999ZYZ玖玖资源站永久 | 国精产品永久999 | 色婷婷国产精品一区在线观看 | 国产色啪 | 久久九九影院 | av片中文 | 欧美 日韩 久久 | 中文字幕日韩高清 | 欧美日韩不卡一区二区三区 | av一区二区三区在线 | 韩国av在线播放 | 欧美一区影院 | 国产精品久久中文字幕 | 日本女人在线观看 | 国产精久久久久久妇女av | 免费www视频 | 日韩电影在线观看一区二区 | 国产精品v欧美精品v日韩 | ww亚洲ww亚在线观看 | 麻豆影视在线播放 | 欧美日韩国产精品一区二区亚洲 | 欧美性护士 | 在线观看视频 | 精品一二区 | 天堂在线视频免费观看 | 国产黄网站在线观看 | 这里只有精品视频在线观看 | 日韩有码欧美 | 福利网在线 | 日韩欧美精品一区二区 | 国产一区国产精品 | 91传媒在线播放 | 久久久久久久久亚洲精品 | 免费亚洲婷婷 | 日韩av免费在线电影 | 麻豆视频免费入口 | av天天草 | 天天综合网入口 | 国产综合视频在线观看 | 久久精品草 | 欧美国产一区在线 | 亚洲精品高清在线 | 国产成人免费 | 久久人人精品 | 欧美精品在线免费 | 日韩精品一区二区三区在线播放 | 日韩欧美在线高清 | 精品福利在线视频 | av三区在线 | 国产小视频国产精品 | 久久久久亚洲精品男人的天堂 | 又粗又长又大又爽又黄少妇毛片 | 国产精品毛片一区视频 | 一区二区三区免费在线观看视频 | 日韩特级片 | 毛片永久新网址首页 | 亚洲香蕉视频 | 日韩h在线观看 | 久久久精品一区二区三区 | avav99| 欧美日韩高清一区二区三区 | 国产成人a亚洲精品 | a在线观看免费视频 | 九九九热 | 欧美a级在线播放 | 天天综合精品 | 天天综合操 | 国产精品免费小视频 | 亚洲精品乱码久久久久久蜜桃欧美 | 成人h视频 | 黄色福利| 草莓视频在线观看免费观看 | 天堂在线一区二区三区 | 91av视频在线播放 | 中文字幕视频免费观看 | 中文字幕av一区二区三区四区 | 欧美aa一级 | 日韩精品免费一区 | 日韩大片在线免费观看 | 精品久久久久久亚洲 | 亚洲成a人片在线观看网站口工 | 国产综合在线观看视频 | 成人黄色小视频 | 久久最新网址 | 四虎成人精品在永久免费 | 少妇高潮流白浆在线观看 | 成人亚洲精品国产www | 亚洲手机av| 丁香婷婷深情五月亚洲 | 国产99自拍| 国产在线播放一区 | 亚洲久草在线 | 亚洲影视九九影院在线观看 | 99久久精品视频免费 | 精品一二三区视频 | 国产成人精品一区在线 | 久久久久国产成人免费精品免费 | 成人免费网视频 | 久久成视频 | 999久久久精品视频 日韩高清www | 中文av一区二区 | 黄色免费网站大全 | 99中文在线 | 色吊丝在线永久观看最新版本 | 超碰在线cao | 91精品国产高清自在线观看 | 欧美一区免费观看 | 四虎在线视频免费观看 | 亚洲精品国产精品国自产观看 | 九九激情视频 | 激情综合网在线观看 | 精品久久久999 | 91精品久久久久久综合乱菊 | 国产精品免费久久久久久 | 免费观看性生活大片3 | 久草在线视频国产 | 丁香六月久久综合狠狠色 | 国产麻豆精品久久 | 成人福利在线播放 | 欧美精品二区 | 日韩特黄av | 欧美永久视频 | 成人中文字幕+乱码+中文字幕 | 91麻豆精品国产91久久久久 | 久久99精品一区二区三区三区 | 国产视频69| 黄色app网站在线观看 | 开心激情五月婷婷 | 免费手机黄色网址 | 久久国产精品一区二区三区四区 | 亚洲视频在线免费看 | 欧美成人免费在线 | 久久激情久久 | 日批网站免费观看 | 日韩中文字幕a | 麻豆国产精品永久免费视频 | 国产91欧美 | 天天摸天天操天天爽 | 91理论片午午伦夜理片久久 | www五月天婷婷 | 久久草视频| 五月激情久久久 | 国产成人免费观看久久久 | 国产一级大片免费看 | 免费在线播放视频 | 久久看免费视频 | 久久久久国产成人免费精品免费 | 国产美女在线免费观看 | 色91av | 一级性视频 | 国产在线小视频 | 国产香蕉视频 | 黄色一级免费电影 | 成年人在线免费看 | 欧美国产日韩一区 | 中文字幕在线视频免费播放 | 99久久婷婷国产综合亚洲 | 岛国精品一区二区 | 婷婷激情av| 黄网站免费大全入口 | 色之综合网 | 久久综合久久综合久久综合 | 中文字幕一区二区三区久久蜜桃 | 五月婷婷欧美视频 | 在线免费性生活片 | av成人免费观看 | 综合久久精品 | 亚州精品国产 | av怡红院| 久久久久久久久久久久国产精品 | 97视频免费 | 国产免费久久 | 日日干av | 成人影片在线播放 | 欧美大片mv免费 | 午夜av大片| 久久一区二区三区超碰国产精品 | 成人av在线网 | 自拍超碰在线 | 天天色天天操天天爽 | 中文字幕视频网站 | 天天色天天艹 | 高清在线一区 | 日韩久久影院 | 亚洲综合日韩在线 | 免费精品在线观看 | 国产免费视频一区二区裸体 | www.色国产| 人人舔人人干 | 天天超碰 | 91麻豆精品国产午夜天堂 | 亚洲精品一区二区三区新线路 | 日韩欧美在线第一页 | 中文字幕一区二区三区四区 | 狠狠躁日日躁狂躁夜夜躁 | 亚州国产精品视频 | 国产无套精品久久久久久 | 日韩电影在线观看一区二区三区 | 免费在线观看成人小视频 | 999视频精品 | av色图天堂网 | 97视频免费看 | 国产区精品视频 | 麻豆免费观看视频 | 精品中文字幕在线播放 | 国产精品久久久久永久免费观看 | 精品在线视频播放 | 国产高清视频免费观看 | 亚洲精品乱码久久久久久9色 | 亚洲精品合集 | av免费网| 免费日韩 精品中文字幕视频在线 | 亚州精品成人 | 欧美va电影 | 亚洲欧洲精品久久 | 美女黄久久| 亚洲最新在线 | 亚洲国产成人在线观看 | 日韩欧美一区二区三区在线 | 91高清视频 | 99综合电影在线视频 | 国产免费小视频 | 天天干天天干天天色 | 国内精品久久久久久久久久久 | 成年人免费电影在线观看 | 免费看久久久 | 日韩在线字幕 | 免费视频一区 | japanese黑人亚洲人4k | 久久国产精品一二三区 | 国产精品欧美一区二区三区不卡 | 爱射综合 | 日韩精品欧美专区 | 日批视频在线播放 | 亚洲理论在线观看 | 特级a毛片 | 国产在线播放不卡 | 国产一区二区精 | 国产黄色视 | 亚洲精品福利在线观看 | 日韩中文字幕视频在线观看 | 国内精品久久久久久久久久清纯 | 亚洲精品一区二区三区在线观看 | 99热最新精品 | 国产 精品 资源 | 成人av电影免费观看 | 亚洲黄色激情小说 | 精品久久久久久久久久岛国gif | 日韩理论在线观看 | 国产精品免费在线视频 | www.久久免费视频 | 免费看片色 | 丝袜美腿在线 | 91精品久久久久久久久 | 国产视频黄 | 国产视频一区二区在线播放 | 亚洲免费不卡 | 一区国产精品 | 日韩成人免费在线观看 | 天天·日日日干 | 能在线看的av | 亚洲精品国产精品国自 | 91av免费在线观看 | 亚洲精品字幕在线 | 久久成人精品电影 | 精品国产一区二 | 成人午夜电影在线播放 | 成人黄色视 | av超碰在线 | 99久高清在线观看视频99精品热在线观看视频 | 丁香婷婷基地 | 男女激情麻豆 | 免费91在线观看 | 中文字幕在线观看免费观看 | 婷婷五综合 | 四虎在线观看视频 | 97视频免费在线观看 | 在线观看久久久久久 | 最新中文字幕在线资源 | 国产白浆在线观看 | 欧美视频在线观看免费网址 | 久久精品中文字幕免费mv | 日韩欧美视频在线观看免费 | 亚洲日本一区二区在线 | 国产精品久一 | 免费a v在线 | 日韩av快播电影网 | 久久婷婷视频 | 国产在线观看免费观看 | 最近2019好看的中文字幕免费 | 综合黄色网 | 69久久久久久久 | 成人精品视频久久久久 | 91精品在线免费观看视频 | 国产高清区 | 日韩精品视频免费在线观看 | 96在线 | 久久伊人精品天天 | 国产亚州精品视频 | 国产精品mv | 中文av在线播放 | 在线中文字母电影观看 | 久久男人影院 | 国产999精品久久久 免费a网站 | 成人小视频在线播放 | 亚洲伊人网在线观看 | 亚洲精品国产综合久久 | 99热精品国产一区二区在线观看 | 久久久久久电影 | 国产原创av在线 | 国产91全国探花系列在线播放 | 天天干夜夜擦 | 日韩丝袜在线观看 | 黄色网址国产 | 精品一区二区在线免费观看 | 一区二区三区免费播放 | 国产 一区二区三区 在线 | 免费在线精品视频 | 国产性天天综合网 | 在线免费观看的av网站 | 成人在线黄色 | 中文字幕在线观看视频一区二区三区 | 日韩免费 | 在线观看精品视频 | 久久人人爽人人爽人人片av软件 | 九九视频精品免费 | 超碰国产在线 | bbbbb女女女女女bbbbb国产 | 又色又爽又黄高潮的免费视频 | 97国产视频| av在线免费观看不卡 | 日韩va欧美va亚洲va久久 | 精品久久久久久久久久久久久久久久久久 | 日韩一二三区不卡 | 伊人永久在线 | 欧美激情精品久久久久 | 一区二区三区免费网站 | 伊人资源站 | 亚洲精品在线电影 | 亚洲一级免费电影 | 久久国产精品99国产精 | 久久97久久97精品免视看 | 中文字幕中文字幕中文字幕 | 国产成人久久av | japanesefreesex中国少妇 | 欧美国产不卡 | 美女黄网久久 | 国产99久久99热这里精品5 | 午夜视频在线网站 | 人人干干人人 | 国产乱对白刺激视频不卡 | 色99导航 | 成人一级片在线观看 | 夜夜狠狠 | 一区二区精品在线 | 中文字幕久久精品亚洲乱码 | 999久久精品 | 五月导航 | 高清av中文字幕 | 久久五月婷婷丁香 | 日韩在线视频在线观看 | 国产理论片在线观看 | 色噜噜噜噜 | 成人一级电影在线观看 | 欧美一级电影 | 人人爽人人爽人人爽学生一级 | 国产精品免费观看视频 | 国产精品大片免费观看 | 手机在线免费av | 中文字幕在线字幕中文 | 色综合天天天天做夜夜夜夜做 | 九九热免费在线观看 | 日韩精品91偷拍在线观看 | 99在线精品视频观看 | 99久e精品热线免费 99国产精品久久久久久久久久 | 欧美va电影| 黄色影院在线播放 | 嫩草av影院 | 国模视频一区二区三区 | 美女视频黄是免费的 | 精品亚洲成人 | 国产精品自在欧美一区 | 国产日韩精品在线观看 | 亚洲国产精品女人久久久 | 国产精品一区二区在线免费观看 | 国产97在线视频 | 美女久久99| 国产在线观看免费 | 亚洲欧洲成人精品av97 | 国产精品久久久久久久久久新婚 | 国产一区二区三精品久久久无广告 | 国产性天天综合网 | 日本不卡123区 | 欧美一级久久久久 | 91色亚洲| 国产亚洲精品美女久久 | 免费观看www7722午夜电影 | 亚洲最大在线视频 | 免费看片日韩 | 亚洲精品乱码久久久久v最新版 | 中文字幕第一页在线视频 | 久久久精品小视频 | 精品一区 在线 | 最新av电影网站 | 成人av资源在线 | av成人动漫在线观看 | 在线观看久久 | 五月婷婷在线观看视频 | 精品亚洲国产视频 | 色网站中文字幕 | 人人爱人人做人人爽 | 国产又粗又猛又黄又爽视频 | 一区二区三区在线观看免费视频 | 在线免费av网 | 国产97视频 | 久久精品系列 | 探花视频免费在线观看 | 国产精品24小时在线观看 | 国产一区视频导航 | 国产一级精品绿帽视频 | 欧美色图30p | 99久久99久久精品国产片 | av网址aaa | 精品国产黄色片 | 欧美日韩99| 97超碰总站 | 欧美最新大片在线看 | 欧美一区二区伦理片 | 日本不卡123区 | 欧美日韩精品综合 | 日韩欧在线 | 久久夜靖品 | 亚洲精品理论 | 91亚洲视频在线观看 | 午夜三级福利 | 日韩在线观看网址 | 国产高清成人在线 | av中文在线影视 | 在线免费观看的av网站 | 美女网站在线 | 国产露脸91国语对白 | 97视频在线免费 | 日韩亚洲在线视频 | 欧美二区在线播放 | 日韩成人精品一区二区 | 亚洲精品视频第一页 | 久久久久久久av | 久久精品国产成人精品 | www.黄色片网站 | 缴情综合网五月天 | 欧美大片www| 97国产 | 久久久久久久99 | 国产一级二级在线 | 在线观看av国产 | 69av视频在线 | 国内揄拍国产精品 | 特黄特色特刺激视频免费播放 | av福利在线播放 | 亚洲永久精品国产 | 激情欧美日韩一区二区 | 色香蕉在线视频 | 国产一区成人 | 国内揄拍国内精品 | 亚洲电影久久久 | 色妞色视频一区二区三区四区 | 欧美精品二区 | 婷婷激情综合网 | av看片在线 | 亚洲精品在线观看不卡 | 亚洲精品乱码久久久久 | 成人精品福利 | 国产成人黄色在线 | 久久中文精品视频 | 亚洲成av人片 |