Ant: using war task on exploded directory - java

I am relatively new to Ant, and am trying to find the easiest way to WAR-up my web application.
I already have build targets that create the following "exploded WAR" directory structure:
MyApp/
src/
...
gen/ <-- this gets created as a part of every build
war/
stylesheets/
myapp.css
views/
index.jsp
cool.jsp
...
WEB-INF/
web.xml
lib/
(All of my dependencies)
classes/
META-INF/
jdoconfig.xml
com/
myapp/
(All compiled binaries)
So, given the fact that by the time I'm ready to create the WAR file (using <war/>, <zip/> or anything else), I already have the exploded version of the WAR ready to go.
The problem I have with the <war/> task is that it doesn't seem to support directories under war/ besides WEB-INF/lib and WEB-INF/classes:
<war destfile="myapp.war" webxml="gen/war/WEB-INF/web.xml">
<lib dir="gen/war/WEB-INF/lib" />
<classes dir="gen/war/WEB-INF/classes" />
</war>
What about stylesheets and views, or anything else I might want? What if I want to add a file or directory to WEB-INF/? What if I wanted to add something to the war at the same level as WEB-INF/? The <war/> task just seems to be too inflexible.
Either way (as I'm sure the task is flexible and I'm just not "getting" it), I just want the easiest way to create a myapp.war with the exact directory structure that the earlier build targets have created under gen/war. Thanks in advance.

You can use a fileset inside of the war tag
An Example from our build file
<war destfile="${war.dest.file.name.without.extension}.war" manifest="${build.dir}/MANIFEST.MF" webxml="${webcontent.dir}/WEB-INF/web.xml">
<fileset dir="${webcontent.dir}" casesensitive="no">
<exclude name="WEB-INF/lib/**"/>
<exclude name="WEB-INF/classes/**"/>
<exclude name="WEB-INF/web.xml"/>
<exclude name="META-INF/context.xml"/>
</fileset>
<lib dir="${app.lib.dir}"/>
<classes dir="${classes.dir}"/>
</war>

Figured it out, this is way easier. The <war/> task imposes too many constraints if you already have your own exploded war directory. Just zip it up!
<zip destfile="myapp.war"
basedir="gen/war" update="true" />

Related

How to create and copy templates in the war file using ant

I'm working on apache freemarker with jersey, we are gaving .ftl templates in template folder, when i trying to create a war file with template its not creating.
<target name="war" depends="clean,compile,copy-resources">
<war destfile="${dist}/sample.war" webxml="WEB-INF/web.xml">
<fileset dir="WebContent"/>
<webinf dir="WEB-INF" includes="**/log4j.properties"></webinf>
<lib dir="${lib}"/>
<classes dir="${build}"/>
<templates dir="${templates}"/>
</war>
</target>
When build this code it is saying
war doesn't support the nested "templates" element.
class and lib folder is adding but template folder not created in war file.
Thanks,
Praveen R.
Take a look at the war Task, and see the example in that page.
However you should use zipfileset to include your .ftl files in the war, here is how it should look like:
<zipfileset dir="${home.dir}/PATH_TO_FTL" includes="**/*.ftl" />
To create and copy the template folder use below code
<copy todir="${templates}">
To add this folder to war file use this code
<webinf dir="WEB-INF" includes="**/log4j.properties,templates/"></webinf>
This solved my problem.

Netbeans/java adding external config files

Based on this topic: Netbeans and external configuration files
I assume that what I want to do this is possible. But the answer is not really working for me.
The code is use know is from the last answer:
<target name="-pre-jar">
<echo>Copying resources files to build directory...</echo>
<mkdir dir="${dist.jar.dir}/resources"/>
<copy todir="${dist.jar.dir}/resources">
<fileset dir="resources" includes="**"/>
</copy>
</target>
But this just creates a dir named: ${dist.jar.dir} with my resources folder and files in it at the same location of my src,dist,build,nbproject folder. But I want it to be in dist, so my dist has, the jar, lib,webfiles and resources.
Thanks for any help and clarification.
If you want to copy all the contents of a specific directory to the \dist directory of the build you can do the following:
<target name="-pre-init">
<!-- Create a resource directory property -->
<property name="src.res.dir" value="${basedir}/res" />
</target>
<target name="-pre-jar">
<!-- Copy external resources folder -->
<copy todir="${build.classes.dir}\inside\res\dir">
<fileset dir="${src.res.dir}\inside\res\dir">
<include name="**/*" />
</fileset>
<copy>
</target>
This will copy the contents of a folder called \inside\res\dir inside of your projects $\res directory. I use this technique to include an application icon in the distribution.
You should then be able to access these resources from inside your application with something like the following:
ClassLoader.getSystemResource("inside/res/dir/file.ext")
Okay I solved it, so to copy a file, I placed the file in in a folder within src named resources with in there my file.
And then the following code does the trick:
<target name="-post-jar">
<copy file="${src.dir}/resources/filename.extension" flatten="true" todir="${dist.dir}/resources" />
</target>
Okay, for some reason my jar isn't being builded/updated any more if I use this in my build file..Anyone any clues?
solved needs to be "-post-jfx-jar" for jfx projects

removing junk folders from a war in build time

I have a web application done several years back, this is done using spring and javascript.
This project we build using the Jidea, IDE.
project have several theme folders which include large amount of images.
after the build the war is so heavy because of these large unused folders and other files.
my question is, is there a method, building tool we can use to remove these junk folders at the build time??
--Rangana
You can use build tools such as Maven or Ant. With these, you can specify exactly what you want to include and what you want to exclude in your war file.
Example with ANT :
<war destfile="dist/MyApp.war" webxml="WebContent/WEB-INF/web.xml">
<fileset dir="WebContent" />
<lib dir="WebContent/WEB-INF/lib" />
<classes dir="build/classes">
<exclude name="config.properties"/>
<include name="**\*.class"/>
<include name="**\*.xml"/>
<include name="**\*.pdf"/>
</classes>
<classes file="config/staging/config.properties"/>
</war>

Log4j not being added to classpath in Ant

I'm attempting to add Log4j to my project's classpath in Ant which creates an executable JAR, but it appears that it's not being added properly.
Here is the path component of my Ant build script:
<path id="classpath.compile">
<fileset dir="${dir.myLibs}">
<include name="**/*.jar"/>
</fileset>
<pathelement location="${dir.webContent}/WEB-INF/lib/log4j.jar" />
</path>
The compile target looks like this:
<target name="-compile">
<javac destdir="${dir.binaries}" source="1.6" target="1.6" debug="true" includeantruntime="false">
<src path="${dir.source}"/>
<classpath refid="classpath.compile"/>
</javac>
</target>
Tthe target that creates the JAR:
<target name="-createJar" >
<jar jarfile="${path.jarFile}"
manifest="${dir.source}\META-INF\MANIFEST.MF">
<fileset dir="${dir.binaries}" casesensitive="yes">
<exclude name="**/*.java"/>
</fileset>
</jar>
</target>
Lastly, the MANIFEST.MF:
Manifest-Version: 1.0
Class-Path: ../../../WebContent/WEB-INF/lib/log4j.jar (what is this pathing relative to?)
Main-Class: foo.Bar
The JAR is created, but when I execute it, I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger...
Any thoughts as to what I'm doing wrong?
It looks from the classpath in your MANIFEST that you are trying to reference a jar inside your jar. The only two ways to make that work AFAIK are 1) a special classloader, like #infosec812 mentions, or 2) by exploding the jar dependencies directly into the root of your jar. Either is workable, but I don't see either of them happening in your ant script.
If you're trying to reference a jar outside of your jar, your relative classpath is relative to the location of the jar you are executing. Make sure the referenced jar exists in that location.
I'm guessing that you're running the Java program as follows
java -jar myapp.jar
In this case you'll need to specify the Class-Path attribute in the manifest. I suggest you also check out the manifestclasspath task
Creating the jar does not include the linked libraries in the jar. You would have to have the required jars in your execution classpath in order to run it that way. Or, you could use the solution I use, which is to create a one-jar archive. It adds a specialized class loader for your application into the resulting jar and also packages your required jars in to the final executable jar. It works really well for deploying neat, simple to use packages.

Using ant war task to include files in WEB-INF directory

I'm using ant to build my web-app. I'm sure this is simple but I can't figure out how to tell ant to create a specific folder in the WEB-INF directory and copy files to it.
My ant war task looks like this:
<target name="warItUp" depends="compile">
<war destfile="MyApp.war" webxml="${home.dir}\WEB-INF\web.xml">
<classes dir="${classes.dir}"/>
<classes file="${src.dir}/hibernate.cfg.xml"/>
<classes dir="${src.dir}" includes="**/*.hbm.xml"/>
<!-- Include the PDF files -->
<fileset dir="${home.dir}/PDFs">
<include name="**/*.pdf"/>
</fileset>
<!-- Include the JSP files -->
<fileset dir="${home.dir}/JSPs">
<include name="**/*.jsp"/>
</fileset>
<!-- Include the images -->
<fileset dir="${home.dir}/images">
<include name="**/*"/>
</fileset>
</war>
All the fileset elements work i.e. they include the pdf, jsp and image files in the root directory of the war file.
But if I want to create a sub-directory in the WEB-INF directory of the war file and include files in it how do I specify that? e.g. say I wanted to include WEB-INF/TagLibraryDescriptors/MyTagLib.tld in the war file or if I wanted to create a WEB-INF/JSP folder in my war file and copy all JSP files to it.
Thanks.
OP here, thanks for all the responses. I found another solution - there is a webinf element that can be included in the war task.
This will copy files from the source JSPs folder into the WEB-INF folder in the war file:
<webinf dir="${home.dir}/JSPs"
includes="**/*.jsp">
</webinf>
whereas this will copy files from the source JSPs folder into the WEB-INF/JSPs folder (my preferred choice):
<webinf dir="${home.dir}"
includes="/JSPs/**/*.jsp">
</webinf>
I think I'll stick with this solution but thanks for the responses.
As an alternative to the nested webinf element, you can also use the zipfileset element, which lets you specify the source folder and the path prefix in the archive:
<zipfileset dir="${home.dir}/JSPs" includes="**/*.jsp" prefix="WEB-INF/JSPs"/>
Try to create this directory into your project and then just add fileset like the following:
<fileset dir="${home.dir}/WEB-INF/mydirectory/*">
<include name="**/*"/>
</fileset>
Why not creating the dir structure you need the mkdir way?

Categories

Resources