3
votes

My Goal is to get a Enterprise Java Application to be built on Jenkins. The Application consists of 4 Projects (Client-Interfaces, Webapplcation (incl. Faces), EJB Application (incl. JPA), EAR-Container-Project).

When Eclipse deploys this projects to a glassfish server, it assembles the Webapplication (war-file), the Client-Interfaces (jar-file) and the EJB-Interfaces (jar-file) into one ear-File.

Now, if I want to use continous integration I need to achieve the same on the CI-Server jenkins.

My first idea was to solve this with ant, so I used the Export-Function of Eclipse and generated build-Files for the projects.

The Problem is that the generated Build-Files refer to the Java EE Libraries (such as Glassfish-Runtime, JPA-Library, etc) which are outside of the project directory. There are about 30 libraries.

This implies that I cannot use the file on jenkins, because this libraries are missing. Of course I can copy these, but I don't think this is how it should be done.

So, what is the best way to get the Java EE Enterprise Application to be built on the CI Server? Do I have to write the ANT-Script all by myself and copy the libraries into the project? Or am I Missing something obvious?

3

3 Answers

4
votes

Since I did not found anything that suited for me, I wrote an ant script that covered my needs on my own.

Here is my solution if this helps anyone in the future: `

<project basedir="." default="build" name="Project">

<available property="glassfishdir" value="/opt/glassfish3/glassfish/modules" 
         file="/opt/glassfish3/glassfish/modules" type="dir" />

<!-- ########### Property Declarations ###################################################################################################################  -->
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<property name="builddir" value="build" />
<property name="outputartifacts" value="out" />

<property name="web.name" value="ProjectWeb" />
<property name="web.projectpath" value="ProjectWeb"/>
<property name="web.src" value="${web.projectpath}/src" />
<property name="web.builddir" value="${builddir}/web" />
<property name="web.builddir.classes" value="${web.builddir}/WEB-INF/classes"/>

<property name="ejb.name" value="ProjectEJB" />
<property name="ejb.projectpath" value="ProjectEJB"/>
<property name="ejb.src" value="${ejb.projectpath}/src"/>
<property name="ejb.builddir" value="${builddir}/ejb" />
<property name="ejb.builddir.classes" value="${ejb.builddir}/classes" />

<property name="ejbclient.name" value="ProjectEJBClient" />
<property name="ejbclient.projectpath" value="ProjectEJBClient"/>
<property name="ejbclient.src" value="${ejbclient.projectpath}/src"/>
<property name="ejbclient.builddir" value="${builddir}/ejbclient" />
<property name="ejbclient.builddir.classes" value="${ejbclient.builddir}/classes"/>

<property name="ear.name" value="ProjectApplication" />
<property name="ear.dir" value="ProjectEAR" />

<!-- ########### Main Targets ###################################################################################################################   -->
<target name="build" depends="create-ear">
</target>

<target name="clean-build">
    <antcall target="clean" />
    <antcall target="build" />
</target>

<target name="clean">
    <delete dir="${builddir}"/>
    <delete dir="${outputartifacts}"/>
</target>

<target name="init">
    <mkdir dir="${outputartifacts}" />
</target>

<!-- ########### EJB App ###################################################################################################################    -->
<target name="init-ejb" depends="init">
    <mkdir dir="${ejb.builddir}" /> 
    <copy includeemptydirs="false" todir="${ejb.builddir.classes}">
        <fileset dir="${ejb.src}">
            <exclude name="**/*.java"/>
        </fileset>
    </copy>
</target>
<target name="build-ejb" depends="init-ejb">
    <javac debug="true" debuglevel="${debuglevel}" destdir="${ejb.builddir.classes}" includeantruntime="false" source="${source}" target="${target}">
        <src path="${ejb.src}"/>
        <classpath>
            <fileset dir="${glassfishdir}">
                <include name="**/*.jar"/>
            </fileset>  

            <fileset dir="${outputartifacts}">
                <include name="**/*.jar"/>
            </fileset>                  
        </classpath>
    </javac>
</target>

<!-- ########### WEB ###################################################################################################################    -->
<target name="init-web" depends="init">
    <mkdir dir="${web.builddir.classes}"/>  
    <copy includeemptydirs="false" todir="${web.builddir}">
        <fileset dir="${web.projectpath}/WebContent">
        </fileset>
    </copy>
    <copy includeemptydirs="false" todir="${web.builddir.classes}">
        <fileset dir="${web.src}">
            <exclude name="**/*.java"/>
        </fileset>
    </copy>
</target>

<target depends="init-web,create-ejb-client" name="build-web">
    <javac debug="true" debuglevel="${debuglevel}" destdir="${web.builddir.classes}" includeantruntime="false" source="${source}" target="${target}">
        <src path="${web.src}"/>
        <classpath>
            <fileset dir="${glassfishdir}">
                <include name="**/*.jar"/>
            </fileset>
            <fileset dir="out/">
                <include name="**/*.jar"/>
            </fileset>  
        </classpath>
    </javac>
</target>
<!-- ############## EJB CLIENT ################################################################################################################ -->
<target name="init-ejb-client" depends="init">
    <mkdir dir="${ejbclient.builddir}"/>
    <copy includeemptydirs="false" todir="${ejbclient.builddir.classes}">
        <fileset dir="${ejbclient.src}">
            <exclude name="**/*.java"/>
        </fileset>  
    </copy>
</target>


<target depends="init-ejb-client" name="build-ejb-client">
    <javac debug="true" debuglevel="${debuglevel}" destdir="${ejbclient.builddir.classes}" includeantruntime="false" source="${source}" target="${target}">
        <src path="${ejbclient.src}"/>
        <classpath>
            <fileset dir="${glassfishdir}">
                <include name="**/*.jar"/>
            </fileset>          
        </classpath>
    </javac>
</target>


<!-- ############ CREATE ARCHIVES################################################################################################################## -->
<target name="create-web" depends="build-web">
    <war destfile="${outputartifacts}/${web.name}.war" basedir="${web.builddir}" webxml="${web.projectpath}/WebContent/WEB-INF/web.xml"/>
</target>

<target name="create-ejb-client" depends="build-ejb-client">
    <jar destfile="${outputartifacts}/${ejbclient.name}.jar" basedir="${ejbclient.builddir.classes}" includes="**/*"/>
</target>

<target name="create-ejb" depends="build-ejb">
    <jar destfile="${outputartifacts}/${ejb.name}.jar" basedir="${ejb.builddir.classes}" includes="**/*">
        <manifest>
            <attribute name="Class-Path" value="${ejbclient.name}.jar"/>
        </manifest>
    </jar>
</target>

<target name="create-ear" depends="create-ejb-client,create-web,create-ejb">
    <ear destfile="${outputartifacts}/${ear.name}.ear" appxml="${ear.dir}/EarContent/META-INF/application.xml">
        <fileset dir="${outputartifacts}" includes="*.jar,*.war"/>
    </ear>
</target>


</project>

`

0
votes

Use Maven.
Maven allow to define all dependencies in a single xml file (pom), dependencies which will be automatically downloaded from internet at compilation phase.
Maven come with a set of plugin to facilitate continuous integration like being able to start a container, run the test and close it automatically. Maven integrate natively with jenkins.
Maven defines a complex lifecycle designed for this kind of problematic and allowing to compile, run unit test, package, run integration test and deploy with a single command triggered from jenkins;

Maven is definitively THE solution here.

0
votes

You can also auto-create the build.xml in Eclipse using "Export... > General\Ant Buildfile" from the project context menu. This way the correct classpath is generated to your JAR's already available in the project.

Chances are that if there are dependencies between the projects, you only need to configure one build file to be run on Jenkins, as it will automatically call the build files from the other projects.