Maven: how to copy resources into WAR? - java

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>

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.

Creating a WAR file using Java

How do I create a deployable WAR file for Apache Tomcat servers programmatically with Java?
Is there a library for such a task?
I am working on a small own IDE for special purposes. The IDE is written in Java and JavaScript, so I need to create the WAR file using those.
If you want to build it from code try to do it from the command line with
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("jar cvf /path/to/your/project/your-file.war");
Of course, the same thing would work using ANT or Maven (as long as those tools are installed on the final platform).
Edit: added improvement suggestion
I don't know of libraries, but a WAR file is just a ZIP file with a different ending.
Just create the inner folder structure and files (google the java code for that) and package as zip (java has methods for that too I think, again google) and rename the file from "myfile.zip" to "myfile.war"
I don't know how you would do it using the IDE you have. But a WAR file has the following structure:
web resources go to the root
project classes (including their package folders) go to a folder WEB-INF/classes
project dependency jars go to WEB-INF/lib
So if you want to build a WAR by hand, you need to create that file structure inside a zip file with a .war extension and you need to copy that to the proper location of the server to deploy it. Most servers also allow 'exploded deployment', meaning that you don't need an actual war file, you can just deploy the stuff to a directory with the same name as your war (IE. 'myapp.war').
You can do this a number of ways, for a quick example if you are using maven you just need to use <packaging>war</packaging>
You could just export the war as has been mentioned, but it's not exactly "programmatic".
If you're using Ant - you can find a tutorial for this here
<?xml version="1.0" ?>
<path id="compile.classpath">
<fileset dir="WebContent/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
</path>
<target name="init">
<mkdir dir="build/classes"/>
<mkdir dir="dist" />
</target>
<target name="compile" depends="init" >
<javac destdir="build/classes" debug="true" srcdir="src">
<classpath refid="compile.classpath"/>
</javac>
</target>
<target name="war" depends="compile">
<war destfile="/APP/jboss-5.1.0.GA/server/all/deploy/DispatchActionEx.war" webxml="WebContent/WEB-INF/web.xml">
<fileset dir="WebContent"/>
<lib dir="WebContent/WEB-INF/lib"/>
<classes dir="build/classes"/>
</war>
</target>
<target name="clean">
</target>
Just write an build.xml file(i have give an example),
change "project name" and "war destfile" which will be ".../apache-tomcat/webapps/projectname.war"
put it in your project folder
open it in eclipse.
right click on it>>run as>>ant build
check whether the war file is created in the webapps folder in apache-tomcat

How to make Eclipse Compiler copy existing class files to the target dir?

How to make Eclipse copy all the files (except .java) from the source directory to the output directory? I have some class-files under my sources, but they are filtered out. The setting "Preferences -> Java -> Compiler -> Building -> Filtered Resources" doesn't work for me.
Thanks!
EDIT:
I came out with a solution: add additional Builder to the Eclipse project. It's an Ant script:
<project name="example" default="copy_resources" basedir=".">
<target name="copy_resources" depends="" >
<copy todir="bin" overwrite="false">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
</project>
However I have to manually trigger the "Build Project" command in order to Ant script be executed. When I do "Clean" it is not executed...
You need to have class directories in a different directory than your source, I usually put them in a directory called "lib" (not just class directories but jars as well).
Once you have the classes in a different directory:
Right click on the project > Properties > Java Build Path > Libraries
tab > Add Class Folder button > Select the directory > OK > OK
When you build your project the class directories should be included.
It sounds like the .class files are artifacts from something else, either checked in, or created by an external process. In either case, Eclipse appears to be blissfully unaware of them (from your description).
You can try the following: add a new builder to your project. Select "Ant" and choose the build.xml at the root of your workspace (or whatever location you decided - you need to make this file). The ant script will run whenever your project is rebuilt.
<?xml version="1.0" encoding="UTF-8"?>
<project default="copy">
<target name="copy">
<mkdir dir="someplace"/>
<copy todir="someplace">
<fileset dir="source">
<include name="**/*.class"/>
</fileset>
</copy>
</target>
</project>
You just need to fixup the source and destination of the files.

Create directory structures during Ant jar task

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.

Categories