How to create war files - java

What are the best practices of creating war files (using eclipse) to run on tomcat? tutorials, links, examples are highly appreciated.

You can use Ant to set up, compile, WAR, and deploy your solution.
<target name="default" depends="setup,compile,buildwar,deploy"></target>
You can then execute one click in Eclipse to run that Ant target. Here are examples of each of the steps:
Preconditions
We'll assume that you have your code organized like:
${basedir}/src: Java files, properties, XML config files
${basedir}/web: Your JSP files
${basedir}/web/lib: Any JARs required at runtime
${basedir}/web/META-INF: Your manifest
${basedir}/web/WEB-INF: Your web.xml files
Set up
Define a setup task that creates the distribution directory and copies any artifacts that need to be WARred directly:
<target name="setup">
<mkdir dir="dist" />
<echo>Copying web into dist</echo>
<copydir dest="dist/web" src="web" />
<copydir dest="dist/web/WEB-INF/lib" src="${basedir}/../web/WEB-INF/lib" />
</target>
Compile
Build your Java files into classes and copy over any non-Java artifacts that reside under src but need to be available at runtime (e.g. properties, XML files, etc.):
<target name="compile">
<delete dir="${dist.dir}/web/WEB-INF/classes" />
<mkdir dir="${dist.dir}/web/WEB-INF/classes" />
<javac destdir="${dist.dir}/web/WEB-INF/classes" srcdir="src">
<classpath>
<fileset dir="${basedir}/../web/WEB-INF/lib">
<include name="*" />
</fileset>
</classpath>
</javac>
<copy todir="${dist.dir}/web/WEB-INF/classes">
<fileset dir="src">
<include name="**/*.properties" />
<include name="**/*.xml" />
</fileset>
</copy>
</target>
Build WAR
Create the WAR itself:
<target name="buildwar">
<war basedir="${basedir}/dist/web" destfile="My.war"
webxml="${basedir}/dist/web/WEB-INF/web.xml">
<exclude name="WEB-INF/**" />
<webinf dir="${basedir}/dist/web/WEB-INF/">
<include name="**/*.jar" />
</webinf>
</war>
</target>
Deploy
Finally, you can set up a task to deploy the WAR directly into your Tomcat deploy location:
<target name="deploy">
<copy file="My.war" todir="${tomcat.deploydir}" />
</target>
Click and go!
Once all this is set up, simply launching the default target from Eclipse will compile, WAR, and deploy your solution.
The advantage of this approach is that it will work outside Eclipse as well as within Eclipse and can be used to easily share your deployment strategy (e.g. via source control) with other developers who are also working on your project.

I've always just selected Export from Eclipse. It builds the war file and includes all necessary files. Providing you created the project as a web project that's all you'll need to do. Eclipse makes it very simple to do.

We use Maven (Ant's big brother) for all our java projects, and it has a very nifty WAR plugin. Tutorials and usage can be found there.
It's a lot easier than Ant, fully compatible with Eclipse (use maven eclipse:eclipse to create Eclipse projects) and easy to configure.
Maven's homepage
Maven WAR plugin
Sample Configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-alpha-2</version>
<configuration>
<outputDirectory>${project.build.directory}/tmp/</outputDirectory>
<workDirectory>${project.build.directory}/tmp/war/work</workDirectory>
<webappDirectory>${project.build.webappDirectory}</webappDirectory>
<cacheFile>${project.build.directory}/tmp/war/work/webapp-cache.xml</cacheFile>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>jsp</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<webResources>
<resource>
<directory>src/main/webapp/</directory>
<targetPath>WEB-INF</targetPath>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</webResources>
<warName>Application</warName>
</configuration>
</plugin>

A war file is simply a jar file with a war extension, but what makes it work is how the contents is actually structured.
The J2EE/Java EE tutorial can be a start:
http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/WebComponents3.html
And the Servlet specification contains the gory details:
http://java.sun.com/products/servlet/download.html
If you create a new web project in Eclipse (I am referring to the Java EE version), the structure is created for you and you can also tell it where your Appserver is installed and it will deploy and start the application for you.
Using the "Export->WAR file" option will let you save the war file.

If you are not sure what to do and are starting from scratch then Maven can help get you started.
By following the the below steps you can get a new war project setup perfectly in eclipse.
Download and install Maven
Go the command line run: mvn archetype:generate
Follow the prompted steps - choosing the simple java web project (18) and a suitable name.
When it is finished run: mvn eclipse:eclipse
Start Eclipse. Choose File -> Import -> Existing project. Select the directory where you ran the mvn goals.
That's it you should now have a very good start to a war project in eclipse
You can create the war itself by running mvn package or deploy it by setting up a server in eclipse and simply adding adding the project to the server.
As some others have said the downside of using maven is that you have to use the maven conventions. But I think if you are just starting out, learning the conventions is a good idea before you start making your own. There's nothing to stop you changing/refactoring to your own preferred method at a later point.
Hope this helps.

Use the following command outside the WEB-INF folder. This should create your war file and is the quickest method I know.
(You will need JDK 1.7+ installed and environment variables that point to the bin directory of your JDK.)
jar -cvf projectname.war *
Reference Link

Use the Ant war task

Use ant build code
I use this for my project SMS
<property name="WEB-INF" value="${basedir}/WebRoot/WEB-INF" />
<property name="OUT" value="${basedir}/out" />
<property name="WAR_FILE_NAME" value="mywebapplication.war" />
<property name="TEMP" value="${basedir}/temp" />
<target name="help">
<echo>
--------------------------------------------------
compile - Compile
archive - Generate WAR file
--------------------------------------------------
</echo>
</target>
<target name="init">
<delete dir="${WEB-INF}/classes" />
<mkdir dir="${WEB-INF}/classes" />
</target>
<target name="compile" depends="init">
<javac srcdir="${basedir}/src"
destdir="${WEB-INF}/classes"
classpathref="libs">
</javac>
</target>
<target name="archive" depends="compile">
<delete dir="${OUT}" />
<mkdir dir="${OUT}" />
<delete dir="${TEMP}" />
<mkdir dir="${TEMP}" />
<copy todir="${TEMP}" >
<fileset dir="${basedir}/WebRoot">
</fileset>
</copy>
<move file="${TEMP}/log4j.properties"
todir="${TEMP}/WEB-INF/classes" />
<war destfile="${OUT}/${WAR_FILE_NAME}"
basedir="${TEMP}"
compress="true"
webxml="${TEMP}/WEB-INF/web.xml" />
<delete dir="${TEMP}" />
</target>
<path id="libs">
<fileset includes="*.jar" dir="${WEB-INF}/lib" />
</path>

Another option would be to build it automatically using Eclipse. Of course if you have continuous integration environment Ant or Maven is recommended. The export alternative is not very convenient because you have to configure every time the export properties.
STEPS:
Enable "Project Archives" support; this might depend on your project (I used it on Java EE/Web project). Right-click project root directory; Configure -> Add Project Archives Support.
Go and create a new archive in the "Project Archives" top dir. You have only jar option, but name you archive *.war.
Configure Fileset-s, i.e what files to be included. Typical is to configure two filesets similar how the Web Deployment Assembly (project property) is configured.
copy /WebContent to /
copy /build/classes to WEB-INF/classes (create this fileset after you define the WEB-INF/classes directory in the archive)
You might need to tweek the fileset exclude property depending where you placed some of the config files or you might need more filesets, but the idea is that once you configured this you don't need to change it.
Build the archive manually or publish directly to server; but is also automatically built for you by Eclipse

Another common option is gradle.
http://www.gradle.org/docs/current/userguide/application_plugin.html
To build your war file in a web app:
In build.gradle, add:
apply plugin: 'war'
Then:
./gradlew war
Use the layout from accepted answer above.

Simpler solution which also refreshes the Eclipse workspace:
<?xml version="1.0" encoding="UTF-8"?>
<project name="project" default="default">
<target name="default">
<war destfile="target/MyApplication.war" webxml="web/WEB-INF/web.xml">
<fileset dir="src/main/java" />
<fileset dir="web/WEB-INF/views" />
<lib dir="web/WEB-INF/lib"/>
<classes dir="target/classes" />
</war>
<eclipse.refreshLocal resource="MyApplication/target" depth="infinite"/>
</target>
</project>

Simplistic Shell code for creating WAR files from a standard Eclipse dynamic Web Project. Uses RAM File system (/dev/shm) on a Linux platform.
#!/bin/sh
UTILITY=$(basename $0)
if [ -z "$1" ] ; then
echo "usage: $UTILITY [-s] <web-app-directory>..."
echo " -s ..... With source"
exit 1
fi
if [ "$1" == "-s" ] ; then
WITH_SOURCE=1
shift
fi
while [ ! -z "$1" ] ; do
WEB_APP_DIR=$1
shift
if [ ! -d $WEB_APP_DIR ] ; then
echo "\"$WEB_APP_DIR\" is not a directory"
continue
fi
if [ ! -d $WEB_APP_DIR/WebContent ] ; then
echo "\"$WEB_APP_DIR\" is not a Web Application directory"
continue
fi
TMP_DIR=/dev/shm/${WEB_APP_DIR}.$$.tmp
WAR_FILE=/dev/shm/${WEB_APP_DIR}.war
mkdir $TMP_DIR
pushd $WEB_APP_DIR > /dev/null
cp -r WebContent/* $TMP_DIR
cp -r build/* $TMP_DIR/WEB-INF
[ ! -z "$WITH_SOURCE" ] && cp -r src/* $TMP_DIR/WEB-INF/classes
cd $TMP_DIR > /dev/null
[ -e $WAR_FILE ] && rm -f $WAR_FILE
jar cf $WAR_FILE .
ls -lsF $WAR_FILE
popd > /dev/null
rm -rf $TMP_DIR
done

**Making War file in Eclips Gaynemed of grails web project **
1.Import project:
2.Change the datasource.groovy file
Like this: url="jdbc:postgresql://18.247.120.101:8432/PGMS"
2.chnge AppConfig.xml
3.kill the Java from Task Manager:
run clean comand in eclips
run 'prod war' fowllowed by project name.
Check the log file and find the same .war file in directory of workbench with same date.

Related

Issue with class-path in manifest file during deployment in Tomcat

I am building the java project using Ant and I am using Ivy for the dependency management. There are two options in ant build for resolving the dependencies during the deployment. One is the lib mode, if this mode is enabled, all the dependent jars will be downloaded into project's WEB-INF/lib folder. Other is manifest mode which does not download any jar. During deployment, MANIFEST.MF (which has the class-paths to all the dependent jars) file will be used for resolving the jars.
Project is running properly when it is in lib mode, but when manifest is enabled, the build is successful but the deployment fails.
Please tell me how to fix this or what could be the reasons for this?
Note: Tomcat server is VWL enabled by default.
Thanks in advance.
Without an example one must speculate what your code looks like. The following example demonstrates the use of the ANT manifestclasspath task to construct a classpath suitable for a jar manifest file. The ivy "retrieve" task populates a relative direcotory containing the jars:
<target name="build" depends="compile">
<ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]"/>
<manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
<classpath>
<fileset dir="${dist.dir}/lib" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${dist.jar}" basedir="${build.dir}/classes">
<manifest>
<attribute name="Main-Class" value="${dist.main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
The following is a detailed example:
How to avoid copying dependencies with Ivy

Jar to Mac OSX App Bundle with app bundler

I'm trying to bundle my .jar to a MacOSX app bundle, using app bundler.
I'm following this tutorial.
It says to add a lib folder to the high-level project directory, but I don't know what that means. I've been looking everywhere for it, and I cannot find out what it is. That's my only problem I have, anyone know?
EDIT:
Here is my build.xml file:
<project name="Rage Mage" basedir=".">
<taskdef name="ragemage"
classname="com.oracle.appbundler.AppBundlerTask"
classpath="lib/appbundler-1.0.jar" />
<target name="bundle-RageMage">
<delete dir="appBundle" failonerror="false"/>
<mkdir dir="appBundle"/>
<bundleapp outputdirectory="bundle"
name="Rage Mage"
displayname="Rage Mage"
icon="res/icon.icns"
identifier="ragemage.src.Window"
mainclassname="ragemage.src.Window">
<classpath file="dist/ragemage_1.1.1.jar" />
</bundleapp>
</target>
Thanks!
Okay, so, after having a little play around, this is what I understand...
Download Java Application Bundler and place it in the lib directory of your project. You will need to create this directory...
Create a new Ant script into your project directory, call it what ever you like...Also, take the time to read through the AppBundler Task Docs
The ant script should be based on the following skeleton...
<project name="ButtonDemo" default="bundle-buttonDemo" basedir=".">
<taskdef name="bundleapp"
classname="com.oracle.appbundler.AppBundlerTask"
classpath="lib/appbundler-1.0.jar" />
<!-- See the lib reference here, this is why you need to use the lib directory! -->
<target name="bundle-buttonDemo">
<delete dir="appBundle" failonerror="false"/>
<mkdir dir="appBundle"/>
<bundleapp outputdirectory="appBundle"
name="ButtonDemo"
displayname="Button Demo"
identifier="components.ButtonDemo"
mainclassname="components.ButtonDemo">
<!-- The following is important and should point to your build -->
<classpath file="dist/ButtonDemo.jar" />
<!-- You can have multiple instance of classpath if you 3rd party or
dependent jars in different locations -->
</bundleapp>
</target>
</project>
Build your project
Run the ant script, using (something like) ant -f {You App Bundler script}
The app bundle, in this case ButtonDemo.app will be created in appBundle directory. If you can, browse the contents of the ButtonDemo.app/Contents/Java and make sure all your required Jar files are there...
Happy bundling!
Updated based on updated build.xml file
1- There is no default target specified by the project tag. Think of this like your "main class" or "main" method, without, ant has no idea what you want to run...
<project name="Rage Mage" basedir="." default="bundle-RageMage">
2- The name of the taskdef is significant and you use it in the any script to identify what ant should do when it hits your tag reference...
So based on your example, you either need to change the name of the taskdef from ragemage to bundleapp or change the bundleapp tag to ragemage...
Either change this...
<taskdef name="bundleapp"
classname="com.oracle.appbundler.AppBundlerTask"
classpath="lib/appbundler-1.0.jar" />
or this (in target bundle-RageMage)
<ragemage outputdirectory="bundle"
name="Rage Mage"
displayname="Rage Mage"
icon="res/icon.icns"
identifier="ragemage.src.Window"
mainclassname="ragemage.src.Window">
<classpath file="dist/ragemage_1.1.1.jar" />
</ragemage>
Personally, I'd leave it as bundleapp, but that's me...
3- The delete, mkdir and outputdirectory attribute of bundleapp are related...
<delete dir="appBundle" failonerror="false"/>
<mkdir dir="appBundle"/>
<bundleapp outputdirectory="bundle"...
Either, make them all appBundle or bundle, what every you want...
4- You main class is unlikely to be ragemage.src.Window and is probably going to be Window

How to set up a Java workspace without an IDE

I usually code with IDEs like Intellij Idea or Eclipse, but due to several reasons, I no longer have access to an IDE, and I'd like to be able to code in Java on a remote Linux machine through a ssh terminal.
Making simple progams with only a few classes is easy, but some of my projects have several libraries and several separate .java files. I also need to export to a .jar file.
For example, I have the following file organisation:
project/
src/
a.java
b.java
c.java
libs/
lib1.jar
lib2.jar
out/
export_here.jar
someconfig.conf
The java app consists of the a, b, and c .java files, uses libraries lib1 and lib2, and the file someconfig.conf needs to be inside the export jar.
I want to know how to easily compile and build a project such as this.
In other words, I just want to know how to export my project into a runnable jar the right way.
I expect this can be done with a few commands. If so, I plan to make a shell script to automate everything.
Thanks in advance!
As suggested by other users you need to use a build management tool to do this like Ant, Maven etc. I have used Ant quiet frequently to do these kind of automated tasks. In order to install and Use Ant you can refer How To Install Apache Ant
After that the main task is to write your automation script and that is called a build xml in ant world. Here is a sample build.xml file you can refer to start with:
<project>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="jar">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="oata.HelloWorld"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>
</project>
And for more information on the above sample You can visit this
In General you can read more at How to create build.xml
After creating your build.xml you can run ant by ant <path to build.xml> or ant in case your build.xml lies in current directory
Hope this helps you in right direction

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

create a .war file from gwt-project

How do I create a .war-file from my gwt-project in eclipse?
I always use Ant build file, so the project gets compiled and packaged as a war with one click.
Add an xml-file to your project with the following content:
<project name="test" basedir="." default="default">
<property name="src.dir" value="src" />
<property name="build.dir" value="war" />
<path id="compile.classpath">
<fileset dir="${build.dir}/WEB-INF/lib">
<include name="**/*.jar" />
<include name="**/*.xml" />
</fileset>
</path>
<target name="default" depends="gwtc, buildwar,deploy">
</target>
<target name="gwtc" description="GWT compile to JavaScript">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="${src.dir}" />
<path refid="compile.classpath" />
</classpath>
<arg line="-logLevel INFO" />
<jvmarg value="-Xmx1024M" />
<arg value="YourProject.EntryPointClass" />
</java>
</target>
<target name="buildwar">
<war basedir="war" destfile="YourProject.war" webxml="war/WEB-INF/web.xml">
<exclude name="WEB-INF/**" />
<webinf dir="war/WEB-INF/">
<include name="**/gwt-servlet.jar" />
<include name="**/classes/**" />
</webinf>
</war>
</target>
<target name="deploy">
<copy file="YourProject.war" todir="." />
</target>
</project>
(Edit `YourProject.EntryPointClass to the path to your EntryPoint-class)
You would need to add gwt-user.jar and gwt-dev.jarto your projects build path(right click on your project -> Build Path -> Add External Achives).
If you now look at your "Problems"-view you get a warning that the two files are not available on the server's class path. You can use the QuickFix to either copy it to WEB-INF/lib or hide the warning. The build file will not include those two file in the war-file.
All you need to do to compile and create the file is to right click the xml-file and select run as Ant Build.
Using Eclipse:
right click the project
choose Google→GWT Compile
when compilation has finished, the console will say i.e.
Linking into /home/janus/bpworkspace/gwtwerkstatt2/war/gwtwerkstatt2
Link succeeded
Compilation succeeded -- 28.623s
open a terminal and navigate to the directory
create the WAR: jar cv * > /tmp/myGWTproject.war
you can now launch it with jetty-runner or similar: java -jar jetty-runner-8.1.7.v20120910.jar /tmp/myGWTproject.war
I just found this solution, and it's amazing :)
Just install the jar and enjoy extracting to a war file.
Project Site
http://code.google.com/p/gwt-project-export-wizard/
One can also use webAppCreator to generate Ant build file.
webAppCreator ships with GWT SDK and also with Eclipse GWT Plugin. First locate GWT plugin directory
find $HOME/.eclipse/ -name "*gwt*sdk*"
this will output GWT plugin dir path. This dir has gwt dir something like gwt-2.4.0. WebAppCreator will be in this dir. Set this dir as GWTSDK_HOME.
export GWTSDK_HOME=/home/m/.eclipse/org.eclipse.platform_3.7.0_1364963873/plugins/com.google.gwt.eclipse.sdkbundle_2.4.0.v201201120043-rel-r37/gwt-2.4.0
make webAppCreator executable
chmod 755 $GWTSDK_HOME/webAppCreator
Now create a project using webAppCreator in some temp dir.
$GWTSDK_HOME/webAppCreator -out fins in.m.fins.Fins
in.m.fins.Fins is the module name. This has to match with your project's gwt.xml in Eclipse workspace. If your gwt.xml is src/in/m/fins/Fins.gwt.xml then module name should be in.m.fins.Fins
-out fins will create the project and build.xml in fins directory. Copy generated build.xml file to your project in Eclipse workspace.
Run war target in Eclipse Ant Window to package your project as war
You have to have GWT designer installed from here
http://dl.google.com/eclipse/inst/d2gwt/latest/3.7
In Eclipse on the main panel click on "Deploy module on aplication server" (It's next to blue google button).
Chose war file name and location where to store it
Click ok
That's it. Works on my GWT 2.4.0, Google Plugin for Eclipse 4.2, Eclipse Juno
For future reference: you'll find another tutorial on how to create a .war using Eclipse on http://blog.elitecoderz.net/.
Fist compile your project. Then:
1. Open your project.
2. Navigate to war folder.
3. Go to File>Export>Archive File
4. Export your war FOLDER as zip file.
5. Change your file extension form .zip to .war
6. Keep calm and enjoy your war file.
Compile your project. Then:
Open your project.
Navigate to war folder.
Go to File>Export>Archive File
Export your war FOLDER as zip file.
Change your file extension form .zip to .war
Keep calm and enjoy your war file.

Categories