2008-06-21

Software Dev: Archive: - 0 (Favorite Java Build Process: Ant + Maven Dependency Management) (2007.12)

(This article is still under editing because it's kinda hard to post here this style of docs which is much better to use attachments. Interested guys please leave your comments and contact info, I will send you those attachments.)


Ant + Maven Dependency Management

Ant: http://ant.apache.org/

Release used: 1.7.0

Maven dependency management within Ant: http://maven.apache.org/ant-tasks.html

Release used: 2.0.7

Build script configuration guide:

Common Ant with Maven


Artifactory (Best internal Maven Repository Management tool):

http://www.jfrog.org/sites/artifactory/latest/
Release used: 1.2.5-rc6

Configuration of Artifactory with SQL-Server

How to Deploy Artifact file(s) into Internal Maven Repo under Artifactory


How to Utilize Common Ant With Maven for Easy Ant Build-- To utilize Maven dependency management feature within Ant build process

To take the advantage of Maven dependency library management (focus on your project direct dependencies only, let Maven Dependency Management to manage / download the dependencies of dependencies of dependency for you automatically) without the learning curve and pain of building entire pure Maven build process. And to ease/simplify the ant build script for classpath and get libraries for IDE.
A working copy:




build.xml:


<?xml version="1.0"?>
<project name="rms-core" default="jar" basedir=".">
<property name="common-ant.script.dir" value="../../common-ant" />
<import file="${common-ant.script.dir}/common-maven-in-ant.xml" />

<target name="jar" depends="compile">
<jar destfile="${sjs-artifact}">
<fileset dir="${classes.dir}">
<exclude name="**/test/**" />
</fileset>
</jar>

<antcall target="share-local" />
<!-- This call is important if this target jar is a dependency of your other project components -->
</target>

......

<!--
This post-compile target won't work for you by default.
I list it here just as an example to show that you could do anything in post-??? targets..
-->
<property name="config.dir" value="conf" />
<property name="DEPLOY_TARGET" value="Tomcat" /> <!-- Overwrite it in ant command line -->
<target name="post-compile">
<condition property="DTARGET" value="${DEPLOY_TARGET}" else="default">
<available file="${config.dir}/META-INF/persistence-${DEPLOY_TARGET}.xml" />
</condition>
<echo message="Deploy target is ${DTARGET}" level="info" />
<copy file="${config.dir}/META-INF/persistence-${DTARGET}.xml" tofile="${classes.dir}/META-INF/persistence.xml" overwrite="true" />
</target>
</project>

The most relevant line to this topic is:




<import file="${common-ant.script.dir}/common-maven-in-ant.xml" />


The common-maven-in-ant.xml does the dependency magic.





common-maven-in-ant.xml:


<?xml version="1.0"?>
<project name="Maven-in-Ant"
xmlns:maven="urn:maven-artifact-ant">
<!-- Internal maven repo (artifactory) url property -->
<property name="repo-syscon-url" value="http://build01:8081/artifactory/repo/" />
<!-- IMPORTANT: change this value to your internal repo url, no matter it's artifactory or not. -->

<property name="shared.lib.dir" value="//syscon.ca/repo" />
<path id="maven-ant-tasks.classpath" path="${shared.lib.dir}/maven/maven-ant-tasks-2.0.7.jar" />
<typedef uri="urn:maven-artifact-ant" resource="org/apache/maven/artifact/ant/antlib.xml" classpathref="maven-ant-tasks.classpath" />
<maven:remoteRepository id="repo.syscon.url" url="${repo-syscon-url}" layout="default" />
<maven:pom id="maven.pom" file="${basedir}/pom.xml" />

<property name="shared.build.dir" value="../../BUILD" />
<property name="build.dir" value="${shared.build.dir}/${maven.pom.artifactId}" />
<property name="lib.dir" value="${build.dir}/lib" />
<property name="classes.dir" value="${build.dir}/classes" />
<property name="deploy.dir" value="${build.dir}/deploy" />
<property name="sjs-artifact" value="${deploy.dir}/${maven.pom.artifactId}-${maven.pom.version}.jar" />

<target name="clean">
<delete dir="${build.dir}" />
<antcall target="post-clean" />
</target>
<target name="post-clean" description="Hook into local build for post clean processing." />

<target name="init" depends="clean">
<mkdir dir="${classes.dir}" />
<mkdir dir="${lib.dir}" />
<mkdir dir="${deploy.dir}" />
<antcall target="post-init" />
</target>
<target name="post-init" description="Hook into local build for post init processing." />

<!-- Dependencies definition common to every project build component:
To compile and to add correct CLASSPATH into run-time scripts
-->
<dirname property="common-ant-script.basedir" file="${ant.file.common-maven-in-ant}" />
<target name="dependencies" depends="init">
<copy file="${common-ant-script.basedir}/settings-m2-syscon-common.xml"
   tofile="${shared.build.dir}/.m2/settings.xml">
<filterset>
 <filter token="shared.build.dir" value="${shared.build.dir}"/>
</filterset>
</copy>

<maven:dependencies   pathId="dependency.classpath"
                   filesetId="dependency.fileset"
    settingsFile="${shared.build.dir}/.m2/settings.xml" >
<pom refid="maven.pom" />
<remoteRepository refid="repo.syscon.url" />
</maven:dependencies>
</target>

<!-- This definition includes all the dependencies in pom.xml already.
Overwrite "classpath" definition ONLY when necessary.
NOTE: any target referring to this "classpath" must depend on "dependencies" target
-->
<path id="classpath">
<path refid="dependency.classpath" />
<pathelement path="${classes.dir}"/>
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${deploy.dir}">
<include name="**/*.jar"/>
</fileset>
</path>

<target name="get-lib-by-maven" depends="dependencies">
<copy todir="${lib.dir}" flatten="true">
<fileset refid="dependency.fileset" />
</copy>
</target>

<!--
Compiles local src directory to classes directory in shared build.
Then call a target that hooks into your local post compile process.
-->
<property name="src.dir" value="src" />
<target name="compile" depends="init, get-lib-by-maven">
<javac destdir="${classes.dir}" classpathref="classpath">
<src path="${src.dir}" />
</javac>
<antcall target="post-compile" />
</target>
<target name="post-compile" description="Hook into local build for post compile processing." />

<!-- Target for sharing the artifact locally to other project components as dependency -->
<target name="share-local">
<maven:install file="${sjs-artifact}"
   settingsFile="${shared.build.dir}/.m2/settings.xml">
<pom refid="maven.pom"/>
</maven:install>
</target>
</project>

Simple steps to utilize above common scripts:

1. Create a pom.xml file for your project to define your direct dependencies:
Following are key format & elements of a pom. (a working copy pom.xml)
pom.xml

4.0.0
RMS Core Module


syscon.rms
sjs-rms-core
1.0







org.hibernate
hibernate-entitymanager
3.3.1.ga
compile



javax.mail
mail
1.4
compile



junit
junit
4.3.1
test



com.oracle
ojdbc14
10.2.0.2.0
runtime



log4j
log4j
1.2.14
runtime






syscon.common
sjs-common-util
1.0
compile







Note:



  • the pom.xml file
    must be in the same directory as the build.xml file.


  • Additional settings in build.xml if
    your project used sjs internal dependencies such as, a. sjs-common-util
    Make your "post-init" target depends on "compile-common-util".


  • ...



b. sjs-common-action Make your "post-init" target depends on
"compile-common-action".


...


Please refer
to http://maven.apache.org/maven-v4_0_0.xsd
for more details.

2. Run ant
build task as usual. e.g.

ant jar

One extra
benefit is to get library jars easier by one command:

ant get-lib-by-maven



Bottom of Form

Artifactory
use Derby as database by default. Syscon has SQL-Server production
database already and the most important is that the backup machenism is
there
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalready.

Quick two
steps to get it work from original zip file:

1. Replace the
content of repo.xml (inside
webapps\artifactory.war\WEB-INF\lib\artifactory-core-1.2.5-rc6.jar\jcr\repo.xml
inside artifactory-1.2.5-rc6.zip) with the content of attached http://info/download/attachments/7962830/repo.xml.sql-server(note: change all "???" to real password)

2. Include a
SQL-Server JDBC driver file into webapps\artifactory.war\WEB-INF\lib

Following are
related information.

A. Artifactory


A1. JCR API


A2. JCR Implementation


A3. Default DB: Derby

This is the
part to be replaced by SQL-Server.

A4. Switch to SQL-Server



  • Configuring
    Jackrabbit
    use SimpleDbPersistenceManager to replace DerbyPersistenceManager


  • Tricky is all in repo.xml
    ( plus a jdbc driver for sqlserver)

core/src/main/resources/jcr/repo.xml
inside svn source or webapps\artifactory.war\WEB-INF\lib\artifactory-core-1.2.5-rc6.jar\jcr\repo.xml
inside artifactory-1.2.5-rc6.zip or it could be /jcr/repo.xml under WEB-INF/classes or any classpath
preceeding WEB/INF/lib

A5. Issues TBD:



  • How to pass
    variables value into the repo.xml config file? db.server.name,
    db.server.port, db.name, db.user, db.password option 1. Hard code in
    the source code. option 2. Write a script to update at build / deploy
    time.



  • Move Web UI users data to
    sqlserver too? Requires more research effort related to: org.springframework.jdbc.datasource.DriverManagerDataSource



  • The link for deploy is available
    to Reader/Search only user, the permission check is done after the user
    uploaded the jar file and then get error message: Not enough permissions to deploy
    artifact 'org.jfrog:artifactory:zip:1.2.5-rc6'.

B. SQL-SERVER


B1. DB Info:



  • Server: sqlsrv01


  • User: artifactory


  • Database: repo (set owner to
    "artifactory" user so that the db schema could be created
    automatically) (Note: SQL-Server default installation disabled TCP/IP
    protocal, use SQLServer Configuration Manager to enable it.)

B2. JTDS JDBC Driver

C.
Artifactory database switch architect diagram



Bottom of Form


Step 0.
Do a search first to see if the jar is already in Syscon internal repo.

Login as
"search" Username: search Password: password

Click "Search
for Artifacts" in the left side Enter the name of the jar and click the
"Go!" button

Step 1.
Prepare to deploy a 3rd party jar into the repo Pre-condition: the 3rd
party jar file has been downloaded and verified. (e.g. to deploy
'icefaces-1.7.0.DR2.jar' )

Login as
"admin" Username: admin Password: xxxxxxxxx (set by the administrator)

Click "Deploy
an Artifact"

Step 2.
Upload and deploy the pom file (optional if the 3rd party jar has no
dependency itself) (e.g. 'icefaces-1.7.0.DR2.pom') Note: Verify to make
sure: a. the value of "GroupId" is same as defined in the pom. b. the
value of "Packaging" is "pom". c. the checkbox "Use Jar POM/Generate
default POM" is UNCHECKED. Tip: Copy the value of the "GroupId". It will
be used in the next step. Click "Deploy" button.

Step 3.
Upload and deploy the jar file (e.g. 'icefaces-1.7.0.DR2.jar' )

Note&Tip: paste the value of "GroupId" from step 2. Verify and/or
correct the values of "ArtifactId", "Version" to make sure it's proper.
IMPORTANT: Leave the "Use Jar POM/Generate default POM" check-box as is.
Do NOT change it. Click "Deploy" button.

Step 4.
Last but not least, verify the jar is in the repo and the pom is
correct. Click "Browsing" ==> "Repositories Tree" and navigate to the
jar file through package names

Right click on
the pom file and select "View" from the popup menu.

Verify the pom
file content is correct. (the values of "groupId", "artifactId",
"version", etc.. and dependencies reference included.)

录近作 - 1 (和春温哥华 2008.4)

和春温哥华

望穿樱树雪山现
温市花色宜赏析
梦回故国真情存
老屋竹香堪追忆


* 老姐在深圳发来咏春诗句感叹应景:

满眼不堪三月喜
举头已觉千山绿

读之尤似身临其境, 遂赋一首应景回应. 字句难工, 聊表情意而已.

* 温哥华到处可见樱树, 三四月间速开速落, 可谓温市一大春景. 而北面雪山环抱, 非至七八月积雪不化. 春夏季节花色雪光辉映, 惟叹词穷而已.

* 小时老屋后长有一大片竹林, 密密实实, 雀虫獾兽共聚, 是儿时掏鸟窝, 粘知了的不二宝地. 每当初春新笋破土发芽, 淡淡清香非我文字所能描述.

==========

录近作 - 0 (太极歌 2006.8)

太极歌

太极本无极
先贤亦无系
巧思复勤勉
立身天地气
招式可另创
心胸必开放
王廷开局明
露禅有灵性
鉴泉兼并蓄
精简大普及
三丰虽传奇
精义自飘絮
阴阳转虚实
五行换八卦
柔极克刚强
四两拨千斤
筋髓皆可易
自然意合一
天地有正气
混元出太极

==========

录旧作 - 1 (戏赏武大樱花 1995)

听课

???????
???????
听课坐爱夫子痴
又是樱花烂漫时


* 当年单位组织青年员工业余在武汉大学求学经济,难得碰上位中年老夫子备课及其认真严谨,教授借贷平衡关系一丝不苟,尤其准备的课余作业题说明清晰明了,一片痴心200%弥补了无法活跃课堂气氛的不足。

==========



折枝

双双对对步行迟
个个眼中似韵诗
忽闻保安声呵斥
落荒而逃已折枝
==========



无题

只羡蜜蜂不羡仙
无阻少滞游花间
可恨凡夫空多情
美意当前语犹腼

==========

录旧作 - 0 (三峡组诗 1995~1996?)

夜上三峡

残月当空悬
峭壁立两肩
险关重重过
蜀藏尽在握

==========



夜出三峡

一轮明月映江心
两岸风景寂无声
三更灯火五更笛
十分想念还是你

==========



三峡情

瞿塘雄关三度游
最是知音不可求
巴山柿红艳无方
相遇相知难相守

==========