Create directory structures during Ant jar task - java

I want to create a jar with the following directory structure:
thejar.jar/
classes/ --> where all classes go
lib/ --> where all dependencies go
res/ --> where all non-classpath resources go (scripts, etc.)
META-INF/
Here's my ant task:
<jar destfile="dist/main/thejar.jar">
<!-- Create the manifest -->
<manifest>
<!-- JAR should be sealed. -->
<attribute name="Sealed" value="true" />
</manifest>
<!-- Copy main build directory to classes/ directory in JAR. -->
<fileset dir="dist/main/classes" includes="build/main"/>
<!-- Copy main library directory to lib/ directory in JAR. -->
<fileset dir="dist/main/lib" includes="lib/main"/>
<!-- Copy main resources directory to res/ in JAR. -->
<fileset dir="dist/main/res" includes="res/main"/>
</jar>
If I am understanding this correctly, it should be:
Copying all the built (.class) files in build/main to dist/main/classes
Copying all lib/main dependencies to dist/main/lib
Copying all res/main files to dist/main/res
JARring up dist/main/* into thejar.jar
The JAR task executes without errors, but when I go to view the contents of thejar.jar I just see META-INF/ (none of the subdirectories I mentioned above).
What's going on here? Thanks in advance!

You want jar task to copy files in build/main into jar's dist/main/lib, but
<fileset dir="dist/main/classes" includes="build/main"/>
means to pack files in dist/main/classes/build/main into the jar file.
Take a look at the example from the Ant-Jar task doc:
<jar destfile="${dist}/lib/app.jar">
<fileset dir="${build}/classes"
excludes="**/Test.class"
/>
<fileset dir="${src}/resources"/>
</jar>
(The code above) jars all files in the ${build}/classes directory and also in the ${src}/resources directory together into a file called app.jar in the ${dist}/lib directory.
To achieve your request, I think you can copy the classes, resources and dependencies with <copy> task into the directory structure that you want and then jar the directory.

Related

ant: include resources in subdirectory to war file

I would like to include a set of resource files to my war file.
I know that I can specify either fileset or webinf as an inner element of my war element in build.xml, but in both of these cases, when I deploy the war file, the resource files end up in either top level directory or WEB-INF directory respectively.
I would like to place them into a subdirectory (say, WEB-INF/resources). Actually, these resource files are in a subdirectory in my source three already, I just need to include this subdirectory as is to the war file.
How is this done?
You can use zipfileset with prefix attribute to add a subdirectory to zip/war file. If the resource files is in src/resource, and you want to pack them into WEB-INF/resource. Here is the example:
<target name="build">
<war destfile="test.war">
<fileset dir="webapps">
<include name="**" />
</fileset>
<zipfileset dir="src/resource" prefix="WEB-INF/resource" />
</war>
</target>

How to convert a java project to a plugin project in Ant?

I am currently trying to write a build.xml which will convert a normal java project say com.example.normal to com.example.plugin.jar.
I have the code for a basic build.xml which creates a jar of the source project. But normally creating a jar file is not the same as creating a plugin jar file. For this reason I need to create a plugin jar file using ant and not just a normal jar file which cannot act as a plugin.
This is the example code snippet for creating the jar file.
<jar destfile="generatedPlugins/com.example.normal.jar">
<fileset dir="JavaSource/com.example.normal"/>
</jar>
Manually, I can create a plugin with the following steps:
Right Click on project > Export > Plugin Development > Deployable
plug-ins and fragments.
In other words, I just need to automate this process using Ant. Any idea how to proceed?
Thanks!
This can't really be done with Ant alone. You should use Tycho or PDE Build to build bundle (plug-in) JARs. Take note that Tycho is the modern, preferred option; I'm not sure that PDE Build is even actively maintained or used any more.
You could try manually editing the build.xml, adding something like
<!-- This builds a .jar file, Assuming you have a set of .class files
created by some "compile" target. -->
<target name="build" depends="compile">
<!-- We need to set up class path for any required libraries so that we
can add it to the manifest file later. -->
<path id="build.classpath">
<pathelement location="${lib.location}"/>
</path>
<!-- Now we convert the class path we just set up to a manifest class
path - we'll call it manifest.cp. We also need to tell it where our
.jar file will be output. -->
<manifestclasspath property="manifest.cp" jarfile="${jar.output.dir}/filename.jar">
<!-- We just give it the classpath we set up previously. -->
<classpath refid="build.classpath"/>
</manifestclasspath>
<!-- Now we can make the .jar. It needs to know the base directory of
our compiled .class files. -->
<jar destfile="${jar.target}/filename.jar" basedir="${class.target}">
<!-- Set up the manifest file with the name of the main class and
the manifest class path we set up earlier. -->
<manifest>
<attribute name="Main-Class" value="name of main class"/>
<attribute name="Class-Path" value="${manifest.cp}"/>
</manifest>
</jar>
</target>
You can generate Ant scripts from the PDE tools by right-clicking on a relevant manifest file (e.g. plugin.xml) in the project and selecting PDE Tools --> Create Ant Build File.
This link from the Eclipse Mars documentation explains in detail.

How to include library files while creating jar files without copying library separately

I need to include some third party jar file to my project jar. I mentioned it in my build.xml and include this to MANIFEST.MF. Now i get thirdparty1.jar thirdparty2.jar file into inside the project jar. But still i can't able to use the jars. Is it need any addition configuration
Here is my build.xml
<manifest>
<attribute name="Class-Path" value="thirdparty1.jar thirdparty2.jar thirdparty3.jar"/>
If i copy the two jar separately it works well. But i don't understand what is the need for copy these separate. How it solve with out copying jar separately.
If the dependency jar is packaged inside the project jar, you need a solution to load it from there. The standard class-path handling in Java won't access jar files located inside other jar files.
See this answer: Classpath including JAR within a JAR. Specifically the One Jar solution: http://one-jar.sourceforge.net/.
It's also possible to use zipgroupfileset for that.given is the sample ant task for that.
<!-- Build JAR file -->
<target name="jar" depends="init-build-dir,compile-main">
<!--creating a temp jar contains all jar -->
<jar jarfile="${project.build.lib.dir}/external-libs.jar">
<zipgroupfileset dir="${project.lib.redist.dir}">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
<sleep seconds="1" />
<!-- creating main jar with temp jar-->
<jar jarfile="${project.build.lib.dir}/${ant.project.name}.jar" manifest="MANIFEST.MF">
<fileset dir="${project.build.main.classes.dir}" includes="**/*.*" />
<zipfileset src="${project.build.lib.dir}/external-libs.jar">
<exclude name="*" />
</zipfileset>
</jar>
<!--removing temp jar -->
<delete>
<fileset dir="${project.build.lib.dir}">
<include name="external-libs.jar" />
</fileset>
</delete>
</target>

How to include a property file in WEB-INF folder of war

I am using ant to build my web-app. I am trying to include a property file in the WEB-INF folder from a source folder. I have included it in the war/WEB-APP/classes folder. But the application is not reading it. Hence, i want to include it in the WEB-INF folder directly to read it in the application.
I have tried the following but nothing seems to work. my build.xml looks like this :
<target name="build-dev" description="Package GWT app to web archive and deploy to web server">
<echo message="Package GWT app to web archive" />
<copy toDir="${basedir}/war/WEB-INF/lib">
<fileset dir="${basedir}/lib" includes="*.jar" />
<fileset dir="${gwt.home}" includes="*.jar" />
</copy>
<copy todir="${basedir}/war" file="${basedir}/src/etc/dev/GroupQuoteUI.properties" />
<war basedir="${war.dir}" destfile="${deploy.dir}/${app.name}.war" webxml="${webinf.dir}/web.xml">
<webinf dir="${webinf.dir}/">
<include name="*." />
<exclude name="**/web.xml" />
</webinf>
<classes dir="${basedir}/src/etc/dev/" includes="*.properties" />
</war>
</target>
i have tried to use :
"include name="${war.dir}/GroupQuoteUI.properties" in "webinf" tag but it did'nt worked.
Also includes="${war.dir}/GroupQuoteUI.properties" inside the tag.
Also this inside "webinf" folder again :
"zipfileset dir="${basedir}/war/" includes="GroupQuoteUI.properties" fullpath="${webinf.dir}/GroupQuoteUI.properties"
but this is giving an error during build stating "cannot have src dir together".
So what should i do to include this file in the WEB-INF directory of the war. All other directories and web.xml file is included.
You cannot read a file that is packed into a war, or jar by accessing it with
new FileInputStream()
Instead you can do the following:
this.getClass().getResourceAsStream(filename)
this will load a resource (your properties-file) from the classpath, so it will read the file in a war-archive.
It does this by using the same ClasseLoader which has been used to load the class that belongs to this.getClass()
Here you can find an example:
How to really read text file from classpath in Java

Maven: how to copy resources into WAR?

I have an Eclipse webapp project that I am trying to migrate from Ant build to Maven build. I have a lot of non-Java files in my src/ folder, for example log4j2.xml, ehcache.xml, some .properties localization files etc.
When I run war:war target on this project, the resulting WAR file contains only the .class files in the WEB-INF/classes folder, all the non-Java files are missing. In Ant I did this:
<target name="copy-resources" depends="compile">
<copy todir="${build}">
<fileset dir="${src}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
How do I achieve the same thing in Maven? I suspect I should be using the resources folder, but right now I am trying to migrate with as little changes to the original codebase as possible...
You can access these files from resources folder. I hope this
link helps.
You can also specify the folder, if it is not the default resources folder, in the pom.xml. See
Specifying resource directories.
For example, if your folder has these files in src/my-resources, then you need to add this to the pom.xml, and then you would be able access it in code.
<resources>
<resource>
<directory>src/my-resources</directory>
</resource>
</resources>

Categories