Ant change directory structure in the war file - ant

I'm new to ant and I have to wrap my web project in war file and I'm using ant
My project is structured like that:
myproject
--images
--css
--js
and in the war file the final structure is like:
myproject
--css
--images
--js
--META-INF
--WEB-INF
I'd like to change the final structure (to put everything from the project directory in "public" folder) BUT only in the war file, and I'd like to be like that:
myproject
--public
-----css
-----images
-----js
--META-INF
--WEB-INF
I have try using copy task and move task but with no success...
What should i do in order to accomplish this?

I think that using prefix attribute in a zipfileset may help you (see zipfileset):
<target name="Wrappin the in war file" description="Compiling....">
<mkdir dir="${build-directory}" />
<delete file="${build-directory}/${war-file-name}" />
<war warfile="${build-directory}/${war-file-name}" webxml="${web-xml-file}">
<zipfileset dir="${web-directory}" prefix="public">
<exclude name=".git/**" />
<exclude name=".svn/**" />
<exclude name=".idea/**" />
<exclude name="node_modules/**" />
<exclude name="bower_components/**" />
</zipfileset>
<manifest>
<attribute name="Built-By" value="${builder}" />
<attribute name="Built-On" value="${build-info.current-date}" />
<attribute name="Built-At" value="${build-info.current-time}" />
</manifest>
</war>
</target>

Related

Exclude files in ant-migration tool while deploying

I am new to salesforce. We are using ant-migration tool. There are a few classes/dashboards/triggers that we are trying to exclude using file sets. All of the below folders are inside src.
<property file="build.properties"/>
<property name="src.dir" value="../src"/>
<fileset dir="${src.dir}" casesensitive="yes">
<echo message="Inside file set"/>
<exclude name="**/classes/Abs*.cls"/>
</fileset>
<target name="deploy">
<sf:deploy
username="${sf.username}.${org}"
password="${sf.password}${sf.securitytoken}"
serverurl="${sf.serverurl}"
checkOnly="${checkOnly}"
maxPoll="${maxPoll}"
deployRoot="${src.dir}"
allowMissingFiles="${allowMissingFiles}"
ignoreWarnings="${ignoreWarnings}"
testLevel="${testLevel}" />
</target>
It looks like I am unable to exclude the same.
Never used filesets, sorry.
My Ant pulls project's structure from Git to temp directory so in the build.xml we just delete stuff which we know is pain to deploy. We still want these files in the repo for ease of use / repo completeness.
<target name="deploy_target">
...
<delete file="${src.dir}/workflows/Reply.workflow" />
<delete file="${src.dir}/workflows/Question.workflow" />
<delete file="${src.dir}/layouts/SocialPost-Social Post Layout.layout" />
<delete file="${src.dir}/layouts/CommunityMemberLayout-Community Member Layout.layout" />
</target>

JSP is not getting copied while creating war using Ant

I am using following Ant script to create a war of simple web application.
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="war">
<path id="compile.classpath">
<fileset dir="WebContent/WEB-INF/lib">
<include name="*.jar" />
</fileset>
</path>
<target name="compile">
<javac destdir="WebContent/WEB-INF/classes" debug="true" srcdir="src">
<classpath refid="compile.classpath" />
</javac>
</target>
<target name="war" depends="compile">
<war destfile="build/myproject.war" webxml="WebContent/WEB-INF/web.xml">
<fileset dir="WebContent">
<include name="**/*.jsp" />
</fileset>
<lib dir="WebContent/WEB-INF/lib" />
<classes dir="WebContent/WEB-INF/classes" />
</war>
</target>
</project>
It's creating the war but when I am opening the war, it's not containing JSP files due to which application is not running. Any idea what is wrong?
Also, right now I am coping war manually in Weblogic. Is there any Ant command which can deploy war?
I don't know exact answer but here is my way of using Ant build.xml for webapps. Give it a try. This works inside Eclipse or run from the command line. Few key points are:
build.xml has reference to compile-time libraries, including servlet-api.jar
dynamic META-INF/MANIFEST.MF
separate targets for compile, jar and war tasks to allow easier per project custom rules
webapp war don't have individual .class files but compiled web-inf/lib/mywebapp.jar library to minimize filesystem noice
you may create web/WEB-INF/classes/ folder and put some .properties file or extreme case "binary provided" class files. They are put inside war package along with other jsp,html,js files.
folder structure is very streamlined, I can use mywebapp/web/ folder directly in Tomcat service during development. Each html, jsp etc changes are reflected at runtime. Compiling jar triggers Tomcat to reload webapp instance.
Use this common folder structure for webapp project.
/mywebapp/ant.bat
/mywebapp/build.xml
/mywebapp/classes/
/mywebapp/src/
/mywebapp/src/META-INF/MANIFEST.MF
/mywebapp/lib/
/mywebapp/web/
/mywebapp/web/WEB-INF/web.xml
/mywebapp/web/WEB-INF/lib/
/mywebapp/web/META-INF/context.xml
mywebapp/build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="mywebapp" default="build" basedir=".">
<property name="name" value="${ant.project.name}" />
<property name="classes" value="./classes" />
<property name="src" value="./src" />
<property name="webdir" value="./web" />
<property name="version" value="1.0"/>
<property environment="env"/>
<path id="libs">
<pathelement location="lib/servlet-api.jar" />
<pathelement location="web/WEB-INF/lib/somelib1.jar" />
<pathelement location="web/WEB-INF/lib/somelib2.jar" />
<pathelement location="web/WEB-INF/lib/gson-2.2.4.jar" />
</path>
<tstamp>
<format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />
</tstamp>
<target name="updatemanifest" description="Update manifest">
<buildnumber file="build.num"/>
<copy file="${src}/META-INF/MANIFEST.MF"
todir="${classes}/META-INF/" overwrite="true" preservelastmodified="true"
/>
<manifest file="${classes}/META-INF/MANIFEST.MF" mode="update">
<attribute name="Implementation-Version" value="${version}.${build.number} (${TODAY})" />
<attribute name="Implementation-Title" value="${name}" />
</manifest>
</target>
<target name="clean" description="Clean compiled classes">
<delete dir="${classes}" />
</target>
<target name="compile" depends="clean" description="Compile classes">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}" target="1.6" source="1.6" encoding="ISO-8859-1"
debug="true" debuglevel="lines,source"
excludes="" includeantruntime="false" >
<classpath refid="libs" />
<compilerarg value="-Xlint:deprecation" />
</javac>
</target>
<target name="jar" depends="updatemanifest" description="Create a .jar file">
<echo message="Build release: ${release}" />
<jar
manifest="${classes}/META-INF/MANIFEST.MF"
jarfile="${webdir}/WEB-INF/lib/${name}.jar" >
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="war" depends="compile,jar" description="Create a .war file">
<delete file="${name}.war" />
<zip destfile="${name}.war"
basedir="${webdir}"
excludes="
**/CVS*
"
/>
</target>
<target name="build" depends="war" description="Build lib">
</target>
</project>
src/META-INF/MANIFEST.MF
Implementation-Title: myappname
Implementation-Version: 1.0.0 (2010-03-01)
Implementation-Vendor: My Name Ltd.
Implementation-URL: http://www.myname.com
mywebapp/build.bat
call c:\apache-ant-1.7.0\bin\ant.bat build
pause
Build script creates war package and manifest.mf within web-inf/lib/mywebapp.jar is updated to have build number, title and version. Very handy you can use folder content as a template for new webapp projects. Just edit build.xml to have new project name.
Some compile-time dependencies point mywebapp/web-inf/lib folder. Non war-packaged libraries are put to mywebapp/lib/ folder for compile time only. I like keeping each dependency within project version control so thats a reason for this lib folder. You may use *.jar wildcard ant syntax but I explictly list each file for self documentation purpose.
Here is a bonus file to be used in Tomcat during development time. It publishes webapp on Tomcat and any changes in project folder is seen immediately, its very handy for client file changes (html,js,jsp).
this file is a copypaste from mywebapp/web/META-INF/context.xml file but an explicit docBase attribute is added.
It directs Tomcat to use files directly from project folder, no redeployment needed at runtime
Start tomcat and keep it running, you may run several webapp projects withing same Tomcat instance. Sometimes bigger development projects need it.
Remote debugging hook requires some java magic not included here
tomcat/conf/Catalina/localhost/mywebapp.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="C:/mywebapp/web"
debug="0" reloadable="true" crossContext="true" >
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1" />
-->
<!--
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
-->
<!-- pooled db connection -->
<Resource name="jdbc/mywebappDB" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="2" maxWait="20000"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
username="myuserid" password="mypwd"
url="jdbc:sqlserver://mysqlserv1.com:1433;DatabaseName=MyDB;applicationName=mywebapp"
validationQuery="SELECT 1"
/>
<!-- <ResourceLink name="jdbc/mywebappDB" global="jdbc/mywebappDB" type="javax.sql.DataSource" /> -->
<Resource name="jdbc/mywebappDB2" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="20" maxWait="10000"
driverClassName="com.mysql.jdbc.Driver"
username="myuserid" password="mypwd"
url="jdbc:mysql://localhost:3306/myDB2?useUnicode=true&characterEncoding=utf8"
validationQuery="SELECT 1" removeAbandoned="true" removeAbandonedTimeout="300"
/>
</Context>
ps: Ant build system is fine no matter what some people may say. Go with it as you please.

How to use filelist as fileset in uptodate Ant command?

I have a target of build.xml that creates a Zip file. To avoid creating the Zip if no file has been updated, I'd like to check for updates beforehand. AFAIK, uptodate is the task to use.
Here is the relevant (simplified) script sections:
<filelist id="zip-files">
<file name="C:/main.exe" />
<file name="D:/other.dll" />
</filelist>
<target name="zip" depends="zip-check" unless="zip-uptodate">
<zip destfile="${zip-file}" >
<filelist refid="zip-files" />
</zip>
</target>
<target name="zip-check">
<uptodate property="zip-uptodate"
targetfile="${zip-file}">
<srcfiles refid="zip-files" />
</uptodate>
</target>
However, uptodate fails because srcfiles must reference a fileset, not a filelist. Still, I can't use a fileset because it would require a dir attribute, which I can't set because source files do not share a base directory.
Of course, I could just copy all files to a common directory before zipping them, thus being able to use fileset, but I was wondering whether there was an alternative solution.
I'm using Ant 1.8.1
Instead of using <srcfiles>, try using <srcresources>. <srcfiles> must be a fileset, but <srcresource> can be a union of any collection of resources, and that should include a filelist.
I can't do any test right now, but it should look something like this:
<filelist id="zip-files">
<file name="C:/main.exe" />
<file name="D:/other.dll" />
</filelist>
<target name="zip" depends="zip-check" unless="zip-uptodate">
<zip destfile="${zip-file}" >
<filelist refid="zip-files" />
</zip>
</target>
<target name="zip-check">
<union id="zip-union">
<filelist refid="zip-files"/>
</union>
<uptodate property="zip-uptodate"
targetfile="${zip-file}">
<srcresources refid="zip-union" />
</uptodate>
</target>
Hope it works for you.

How do you use ant to unjar multiple JAR files and rebuild them into one JAR file?

I would like to unjar multiple JAR files and then rebuild into one JAR using an ant build script. Is this possible?
Yes, it's possible with ant. A jar file is basically a zip with a special manifest file. So to unjar, we need to unzip the jars. Ant includes an unzip task.
To unzip/unjar all the jar files in your project:
<target name="unjar_dependencies" depends="clean">
<unzip dest="${build.dir}">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</unzip>
</target>
Obviously you need to declare ${build.dir} and ${lib.dir} first. The line <include name="**/*.jar" /> tells ant to include all files that end up with the jar extension, you can tweak that include to suit your needs.
To pack everything into a jar, you use the jar task:
<target name="make_jar" depends="compile, unjar_dependencies">
<jar basedir="${build.dir}"
destfile="${dist.dir}/${project_name}.jar">
<manifest>
<attribute name="Main-Class" value="${mainclass}" />
</manifest>
<fileset dir="${build.dir}">
<include name="**/*.class" />
</fileset>
<fileset dir="${src.dir}">
<include name="applicationContext.xml" />
<include name="log4j.properties" />
</fileset>
</jar>
</target>
In this example, we include different filesets. In one fileset we are including all compiled classes. In another fileset we include two config files that this particular project depends upon.
Yes it is !
You have two possibilities :
Espen answer :
One possible solution that creates one
jar file from all the jar files in a
given directory:
<target name="dependencies.jar">
<jar destfile="WebContent/dependencies.jar">
<zipgroupfileset dir="lib/default/" includes="*.jar"
excludes="*.properties" />
</jar>
</target>
This is useful if you don't need to exclude content that are in some jars (like for example some properties configuration file that might override yours, etc). Here the excludes properties is filtering out files from the dir property.
Use zipfileset
The other solution is to use the zipfileset tag where the excludes property this time will filter out content from the jar to be merged.
<jar destfile="your_final_jar.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="main.class"/>
<attribute name="Class-Path" value="."/>
</manifest>
<zipfileset
excludes="META-INF/*.SF"
src="/path/to/first/jar/to/include.jar"/>
</jar>
Of course you can combine the two tags (zipfileset and zipgroupfileset) inside the same jar tag to get the best of the two.
Yes, it's possible.
One possible solution that creates one jar file from all the jar files in a given directory:
<target name="dependencies.jar">
<jar destfile="WebContent/dependencies.jar">
<zipgroupfileset dir="lib/default/" includes="*.jar"
excludes="*.properties" />
</jar>
</target>
There is also a project devoted to repackage jars called JarJar. You can use it to repackage mutiple Jars into one. Depending on your requirements, you can even rename classes to prevent version conflicts.
From their getting started page:
In this example we include classes from jaxen.jar and add a rule that changes any class name starting with "org.jaxen" to start with "org.example.jaxen" instead (in our imaginary world we control the example.org domain):
<target name="jar" depends="compile">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="lib/jarjar.jar"/>
<jarjar jarfile="dist/example.jar">
<fileset dir="build/main"/>
<zipfileset src="lib/jaxen.jar"/>
<rule pattern="org.jaxen.**" result="org.example.#1"/>
</jarjar>
</target>

how to add a complete folder to a jar file by ant

I'd like to create like a "fat" jar with ant where I have, not only the usual classes, manifest files, etc, but also my 'libs' folder too.
I tried with:
<jar destfile="myjar.jar" update="yes" basedir="${libs.dir}"/>
but this adds the files in 'libs' the root of the jar file where I'd like to have the libs folder itself in the jar (with everything it contains of course)
Can I maybe create the lib folder myself in the jar and add the files to that specific location in the jar then ?
If you specify to use the directory as the root for your file set then you can just match for the directory and it will preserve the structure.
<jar destfile="myjar.jar" >
<fileset dir=".">
<include name="**/${libs.dir}/**"/>
</fileset>
</jar>
You have to do something like the following. Specifically, the zipfileset command. You basically are saying you want to build the ${build.name}.jar (you could hard code a path to be "myjar.jar" or something along those lines) and then add the various files to the JAR.
Hope this helps!
<jar destfile="${dist}/${build.name}.jar">
<!-- Generate the MANIFEST.MF file. -->
<manifest>
<attribute name="Built-By" value="${user.name}" />
<attribute name="Release-Version" value="${version}" />
<attribute name="Main-Class" value="my.lib.Main" />
<attribute name="SplashScreen-Image" value="TitleScreen.png" />
<attribute name="Class-Path" value="${classpath}" />
</manifest>
<zipfileset dir="${build.dir}" />
<zipfileset dir="${resources}" />
<fileset file="${resources}/icons/misc_icons/TitleScreen.png" />
</jar>
Use this ant extension: http://one-jar.sourceforge.net/
There is also Eclipse plugin: FatJar
http://www.vertigrated.com/blog/2009/11/how-to-bundle-command-line-programs-into-a-single-executable-jar-file/

Resources