How to include jars in lib into project jar file in Netbeans? - netbeans

I'm using some apache HttpClient jars, so I put them in my project's lib directory, when Netbeans compiles the project, it copies the lib and generated a project jar into dist directory, but when I run my project with webstart, I need to copy the project jar and lib into tomcat's ROOT dir, I wonder if Netbeans can generate a project jar that includes all the jars in the lib dir, so I don't have to copy the project jar and the lib dir into tomcat's ROOT dir. Can Netbeans do that ?

That's really easy to package every dependent library (*.jar) into one single myProject.jar.
Just follow these steps and you will finally pack every dependent library into single jar. If you are using NetBeans then you can follow exactly or else you need to find your build.xml file in project files.
Follow these steps to edit build.xml
1) Click on Files tab on the left side of the project panel in NetBeans.
2) Double click on the build.xml file and add these lines in it just before </project> line
<target name="package-for-store" depends="jar">
<property name="store.jar.name" value="myProject"/>
<property name="store.dir" value="store"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${store.dir}"/>
<mkdir dir="${store.dir}"/>
<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<zip destfile="${store.jar}">
<zipfileset src="${store.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete file="${store.dir}/temp_final.jar"/>
</target>
3) Change value in second line of the code as per your project name which is
<property name="store.jar.name" value="myProject"/> //<---Just value not name
4) Save it and right click on build.xml and choose Run Target and then Other Targets and finally click on Package-for-store
5) And here you done. Now you can go and check just like dist folder there will be a store folder which will be containing your final complete jar including all of your dependent libraries. Now whenever you want to change / add more libraries or so, just follow step 4.
Picture for step 4

OK, found the answer at the following site : http://arunasujith.blogspot.com/2011/08/how-to-build-fat-jar-using-netbeans.html

Robert Eckstein describes a solution for this problem. You just need to paste the following code to build.xml. The libraries are all found automatically.
Here we go:
<target name="-post-jar">
<!-- Change the value to the name of the final jar without .jar -->
<property name="store.jar.name" value="MyJarName"/>
<!-- don't edit below this line -->
<property name="store.dir" value="dist"/>
<property name="temp.dir" value="temp"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${temp.dir}"/>
<mkdir dir="${temp.dir}"/>
<jar destfile="${temp.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<delete dir="${store.dir}"/>
<zip destfile="${store.jar}">
<zipfileset src="${temp.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete dir="${temp.dir}"/>
</target>
Go to your build.xml, and add the code right before the closing project tag at the end.
Now change the value of the first propertiy field as commented
Click Clean & Build, and your jar will be in the dist folder
Reference link:
https://stackoverflow.com/a/30172829/2761273

check MainClass main file is updated as main file in Properties>run
Update Build.xml with following code before project tag closes
<!-- Change the value to the name of the final jar without .jar -->
<property name="store.jar.name" value="MyJarName"/>
<!-- don't edit below this line -->
<property name="store.dir" value="dist"/>
<property name="temp.dir" value="temp"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${temp.dir}"/>
<mkdir dir="${temp.dir}"/>
<jar destfile="${temp.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<delete dir="${store.dir}"/>
<zip destfile="${store.jar}">
<zipfileset src="${temp.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete dir="${temp.dir}"/>
Properties>packaging> tick all
clean and build
Upload to server.

Okay, so this is my solution. I too had the problem with my program compiling and running on Netbeans but it failing when I tried java -jar MyJarFile.jar. Now, I don't fully understand Maven and I think this why was having trouble getting Netbeans 8.0.2 to include my jar file in a library to put them into a jar file. I was thinking about how I used to use jar files with no Maven in Eclipse.
It's Maven that compiles all the dependencies and plugins, not Netbeans. (If you can get Netbeans to do this please tell us how.)
[Solved - for Linux] by opening a terminal.
Then
cd /MyRootDirectoryForMyProject
Next
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Next
mvn install
This will create jar file in the target directory.
MyJarFile-1.0-jar-with-dependencies.jar
Now
cd target
(You may need to run: chmod +x MyJarFile-1.0-jar-with-dependencies.jar)
And finally
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Please see
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException

Related

Missing output files after running Ant script from Eclipse

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?

How to combine 3 steps in ant build.xml into one step for Netbeans to generate a signed jar to run in web start?

My web start app ran fine, but I realized there is a lib dir I need to copy into the tomcat ROOT dir in order for my web start app to work, but I want to just combine all my jars into one big jar so I just need to copy one file each time I update the project. I searched on the web and found a solution to combine all jars into one, with the following step, which was mentioned at : http://arunasujith.blogspot.com/2011/08/how-to-build-fat-jar-using-netbeans.html
I rewrote my build.xml to look like this :
<project name="Test_Tool" default="default" basedir=".">
<description>Builds, tests, and runs the project Test_Tool.</description>
<import file="nbproject/build-impl.xml"/>
<target name="package-into-one-jar" depends="jar">
<property name="store.jar.name" value="Test_Tool"/>
<!-- don't edit below this line -->
<property name="store.dir" value="dist"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest><attribute name="Main-Class" value="${main.class}"/></manifest>
</jar>
<zip destfile="${store.jar}"><zipfileset src="${store.dir}/temp_final.jar" excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/></zip>
<delete file="${store.dir}/temp_final.jar"/>
<delete dir="${store.dir}/lib"/>
</target>
</project>
But when I ran it, it said there are some files unsigned, and can't run from html page, so I did some more search and found a way to sign the jar file, which is mentioned at : http://www.asjava.com/ant/how-do-i-sign-jar-files-in-ant/
So I've come up with an script [ sign_jar.xml ] look like this :
<?xml version="1.0"?>
<project name="ant to create keystore and sign jars" default="signjars" basedir=".">
<tstamp/>
<property name="build.output.dir" value="C:/Dir_Test_Tool/dist"/>
<property name="build.classes.dir" value="C:/Dir_Test_Tool/dist"/>
<property name="verisign.key.store" value="${build.output.dir}/.keystore"/>
<property name="verisign.key.storepass" value="asjava.com"/>
<property name="verisign.key.alias" value="asjava"/>
<property name="verisign.key.pass" value="asjava.com"/>
<target name="signjars">
<mkdir dir="${build.output.dir}"/>
<genkey alias="${verisign.key.alias}" verbose="true" storepass="${verisign.key.storepass}"
keypass="${verisign.key.pass}" validity="365" keystore="${verisign.key.store}">
<dname>
<param name="CN" value="AsJava.com Group"/>
<param name="OU" value="Jim"/>
<param name="O" value="AsJava.com"/>
<param name="C" value="US"/>
</dname>
</genkey>
<signjar jar="${build.classes.dir}/Test_Tool.jar"
signedjar="${build.output.dir}/Test_Tool.jar"
alias="${verisign.key.alias}"
storepass="${verisign.key.storepass}"
keystore="${verisign.key.store}"
keypass="${verisign.key.pass}"/>
</target>
</project>
After all the changes, I needed to do the following to get the signed big jar file :
<1> Build my project in Netbeans
<2> In files view of the project right click build.xml file and then select Runtarget >> Other Targets >> package-into-one-jar
<3> In files view of the project right click sign_jar.xml file and then select Runtarget >> signjars
Now it works as I wished : One big jar that is signed.
But that's 3 steps in order to achieve this, there must be an easier way, why can't it be done in one step ? So I combined the above files into one, which looked like this :
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test_Tool" default="default" basedir=".">
<description>Builds, tests, and runs the project Test_Tool.</description>
<import file="nbproject/build-impl.xml"/>
<target name="package-into-one-jar" depends="jar">
<property name="store.jar.name" value="Test_Tool"/>
<property name="store.dir" value="dist"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest><attribute name="Main-Class" value="${main.class}"/></manifest>
</jar>
<zip destfile="${store.jar}"><zipfileset src="${store.dir}/temp_final.jar" excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/></zip>
<delete file="${store.dir}/temp_final.jar"/>
<delete dir="${store.dir}/lib"/>
</target>
<property name="build.output.dir" value="c:/asjava"/>
<property name="build.classes.dir" value="C:/Dir_Test_Tool/dist"/>
<property name="verisign.key.store" value="${build.output.dir}/.keystore"/>
<property name="verisign.key.storepass" value="asjava.com"/>
<property name="verisign.key.alias" value="asjava"/>
<property name="verisign.key.pass" value="asjava.com"/>
<target name="signjars">
<mkdir dir="${build.output.dir}"/>
<genkey alias="${verisign.key.alias}" verbose="true" storepass="${verisign.key.storepass}"
keypass="${verisign.key.pass}" validity="365" keystore="${verisign.key.store}">
<dname>
<param name="CN" value="AsJava.com Group"/>
<param name="OU" value="Jim"/>
<param name="O" value="AsJava.com"/>
<param name="C" value="US"/>
</dname>
</genkey>
<signjar jar="${build.classes.dir}/Test_Tool.jar"
signedjar="${build.output.dir}/Test_Tool.jar"
alias="${verisign.key.alias}"
storepass="${verisign.key.storepass}"
keystore="${verisign.key.store}"
keypass="${verisign.key.pass}"/>
</target>
</project>
But the strange thing is : now it copies all the compiled directories under src into dist, if I delete them the result big jar won't run, I don't know ant good enough to correctly combine the above 3 steps into one, and don't know Netbeans enough to solve this problem, can someone help ?

How to export my eclipse java project to the remote server as a runnable jar?

Is there a way to export my eclipse java project as a runnable jar to my remote server directly from eclipse. Can this be done using Ant?
Yes this can be done by ant. Use the jar task to create a jar and the scp task to transfer your jar to a server.
Some examples:
<target name="jar" depends="compile">
<mkdir dir="${dist}" />
<jar jarfile="${dist}/myjar.jar" basedir="${target}">
<fileset dir="${source}">
<include name="**/*.gif" />
<include name="**/*.properties" />
</fileset>
</jar>
</target>
<target name="dist" depends="jar" >
<scp file="${dist}/myjar.jar" trust="true" keyfile="/tmp/keyfile.openssh" todir="user#server:/directory" passphrase="phrase" />
</target>
You could add a network driver mapping, then export it to remote server like local.

Folder with jars in project

When I work on small desktop projects I used to create lib folder in my project's root where I keep all project's jar dependencies. Then I use Configure Build Path -> Libraries -> Add JARs... to manually add all jars from this folder to buildpath/classpath. And because Add JARs... (unlike Add external JARs) uses relative paths, the project is portable, what is important for me.
The problem is that each time I add or remove a jar from my lib folder I need to manually add/remove this jar in project buildpath settings (and of course I often forget to do so).
Is there a way to just inform Eclipse that "This is a folder where I keep all of my jars. Please, add all the jars from there automatically to buildpath/classpath"? I tried to treat this folder as a class folder (Add class folder...) but it doesn't work that way :(.
P.S. I know about Maven and Eclipse-Maven integration but I want to keep my small project's simple (Maven integration is sometimes frustrating so I prefer to avoid it in these projects), so please don't suggest this in answer. Also as I mentioned, these are desktop projects, so there is no WEB-INF/lib folder in my project that is usually automatically handled by Java EE plugins.
you can try with a classpath container, take a look here for an example .
Take a look also at the Apache IvyDE classpath container .
However adding a new library to the classpath is simple and quick as :
Right click on it ---> Build Path ---> Add To Build Path
EDIT
This lightweight plugin should do exactly what you want !
I am not too sure, but can't you have wildcards in your classpath? That way you could just edit your .classpath file for that Eclipse project and use * within a particular folder... I have not tried, i'm in a rush but that's my idea... don't know if works
EDIT here is something that you could find useful:
How to use a wildcard in the classpath to add multiple jars?
Basically, just edit your .classpath file, which is where Eclipse stores the classpath settings for a project
I think the best is to use Gradle. This does not have the frustration of Maven with Eclipse. If you use STS it comes with Gradle pre-bundled.
See the link
So yeah I did this before:
Use Apache Ant and specify an ant configuration that suits your build path and eclipse should be able to use it with the use from existing ant build option.
Here is an example ant file you might have:
<?xml version="1.0"?>
<project name="Demo Project" basedir="." default="package">
<!-- ================================================================= -->
<!-- C O N F I G U R A T I O N -->
<!-- ================================================================= -->
<!--
Access the environment properties
-->
<property environment="env" />
<!--
TODO: Access the environment properties with a prefix of "env".
-->
<!--
Additional 3rd-party tools
-->
<property name="ant.home" value="${env.ANT_HOME}"/>
<property name="junit.home" value="${env.JUNIT_HOME}"/>
<property name="jmock.home" value="${env.JMOCK_HOME}"/>
<!--
Project folders
-->
<property name="project.home" value="${basedir}" />
<property name="bin.dir" value="${project.home}/bin" />
<property name="dist.dir" value="${project.home}/dist" />
<property name="dist.file" value="${dist.dir}/lab03.jar" />
<property name="col.file" value="${dist.dir}/lab03-col.jar" />
<property name="src.dir" value="${project.home}/src" />
<property name="lib.dir" value="${project.home}/lib" />
<!--
TODO: Define the classpath to be used during compilation. This should
consist of all of the JAR files in the ${lib.dir} folder.
-->
<path id="project.class.path">
<path location="${dist.file}" />
<path location="${bin.dir}" />
<fileset dir="${junit.home}">
<include name="junit-4.7.jar"/>
</fileset>
<fileset dir="${jmock.home}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${ant.home}/lib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<!--
TODO: Define the classpath to be used during execution. This should
consist of all of the JAR files in the ${lib.dir} folder as well as
${dist.file}.
-->
<path id="execution.class.path">
<path location="${bin.dir}" />
<path location="${bin.dir}/MyPath1/MyPath" />
<path location="${bin.dir}/MyPath1/MyPath/impl" />
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<!-- ================================================================= -->
<!-- C L E A N -->
<!-- ================================================================= -->
<target name="clean"
description="Clean all build products">
<delete dir="${bin.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- ================================================================= -->
<!-- C O M P I L E -->
<!-- ================================================================= -->
<target name="compile"
depends="clean,init"
description="Compiles the application code">
<!--
TODO: Add the javac task. It should compile everything in ${src.dir}
and place the output in ${bin.dir}. The classpath should refer to the
"project.class.path" defined above.
-->
<javac srcdir="${src.dir}"
destdir="${bin.dir}">
<classpath refid="project.class.path" />
</javac>
</target>
<!-- ================================================================= -->
<!-- E N V -->
<!-- ================================================================= -->
<target name="env"
description="Displays information about the build">
<echo message="src.dir..........${src.dir}" />
<echo message="lib.dir..........${lib.dir}" />
<echo message="bin.dir..........${bin.dir}" />
<echo message="dist.dir.........${dist.dir}" />
<echo message="dist.file........${dist.file}" />
<echo message="col.file.........${col.file}" />
<echo message="reports.dir......${reports.dir}" />
</target>
<!-- ================================================================= -->
<!-- I N I T -->
<!-- ================================================================= -->
<target name="init"
depends="env"
description="Initializes the environment">
<mkdir dir="${bin.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<!-- ================================================================= -->
<!-- P A C K A G E -->
<!-- ================================================================= -->
<target name="package"
depends="compile"
description="Creates the application distribution file">
<!--
TODO: Create a JAR file. The target JAR should be ${dist.file} and it
should contain everything from ${bin.dir}.
-->
<jar destfile="${dist.file}"
basedir="${bin.dir}"
excludes="**/*Test*.class"
/>
</target>
<!-- ================================================================= -->
<!-- P A C K A G E - C O L -->
<!-- ================================================================= -->
<target name="package-col"
depends="compile"
description="Creates the file to be submitted to COL.">
<jar destfile="${col.file}">
<fileset dir="${project.home}"
includes="src/**/*.java" />
<fileset dir="${project.home}"
includes="lib/**/*.jar" />
<fileset dir="${project.home}"
includes="build.xml" />
</jar>
</target>
<!-- ================================================================= -->
<!-- R U N -->
<!-- ================================================================= -->
<target name="run"
depends="package"
description="Executes the test file">
<java classname="MyPath1.MyPath.FileScanner">
<classpath refid="execution.class.path" />
<arg value="file:///" />
</java>
</target>
</project>
AND Here is a link with someone with a similair problem using ant to solve his classpath problems.
Ant is portable so it can actually be set up anywhere and you can also use global variables to keep all systems consistent or just use relative paths. And there is also an eclipse ant plugin
just try including
<classpathentry kind="lib" path="lib/spring/4.2.1" including="*.jar"/>

Java EE eclipse project directory structure?

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>