removing junk folders from a war in build time - java

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>

Related

Java Ant Job how to ship Log4j jar with my jar

Just trying to upgrade some old stuff and part of that I need to bundle my custom jar which uses Log4j. I did add the following for my <javac> task which compiles successfully.
<path id="my.classpath">
<fileset dir="${mainpath}">
<include name="**/*log4j*.jar"/>
</fileset>
</path>
<javac srcdir="src/java" destdir="build/filez/java" debug="on" deprecation="no"
includes="my/instruments/**/*, org/apache/log4j/**/*">
<classpath refid="my.classpath"/>
</javac>
However, In my <jar> job I cannot see any log4j dependency packed with my custom jar. This might be a silly question, but how do ensure that my custom-jar does not fail when called from another application since the dependency isn't packed? Will it be okay as long as log4j has been loaded by classloader in the target application?
Additionally, do I need to add something in my Manifest for this?
I cannot use Maven (yes I know) for a little while, so cannot solve this problem with maven
You can use One-JAR to package your code along with it's dependencies into one big executable JAR.
It can be used either as a standalone tool from the command line or as a task defined in build.xml.
<!-- Construct the One-JAR file -->
<one-jar destfile="hello.jar" manifest="hello.mf">
<main>
<!-- Construct main.jar from classes and source code -->
<fileset dir="${classes.dir}/src"/>
</main>
<lib>
<fileset file="${build.dir}/lib.jar" />
</lib>
</one-jar>

Ant: using war task on exploded directory

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" />

Ant File, include another file

Let me describe the scenario first. I have a main build file called main_build.xml. This file calls 4 other build files defined for sub projects, copies the Jars generated by sub project builds and then creates a WAR and finally EAR.
I have my classpath dependencies defined in a XML file named my_clspath.xml.
Now I have two questions:
1. How do I include my_clspath.xml file within the main_build.xml?
2. After including the my_clspath.xml in main_build, how do I make the classpath available for all 4 sub builds which are called from this main_build?.
my_clspath.xml content:
<fileset dir="../myApp_Ear/build/">
<include name="**/*.jar" />
</fileset>
<fileset dir="../myApp_Ear/lib/">
<include name="**/*.jar" />
</fileset>
Try
<project name="Your Project">
<include file="my_clspath.xml" />
<ant antfile="sub1.xml" inheritAll="true" inheritRefs="true" />
</project>
Also, you should set an id on the Filesets. Just having them in your Ant file does not do anything.
<fileset dir="../myApp_Ear/build/" id="my.EAR.fileset">
<include name="**/*.jar" />
</fileset>
Then, in sub1.xml, you can reference the filesets with <fileset refid="my.EAR.fileset" />
Hope this helps.
You should really take a look at the <subant> task. This does exactly what you're asking: You have a master build.xml file that's calling some sub-ant build files to build basic components.

Eclipse: Ant script to export User Library/Libraries for project

I am new to Java programming. I initially started with NetBeans but have moved to Eclipse given the advice from a friend.
In NetBeans, a pre-written ant build script for the project would generate a Project.jar file and place all required libraries/jars in a lib/ folder.
However, in Eclipse it appears that I need to write my own ant script. I have written a few lines to generate the jar file:
<target name="compile">
<mkdir dir="${build.dir}"/>
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="jars" debug="on"/>
</target>
How do I write a command to copy all of the jars in my User Library to a ${build.dir}/lib/ folder?
Thanks.
Use the copy task
like so, with the appropriate include or exclude pattern
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir">
<include name="**/*.jar"/>
</fileset>
</copy>
<copy todir="${build.dir}/lib/">
<fileset dir="src_dir" excludes="**/*.java"/>
</copy>
If you are new to Java take the chance to have a look at maven. It is a build tool like ant with a lot of predefined 'goals' and a fully developed dependency (to other libraries) handling. You will find a eclipse plugin which will be very useful.
Maven projects have a special directory layout which is kind of best practise and helpful for beginners. If you work on a maven project you can just use the command
mvn dependency:copy-dependencies
as a console command (or eclipse run configuration) to copy your project dependencies (libraries) to the <project>\target\dependency directory.
I recommend to use ant4eclipse library for ant based eclipse projects. When you use it, you can access eclipse workspace/project settings, and can iterate tought eclipse project class path in ant.
See the example code bellow:
<path id="ant.classpath">
<fileset dir="${lib.dir}/ant4eclipse">
<include name="*.jar" />
</fileset>
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<taskdef resource="net/sf/ant4eclipse/antlib.xml" />
<targetPlatform
<target name="copy_jars">
<getEclipseClasspath workspace="${basedir}/.."
projectname="TestProject"
targetPlatformLocation="c:/eclipse"
property="classpath"
relative="false"
runtime="true"
pathseparator="#" />
<!-- iterate over all classpath entries -->
<foreach list="${classpath}" delimiter="#"
target="copy_jar_file" param="classpath.entry" />
</target>
<target name="copy_jar_file">
<!-- check if current is a .jar-file ... -->
<if>
<isfileselected file="${classpath.entry}">
<filename name="**/*.jar" />
</isfileselected>
<then>
<!-- copy the jar file to a destination directory -->
<copy file="${classpath.entry}" tofile="${dest.dir}"/>
</then>
</if>
</target>
If you would like to use user libraries, you can define it by userlibraries command.

How to perform Ant path mapping in a 'war' task?

I have several JAR file pattern sets, like
<patternset id="common.jars">
<include name="external/castor-1.1.jar" />
<include name="external/commons-logging-1.2.6.jar" />
<include name="external/itext-2.0.4.jar" />
...
</patternset>
I also have a 'war' task containing a lib element:
<lib dir="${src.dir}/jars">
<patternset refid="common.jars"/>
<patternset refid="web.jars"/>
...
</lib>
Like this however, I end up with WEB-INF/lib containing the subdirectories from my patterns:
WEB-INF/lib/external/castor-1.1.jar
WEB-INF/lib/external/...
Is there any way to flatten this, so the JAR files appear at the top-level under WEB-INF/lib, regardless of the directories specified in the patterns? I looked at mapper but it seems you cannot use them inside lib.
I was dissatisfied with having to manually generate a WAR directory or declare library subdirectories, so I came up with this. Seems to work, obviously you'll need to adjust it to your own needs:
<war destfile="build/output.war" webxml="${web.dir}/WEB-INF/web.xml">
<fileset dir="${web.dir}" />
<mappedresources>
<fileset dir="${lib.dir}" includes="**/*.jar" />
<chainedmapper>
<flattenmapper/>
<globmapper from="*.jar" to="WEB-INF/lib/*.jar" />
</chainedmapper>
</mappedresources>
</war>
You can try to use mappedresources element (Ant 1.8+)
<mappedresources>
<!-- Fileset here -->
<globmapper from="external/*.jar" to="*.jar"/>
</mappedresources>
http://ant.apache.org/manual/Types/resources.html#mappedresources
If you have a typical web project it is better to split the web-app libraries and general-purpose libraries in different folders and leave WEB-INF/lib to have only those needed at runtime. This way you'll avoid collisions and also your project will look much clearer to other developers.

Categories

Resources