War deployment file structure

What’s a war deployment, do I need my own army?

When it comes to deploying an web based application we have a few options on the table. Well only one really if you stick to J2EE standards, not counting Ear deployments which also deploy web apps via wars. Outside the world of J2EE though, it becomes a crap shoot based on the web framework you’re using. So what’s a war look like?

webapp.war
	|-- images/
	|   `-- banner.jpg
	|-- index.html
	|-- jsps/
	|   |-- public/
	|   |   `-- login.jsp
	|   `-- private/
	|       |-- application.jsp
	|       `-- settings.jsp
	`-- WEB-INF/
	    |-- lib/
	    |   `-- some-library.jar
	    |-- classes/
	    |   `-- compiled.class
	    `-- web.xml

There are 2 sections which pretty much divide up the entire archive. All the stuff directly inside the root / of the war file, and then everything that’s inside the WEB-INF directory. The key difference between the two is one is publicly accessible while the other one has protected access; it’s a violation of the spec for an application server to allow public exposure to anything in the WEB-INF folder of your application.

Context

Your war file has an application context. An application context is the reserved namespace your web application has in relation to the application server’s qualified domain name. For example, if on startup you bound jboss to the localhost domain your server’s fully qualified url would be:

http://localhost:8080/

This represents the root of your application server. If you are deploying a single war/a single web application, by default your application will take on the context name of the war file. So in our example above, if we wanted to access webapp.war’s deployed application we would need to call it this way:

http://localhost:8080/webapp

Jboss only!

Out of the box, jboss comes with a default ROOT.war application in the deploy directory that links to other jboss web applications. One great thing about jboss is you can set up your configuration instance to deploy whatever components you want, meaning you can remove this ROOT.war file and use your own as the context root. You would need to replace the default ROOT.war file with the contents of your war file to make your application use the same context. This is kind of messy though, so I would recommend just removing the ROOT.war file and instead stick a jboss-web.xml file in your war’s WEB-INF directory configured like this:

 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3//EN" 
    "http://www.jboss.org/j2ee/dtd/jboss-web_3_0.dtd">

<jboss-web>

   <context-root>/</context-root>

</jboss-web>

The context-root element here basically tells jboss to load up the war file into the root context of the application server, so calls to “http://localhost:8080/” will be processed by your war file. There’s also a way to map virtual hosts in jboss, discussed in another article, Virtual hosting with Jboss.

Compiled Resources

The other 2 things that need to go into the WEB-INF directory are the WEB-INF/lib and WEB-INF/classes directories. The /lib directory is a place where you put all of your web application’s third party jar files, as well as any jar’d up version of your custom code and resources. If you choose not to jar up all your custom code and resources you can then stick all your .class files and application resources in the WEB-INF/classes directory. From my point of view, its cleaner to just jar everything up and stickem in the /lib directory. Naked class files and resources are so.. messy.. But that’s just my opinion. It’s important to note, if you have empty /lib or /class directories you don’t need to include them in your deployment, they are only required if you are going to stick resources in there.

Static Resources

Now that you’ve figured out all your application resources, you can then then stick all your static resources in the root of your war file. I should point out that there are two sides of the fence about how you should proceed about this though; purists think everything but the basics need to be obscured from the user to prevent them from hacking urls/jsps (by sticking jsps in the WEB-INF, hiding them from exposure) while other folks don’t really care. I think the folks don’t really care that much because they’re using a web framework that hides the true jsp paths and file names. If you’re not using a web framework, it better be for a good reason. You then might want to consider obscuring the jsps in the WEB-INF.

That’s pretty much all there is to a war’s file structure. When it comes time to deploy, most of the time the war file is deployed as a zipped up archive. Jboss also supports the notion of exploded wars, which is basically just an unzipped war file. Exploded wars are like a double edges sword though – if you deploy as an exploded war you get the benefit of not having to redeploy the entire application if you want to fix something like text on a page. Be wary though, circumventing a build process is never a good idea. Build process is there for a reason, its purpose is to track code, updates and and make sure only tested code is released.



Related posts:

  1. Ejb3 Basics: Bean Managed Transactions
  2. Using Jboss System Properties
  3. Ejb3 Basics: Deploying Message Driven Beans

Comments (1)

  1. avatar

    9:39 am, January 25, 2010John Smith  / Reply

    Or instead of doing a non-standard jboss only thing, you could put a context.xml in META-INF which follows the servlet standard unlike the jboss specific file.

Pingbacks (0)

› No pingbacks yet.