Java WAR file description:
Java Web ARchive files are used to bundle web applications in a "zip" file for use with a Java applications server such as Tomcat or JBoss.
The Java WAR file is a Java standard for deployment of a bundled group of JSP, Java servlets, html, javascript, images and other files for necessary for the development of web applications.
The WAR file is generated with the Java "jar" command and follows a directory hierarchy as shown here:
WebAppX/
/META-INF/MANIFEST.MF
/WEB-INF/web.xml
| /classes/
| | /ServletA.class
| | /ServletB.class
| | /ServletC.class
| | /aa/bb/cc/ServletD.class
| | /com/megacorp/ProjX/
| | | /Abc.class
| | | /Ijk.class
| /tags/
/lib/
| /filea.jar
| /fileb.jar
| /filec.jar
/index.html
/my.css
/images/my.png
/xxx.jsp
/yyy.jsp
/zzz.jsp
Note:
- /META-INF: This directory and its contents are generated by the "jar" command. Does not have to be explicitly generated.
- /META-INF/services: contents of jar file
- /META-INF/MANIFEST.MF: only one manifest
- /WEB-INF: Required for servlet support and any class files to be called by JSP or servlets. There is only one /WEB-INF. It must be defined at the lot directory in the WAR file and can not be nested to a lower directory.
- /WEB-INF/web.xml: Required only to register servlets.
- Once deployed, this web application would be called using the URL http://localhost:8080/WebAppX/
- Servlet URLs: http://localhost:8080/WebAppX/ServletA is mapped from its class name to its URL name by the web.xml file.
ServletC mapping to URL: http://localhost:8080/WebAppX/ServletC
WAR File Creation:
Command: jar cf WebAppX.war .
Where this command is executed in the same directory which contains the index.html (or index.jsp) and WEB-INF directory.
Also see the jar man page
WAR file and Servlets:
Where the file /WEB-INF/web.xml maps the servlet name to the URL display name.
01 | <? xml version = "1.0" encoding = "ISO-8859-1" ?> |
03 | PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" |
06 | < display-name >Welcome to our server</ display-name > |
07 | < description >Welcome to our server</ description > |
09 | < servlet-name >Servlet-A</ servlet-name > |
10 | < servlet-class >ServletA</ servlet-class > |
13 | < servlet-name >Servlet-B</ servlet-name > |
14 | < servlet-class >ServletB</ servlet-class > |
17 | < servlet-name >Servlet-C</ servlet-name > |
18 | < servlet-class >aa.bb.cc.ServletC</ servlet-class > |
22 | < servlet-name >Servlet-A</ servlet-name > |
23 | < url-pattern >/ServletA</ url-pattern > |
26 | < servlet-name >Servlet-B</ servlet-name > |
27 | < url-pattern >/ServletB</ url-pattern > |
30 | < servlet-name >Servlet-C</ servlet-name > |
31 | < url-pattern >/ServletC</ url-pattern > |
35 | < welcome-file >index.jsp</ welcome-file > |
36 | < welcome-file >index.html</ welcome-file > |
37 | < welcome-file >index.htm</ welcome-file > |
Note that this example shows a
web.xml file defining three separate servlets to be deployed in the WAR file.
Where XML tags must appear in the following order:
- <context-param>
- <filter>
- <filter-mapping>
- <listener>
- <servlet>
- <servlet-mapping>
- <session-config>
- <mime-mapping>
- <welcome-file-list>
- <error-page>
- <taglib>
- <resource-env-ref>
- <resource-ref>
- <security-constraint>
- <login-config>
- <security-role>
- <env-entry>
- <ejb-ref>
- <ejb-local-ref>
Note that the following will
NOT work:
Must order all <servlet> tags together then <servlet-mapping>, etc
When not ordered properly you will get the error:
Caused by: org.xml.sax.SAXException: The content of element type "web-app" must match ...
Example servlet:
05 | import javax.servlet.*; |
06 | import javax.servlet.http.*; |
08 | public class ServletA extends HttpServlet |
10 | protected void doGet(HttpServletRequest request, HttpServletResponse response) |
11 | throws ServletException, IOException |
13 | doit(request, response); |
16 | protected void doPost(HttpServletRequest request, HttpServletResponse response) |
17 | throws ServletException, IOException |
19 | doit(request, response); |
23 | * Class description goes here |
27 | * @throws ServletException |
30 | protected void doit(HttpServletRequest request, HttpServletResponse response) |
31 | throws ServletException, IOException |
33 | String value = request.getParameter( "param-name" ); |
JSP call to class in WAR file:
1 | <%@ page language= "java" import = "com.megacorp.YYY.XXX.Abc" %> |
4 | String sss = abc.methodA(argx); |
[Potential Pitfall]: incorrect object instantiation
Error:
Abc abc = new Abc;
Syntax error on token "new", delete this token
Fix:
Abc abc = new Abc();
Ant file to generate a WAR file:
file:
build.xml
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
02 | < project name = "ProjX" default = "all" basedir = "." > |
03 | < description >Builds, tests, and runs the project ProjX.</ description > |
04 | < property name = "build.dir" value = "./" /> |
05 | < property name = "lib.src.dir" location = "${build.dir}/src/lib" /> |
06 | < property name = "servlets.src.dir" location = "${build.dir}/src/servlets" /> |
09 | < path id = "classpath.base" > |
10 | < pathelement location = "/usr/java/latest/lib/tools.jar" /> |
11 | < pathelement location = "/opt/jboss-6.0.0.20100721-M4/lib/jbosssx.jar" /> |
12 | < pathelement location = "/opt/jboss-6.0.0.20100721-M4/client/jboss-servlet-api_3.0_spec.jar" /> |
16 | < echo message = "Available targets are:" /> |
17 | < echo message = "clean - Remove WebAppX.war and class files." /> |
18 | < echo message = "war - Generate war file to deploy to JBoss." /> |
19 | < echo message = "war-deploy - Copy war file to JBoss war file deployment directory." /> |
22 | < target name = "clean" description = "Remove .class and .jar files" > |
23 | < delete includeEmptyDirs = "true" failonerror = "false" > |
24 | < fileset dir = "${servlets.src.dir}" > |
25 | < include name = "**/*.class" /> |
27 | < fileset dir = "${lib.src.dir}" > |
28 | < include name = "**/*.class" /> |
30 | < fileset dir = "WEB-INF/classes" > |
31 | < include name = "**/*.class" /> |
34 | < include name = "WebAppX.war" /> |
38 | < target name = "compile-war-lib" > |
39 | < mkdir dir = "WEB-INF/classes" /> |
40 | < javac srcdir = "${lib.src.dir}" destdir = "WEB-INF/classes" debug = "true" includeAntRuntime = "false" > |
41 | < classpath refid = "classpath.base" /> |
42 | < include name = "**/*.java" /> |
46 | < target name = "compile-war" depends = "compile-war-lib" > |
47 | < mkdir dir = "WEB-INF/classes" /> |
48 | < javac srcdir = "${servlets.src.dir}" destdir = "WEB-INF/classes" debug = "true" includeAntRuntime = "false" > |
49 | < classpath refid = "classpath.base" /> |
50 | < classpath refid = "classpath.lib" /> |
51 | < include name = "**/*.java" /> |
55 | < target name = "war" depends = "compile-war,other-dependencies-go-here" > |
56 | < war destfile = "WebAppX.war" webxml = "WEB-INF/web.xml" > |
58 | < include name = "**/*.jsp" /> |
59 | < include name = "**/*.css" /> |
60 | < include name = "**/*.png" /> |
61 | < include name = "index.html" /> |
62 | < include name = "WEB-INF/**/*.class" /> |
63 | < exclude name = "**/.svn/**" /> |
64 | < exclude name = "test/**" /> |
65 | < exclude name = "src/**" /> |
70 | < target name = "war-deploy" depends = "war" description = "Deploy application as a WAR file" > |
71 | < copy todir = "${deploy.dir}" preservelastmodified = "true" > |
73 | < include name = "*.war" /> |
78 | < target name = "all" depends = "war" /> |
Note the use of the <war> ant task. The <jar> ant task can also be used to generate a WAR file but jar is more work as the user must specify much more detailed information.
Given the following source tree:
ProjX/src/servlets/ServletA.java
| | /ServletB.java
| /lib/com/megacorp/YYY/XXX/Abc.java
| | /Ijk.java
/deploy/WebAppX/
/index.html
/xxx.jsp
/WEB-INF/web.xml
| /classes/
| | /ServletA.class
| | /ServletB.class
| | /com/megacorp/YYY/XXX/Abc.class
| | | /Ijk.class
/...
or some put the source in deployed folders and let ant pick what is needed to assemble the WAR file:
ProjX/WebAppX/index.html
/xxx.jsp
/WEB-INF/web.xml
| /classes/
| | /ServletA.class
| | /ServletB.class
| | /src/
| | /src/servlets/ServletA.java
| | /src/servlets/ServletB.java
| | /src/com/megacorp/YYY/XXX/Abc.java
| | | /Ijk.java
| | /com/megacorp/YYY/XXX/Abc.class
| | | /Ijk.class
WAR File Deployment:
Tomcat:
Copy the WAR file to
$CATALINA_HOME/webapps/WebAppX.war
Where that resolves to (RHEL6 RPM package): /var/lib/tomcat6/webapps/
Tomcat 8 Apache binary download installation: /opt/apache-tomcat-8.0.0-RC1/webapps/
JBoss:
Simply copy the WAR file to
$JBOSS_HOME/server/default/deploy/WebAppX.war
Exploded WAR files: Note that the WAR file can be "un-jar'ed" and expanded on the file system.
$JBOSS_HOME/server/default/deploy/WebAppX.war/WEB-INF/web.xml
/classes/
Sometimes this eases JSP development but can cause servlet complications as well.
The JBoss server will not recognize servlet updates and you need to restart the JBoss server in order to pick up the changes. JSP development is simplified as JSP pages can be edited in place and tried immediately.
Use the URL
http://localhost:8080/WebAppX/file.jsp
Individual JSP pages can also be developed in the default WAR directory:
$JBOSS_HOME/server/default/deploy/ROOT.war/file.jsp
Use the URL http://localhost:8080/file.jsp
Example:
Hello World Tomcat servlet example WAR file:
Directory set-up:
- mkdir -p src/main/java/com/megacorp/projectx
- mkdir -p src/main/webapp/WEB-INF
File:
src/main/java/com/megacorp/projectx/HelloWorld.java
01 | package com.megacorp.projectx; |
06 | import javax.servlet.*; |
07 | import javax.servlet.http.*; |
09 | public class HelloWorld extends HttpServlet { |
11 | public void doGet(HttpServletRequest request, |
12 | HttpServletResponse response) |
13 | throws IOException, ServletException |
15 | response.setContentType( "text/html" ); |
16 | PrintWriter out = response.getWriter(); |
17 | out.println( "<html>" ); |
18 | out.println( "<head>" ); |
19 | out.println( "<title>Hello World!</title>" ); |
20 | out.println( "</head>" ); |
21 | out.println( "<body>" ); |
22 | out.println( "<h1>Hello World!</h1>" ); |
23 | out.println( "</body>" ); |
24 | out.println( "</html>" ); |
File:
src/main/webapp/WEB-INF/web.xml
01 | <? xml version = "1.0" encoding = "UTF-8" ?> |
07 | metadata-complete = "true" > |
09 | < description >Hello World</ description > |
10 | < display-name >Hello World</ display-name > |
13 | < servlet-name >HelloWorld</ servlet-name > |
14 | < servlet-class >com.megacorp.projectx.HelloWorld</ servlet-class > |
18 | < servlet-name >HelloWorld</ servlet-name > |
19 | < url-pattern >/HelloWorld</ url-pattern > |
This associates the class
com.megacorp.projectx.HelloWorld to a URL path
/HelloWorld
Maven Build File:
./pom.xml
03 | < modelVersion >4.0.0</ modelVersion > |
04 | < groupId >com.megacorp.projectx</ groupId > |
05 | < artifactId >ProjectX</ artifactId > |
06 | < packaging >war</ packaging > |
07 | < version >1.0-SNAPSHOT</ version > |
12 | < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > |
17 | < groupId >javax.servlet</ groupId > |
18 | < artifactId >javax.servlet-api</ artifactId > |
19 | < version >3.1.0</ version > |
20 | < scope >provided</ scope > |
27 | < groupId >org.apache.maven.plugins</ groupId > |
28 | < artifactId >maven-war-plugin</ artifactId > |
29 | < version >3.2.3</ version > |
31 | < warSourceDirectory >src/main/webapp</ warSourceDirectory > |
32 | < webappDirectory >/opt/apache-tomcat-9.0.30/webapps/projectx/</ webappDirectory > |
36 | < groupId >org.apache.maven.plugins</ groupId > |
37 | < artifactId >maven-compile-plugin</ artifactId > |
38 | < version >3.1</ version > |
[Potential Pitfall]: Error:
package javax.servlet.http does not exist cannot find symbol
POM file requires dependency "javax.servlet-api" to fix this error.
Build:
- Generate WAR file: mvn package
This will generate target/Hello-1.0-SNAPSHOT.war
- Deploy WAR file: mvn install
This will install the servlet to Tomcat's "webappDirectory" /opt/apache-tomcat-9.0.30/webapps/projectx/
Inspect the contents of the war file:
jar tf target/Hello-1.0-SNAPSHOT.war
META-INF/MANIFEST.MF
META-INF/
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/com/
WEB-INF/classes/com/megacorp/
WEB-INF/classes/com/megacorp/projectx/
WEB-INF/classes/com/megacorp/projectx/HelloWorld.class
WEB-INF/web.xml
META-INF/maven/com.megacorp.projectx/Hello/pom.xml
META-INF/maven/com.megacorp.projectx/Hello/pom.properties
Test:
http://localhost:8080/projectx/HelloWorld
Links:

Books:
 |
"Core Java 2, Volume 1: Fundamentals "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354764, Prentice Hall PTR 8th edition
The industry standard. Need I say more?
|
|
 |
"Core Java 2: Volume 2 Advanced Features "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354799, Prentice Hall PTR 8th edition
The industry standard. Need I say more?
|
|
 |
"Core Java Server Faces"
by David Geary, Cay S. Horstmann
ISBN # 0131738860, Prentice Hall PTR 2nd edition
|
|
 |
"JSP, Servlets, and MySQL"
by David Harms
ISBN # 0764547879, Hungry Minds, Inc
|
|