I have a simple web application developed in the Eclipse Luna. The directory structure of the application is like:
Project name is SchoolSchedule.
Under the project name, there are Java Resources, build, WebContent folders, and the build.xml file.
Under Java Resources, it is the "src" folder and my Java code package name is under the "src" folder.
Under the WebContent, there are META-INF, WEB-INF and my jsp files
Under the WEB-INF, there are web.xml file and the "lib" directory.
The build.xml is at the project root. This web application runs successfully and produces expected results.
I created an Ant script to compile, build a WAR file, and deploy the WAR. But, even the basic task does not work. I right click on the build.xml --> run as ... --> Ant build. In the console, I can see all the echo messages and no error. However, I do not see any new directories created (I "refresh" the project.). No "class" files compiled from the Java code and not to mention build and deploy those tasks.
There is something I did not get it right. Please help. Here is my Ant script:
<?xml version="1.0" encoding="UTF-8"?>
<project name="AntWarWebApp" basedir="." >
<echo>Define properties</echo>
<property name="name" value="SchoolSchedule"/>
<property name="src" location="src"/>
<property name="web" location="WebContent"/>
<property name="build" location="build"/>
<property name="classDir" location="${build}/src"/>
<property name="distDir" location="${build}/dist"/>
<property name="warDir" location="${build}/war"/>
<property name="tomcat.webapps" value="C:\apache-tomcat-7.0.70\webapps" />
<echo>time stamp</echo>
<tstamp prefix="build-info">
<format property="current-date" pattern="d-MMMM-yyyy" locale="en" />
<format property="current-time" pattern="hh:mm:ss a z" locale="en" />
<format property="year-month-day" pattern="yyyy-MM-dd" locale="en" />
</tstamp>
<echo>clean up previous build directories</echo>
<target name="clean" description="Delete old build directories">
<delete dir="${distDir}"/>
<delete dir="${warDir}"/>
<delete dir="${classDir}"/>
</target>
<echo>create directories</echo>
<target name="init" depends="clean">
<mkdir dir="${build}"/>
<mkdir dir="${classDir}"/>
<mkdir dir="${warDir}"/>
<mkdir dir="${distDir}"/>
<mkdir dir="${warDir}/WEB-INF"/>
<mkdir dir="${warDir}/WEB-INF/classes"/>
</target>
<echo>start compiling</echo>
<target name="compile" depends="clean, init" description="Compile main
source tree java files">
<javac srcdir="${src}" destdir="${classDir}" />
<classpath>
<fileset dir="${basedir}/WebContent/WEB-INF/lib">
<include name="*" />
</fileset>
</classpath>
</target>
<echo>start building WAR file</echo>
<target name="buildwar" depends="clean, init, compile">
<war basedir="${wardir}" destfile="${distDir}/${name}.war"
webxml="${wardir}/WEB-INF/web.xml">
<webinf dir="${wardir}/WEB-INF/">
<include name="**/*.jar" />
</webinf>
<manifest>
<attribute name="Built-On" value="${build-info.current-date}" />
<attribute name="Built-At" value="${build-info.current-time}" />
</manifest>
</war>
</target>
<echo>end building WAR file</echo>
<target name="deploy" depends="init, compile, buildwar" description="Deploy application">
<delete dir="${tomcat.webapps}/*.war" />
<echo>copy WAR file to Tomcat deploy directory</echo>
<copy file="${distdir}/*.war" todir="${tomcat.webapps}" />
</target>
</project>
Aren't you supposed to have some kind of top-level element
<project>
....
</project>
around all this?
Related
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?
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>
`
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.
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.
I have jax-ws web service (jboss implementation) configured with annotation.
#WebService([...], wsdlLocation = "/WEB-INF/wsdl/service.wsdl")
The wsld file is included into war file. The war file is included into ear file, that is deployed on JBoss (version: 5.0.1.GA).
During deployment I receive error message like that:
"Could not find /WEB-INF/wsdl/service.wsdl in the additional metadatafiles!"
I tried to put the file in many places:
- META-INF folder of war file,
- META-INF folder of ear file,
- classpath of war file,
but I it didn't help.
Anyone knows how should I configure it?
i had the same problem and i solved like this:
#WebService(targetNamespace="http://my.app.it/", wsdlLocation = "WEB-INF/wsdl/additional.wsdl")
(WEB-INF not start with slash)
To address this issue, I placed the WSDLs into the jar file that I had created from the generated stubs. Then set the wsdllocation and all was good.
example of my ant target:
<target name="genclients" depends="clean, -createdirs">
<wsimport
fork="true"
xnocompile="true"
wsdl="${src.resource.dir}\${wsdl.name}"
wsdllocation="/resources/${wsdl.name}"
sourcedestdir="${src.generated.dir}"
verbose="true"
destdir="${target.classes.dir}"
keep="true"
extension="true"
debug="true"
package="com.fedex.ship.stub"
xadditionalHeaders="true"
binding="${basedir}/binding.xml"
>
<arg line="-mark-generated"/>
</wsimport>
<javac srcdir="${src.generated.dir}" destdir="${target.classes.dir}" includeantruntime="false" source="1.6" target="1.6" debug="true" deprecation="false" optimize="false" failonerror="true">
<include name="**/*.java"/>
</javac>
<copy todir="${target.classes.dir}" preservelastmodified="true" overwrite="true">
<fileset dir="${src.dir}" >
<include name="**/*.wsdl"/>
<include name="**/*.xsd"/>
</fileset>
</copy>
<pathconvert property="manifest.classpath" pathsep=" ">
<mapper>
<chainedmapper>
<flattenmapper />
</chainedmapper>
</mapper>
<path>
</path>
</pathconvert>
<mkdir dir="${target.classes.dir}/META-INF"/>
<manifest file="${target.classes.dir}/META-INF/manifest.mf">
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
<jar jarfile="${target.jar.dir}/${jar.name}" basedir="${target.classes.dir}" manifest="${target.classes.dir}/META-INF/manifest.mf" excludes=".settings,**/.svn"/>
<!--
<delete failonerror="false" includeEmptyDirs="true">
<fileset dir="${target.classes.dir}"/>
</delete>
-->
</target>
I currently configured a jenkins server that validates my project on javascript errors with JSlint ( with ant). Now i want to show all the errors with the violation plugin. I can generate an xml with all the errors. But it doesn't show this in the graph.
This is my build.xml:
<?xml version="1.0" encoding="UTF-8"?>
<taskdef name="jslint"
classname="com.googlecode.jslint4java.ant.JSLintTask"
classpath="jslint/jslint4java-2.0.2.jar" />
<property name="reports.dir" value="reports" />
<target name="clean" description="Removes output files created by other targets.">
<delete dir="${reports.dir}" failonerror="true" />
</target>
<target name="jslint" depends="clean">
<mkdir dir="reports" />
<jslint options="white,undef,plusplus,newcap,vars,indent=4">
<predef>jQuery, setTimeout, history, window, document</predef>
<formatter type="xml" destfile="jslint_results.xml"/>
<fileset dir="" includes="**/*.js" excludes="lib/*.js" />
</jslint>
</target>
This is my violations setting:
The pattern is relative to your workspace. So if your report 'lives' in <WORKSPACE>/reports the pattern should be reports/jslint_results.xml or **/jslint_results.xml
I'm able to run an Ant build from Eclipse by right clicking and selecting Ant Build.
When I attempt to execute the same build by running Ant from cmd I get results that the "Build Was Successful" but nothing is built.
Build.xml file
<property name ="build.dir" value="${basedir}/build"/>
<property name="lib.dir" value="${basedir}/lib"/>
<property name="src.dir" value="${basedir}/src"/>
<property name="name" value="value"/>
<target name="setClassPath">
<path id="classpath_jars">
<path id="${basedir}/"/>
<fileset dir="${lib.dir}" includes="*.jar"/>
</path>
<pathconvert pathsep=":" property="test.classpath" refid="classpath_jars"/>
</target>
<target name="loadTestNG" depends="setClassPath">
<taskdef resource="testngtasks" classpath="${test.classpath}"/>
</target>
<target name="init">
<mkdir dir="${build.dir}"/>
</target>
<target name="clean">
<echo message="deleting existing build directory"/>
<delete dir="${build.dir}"/>
</target>
<target name="compile" depends="clean, init, setClassPath, loadTestNG">
<echo message="classpath: ${test.classpath}"/>
<echo message="compiling..."/>
<javac destdir="${build.dir}" srcdir="${src.dir}" classpath="${test.classpath}" encoding="cp1252"/>
</target>
<target name="run" depends="compile">
<testng classpath ="${test.classpath}:${build.dir}">
<xmlfileset dir="${basedir}" includes="testng.xml"/>
</testng>
</target>
</project>
And the Testng.xml
<suite name="Regression Test Suite">
<test name="My Test">
<classes>
<class name="com.RegressionTest.Sometest"/>
</classes>
</test>
</suite>
I determined the issue. I did not indicate the default target in my Project set up. Eclipse IDE was able to compile but in the terminal I was only using ANT and not indicating which target to build. So it was "building" successfully because I did not tell it what to build.
I am attempting to setup a sample dynamic web project in Eclipse using Java EE, Spring and Maven (using Nexus repository manager). I was wondering if anybody knows the "best practice" directory structure that I should setup for an enterprise web app in Eclipse? Should I just stick with the default structure that is setup for me? I ask because looking around the internet I see wide variation (for instance, where the WEB-INF and META-INF folders are..if there is a 'war' directory etc.). Thanks!
If you use Maven, I'd warmly recommend to just follow Maven's convention. This is the "best practice" in Maven's world (and I don't see any good reasons to not do so, not following this advice will lead to more work).
One easy way to create a webapp project is to use the maven-archetype-webapp:
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp \
-DgroupId=com.mycompany.app \
-DartifactId=my-webapp \
-Dversion=1.0-SNAPSHOT
(You can paste this command "as is" in a Linux shell; on Windows, type everything on single line without the "\".)
And this is the structure you'll get:
my-webapp
|-- pom.xml
`-- src
`-- main
|-- resources
`-- webapp
|-- WEB-INF
| `-- web.xml
`-- index.jsp
This layout is compliant with Eclipse WTP (whatever plugin you're using for the Eclipse integration). Just import this project into Eclipse and there you go.
If you have more specific question, feel free to ask (for example, most of time you don't have to worry about the META-INF directory, but put it under src/main/resources if really you need to have it).
If you're using Maven, it's best to follow their convention.
If you're using Spring, you don't need an EAR. A WAR will do just fine.
A WAR file has a definite standard that you must follow. As long as you can generate a proper WAR file, you can use any directory structure for your source code that makes sense to you.
I use something like this:
/project
+---/src (.java)
+---/test (TestNG .java here)
+---/test-lib (testNG JAR, Spring test JAR, etc.)
+---/resources (log4j.xml, etc.)
+---/web (root of web content here)
+---+---/WEB-INF
+---+---+---/classes (compile .java to this directory)
+---+---+---/lib (JAR files)
I use IntelliJ, so it creates an exploded WAR file as output for me.
I have an Ant build.xml that generally follows the IntelliJ directory structure. You're welcome to crib it if you find it useful.
<?xml version="1.0" encoding="UTF-8"?>
<project name="xslt-converter" basedir="." default="package">
<property name="version" value="1.6"/>
<property name="haltonfailure" value="no"/>
<property name="out" value="out"/>
<property name="production.src" value="src"/>
<property name="production.lib" value="lib"/>
<property name="production.resources" value="config"/>
<property name="production.classes" value="${out}/production/${ant.project.name}"/>
<property name="test.src" value="test"/>
<property name="test.lib" value="lib"/>
<property name="test.resources" value="config"/>
<property name="test.classes" value="${out}/test/${ant.project.name}"/>
<property name="exploded" value="out/exploded/${ant.project.name}"/>
<property name="exploded.classes" value="${exploded}/WEB-INF/classes"/>
<property name="exploded.lib" value="${exploded}/WEB-INF/lib"/>
<property name="reports.out" value="${out}/reports"/>
<property name="junit.out" value="${reports.out}/junit"/>
<property name="testng.out" value="${reports.out}/testng"/>
<path id="production.class.path">
<pathelement location="${production.classes}"/>
<pathelement location="${production.resources}"/>
<fileset dir="${production.lib}">
<include name="**/*.jar"/>
<exclude name="**/junit*.jar"/>
<exclude name="**/*test*.jar"/>
</fileset>
</path>
<path id="test.class.path">
<path refid="production.class.path"/>
<pathelement location="${test.classes}"/>
<pathelement location="${test.resources}"/>
<fileset dir="${test.lib}">
<include name="**/junit*.jar"/>
<include name="**/*test*.jar"/>
</fileset>
</path>
<path id="testng.class.path">
<fileset dir="${test.lib}">
<include name="**/testng*.jar"/>
</fileset>
</path>
<available file="${out}" property="outputExists"/>
<target name="clean" description="remove all generated artifacts" if="outputExists">
<delete dir="${out}" includeEmptyDirs="true"/>
<delete dir="${reports.out}" includeEmptyDirs="true"/>
</target>
<target name="create" description="create the output directories" unless="outputExists">
<mkdir dir="${production.classes}"/>
<mkdir dir="${test.classes}"/>
<mkdir dir="${reports.out}"/>
<mkdir dir="${junit.out}"/>
<mkdir dir="${testng.out}"/>
<mkdir dir="${exploded.classes}"/>
<mkdir dir="${exploded.lib}"/>
</target>
<target name="compile" description="compile all .java source files" depends="create">
<!-- Debug output
<property name="production.class.path" refid="production.class.path"/>
<echo message="${production.class.path}"/>
-->
<javac srcdir="src" destdir="${out}/production/${ant.project.name}" debug="on" source="${version}">
<classpath refid="production.class.path"/>
<include name="**/*.java"/>
<exclude name="**/*Test.java"/>
</javac>
<javac srcdir="${test.src}" destdir="${out}/test/${ant.project.name}" debug="on" source="${version}">
<classpath refid="test.class.path"/>
<include name="**/*Test.java"/>
</javac>
</target>
<target name="junit-test" description="run all junit tests" depends="compile">
<!-- Debug output
<property name="test.class.path" refid="test.class.path"/>
<echo message="${test.class.path}"/>
-->
<junit printsummary="yes" haltonfailure="${haltonfailure}">
<classpath refid="test.class.path"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.out}">
<fileset dir="${test.src}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="${junit.out}">
<fileset dir="${junit.out}">
<include name="TEST-*.xml"/>
</fileset>
<report todir="${junit.out}" format="frames"/>
</junitreport>
</target>
<taskdef resource="testngtasks" classpathref="testng.class.path"/>
<target name="testng-test" description="run all testng tests" depends="compile">
<!-- Debug output
<property name="test.class.path" refid="test.class.path"/>
<echo message="${test.class.path}"/>
-->
<testng classpathref="test.class.path" outputDir="${testng.out}" haltOnFailure="${haltonfailure}" verbose="2" parallel="methods" threadcount="50">
<classfileset dir="${out}/test/${ant.project.name}" includes="**/*.class"/>
</testng>
</target>
<target name="exploded" description="create exploded deployment" depends="testng-test">
<copy todir="${exploded.classes}">
<fileset dir="${production.classes}"/>
</copy>
<copy todir="${exploded.lib}">
<fileset dir="${production.lib}"/>
</copy>
</target>
<target name="package" description="create package file" depends="exploded">
<jar destfile="${out}/${ant.project.name}.jar" basedir="${production.classes}" includes="**/*.class"/>
</target>
</project>