Creating and Packaging the Application


The application is the soon-to-be-classic "The Great Albert Einstein Quote Machine." The application is simple; it consists of five files, including the build file.


Tip: To save yourself some typing, you can download the example code for this book from the O'Reilly web site, http://www.oreilly.com. You'll be able to find it on the same page as this book's listing.

In this section we look at the required files for a simple JBoss web application, and the build file to package them up so that JBoss can run them.

How do I do that?

Since our application is a web application, it is packaged as a WAR file for deployment on the server. The WAR file has places for JSPs, HTML, libraries, and metadata (see Figure 2-1).

Let's look at the files that go into a WAR file; as we talk about each file we'll identify where it goes in the WAR file.

Developer's Notebook 2-1. Standard WAR file structure


The first file is the core of our application, quote.jsp:

     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>     <%@ page import="java.util.ArrayList" %>     <%@ page import="java.util.Random" %>          <%       //List of sayings       String[  ] quotes = {         "Before God we are all equally wise - and equally foolish",         "I never think of the future - it comes soon enough",          "Imagination is more important than knowledge...",          "Reality is merely an illusion, albeit a very persistent one",          "The important thing is not to stop questioning",          "The secret to creativity is knowing how to hide your sources",          "Science without religion is lame, religion without science is blind",          "Everything that is really great and inspiring is created by" +             "the individual who can labor in freedom"       };       ArrayList list = new ArrayList(Arrays.asList(quotes));        Random r = new Random(  );       int x = r.nextInt(list.size(  ));       String saying = (String)list.get(x);        saying = saying + " -- Albert Einstein";       pageContext.setAttribute("saying", saying);     %>          <html>       <head>           <title>JBoss Notebook Chapter 2 Demo 1</title>       </head>       <body>         <br>         <c:set var="sessionCount" scope="session"                 value="${sessionCount + 1}" />         <c:set var="applicationCount" scope="application"                 value="${applicationCount + 1}" />         <h1>             <font color="#1230cb">The Great Albert Einstein Quote Machine</font>         </h1>         <h3>             <spacer size="32" type="horizontal">             <font color="#a6a6a6">                 ${saying}             </font>         </h3>         <br><br>         You've visited this application ${sessionCount}         times in this session         <br>         and the application has been visited ${applicationCount}         times by you and others.         </body>     </html> 


Note: We've made use of JSTL tags here. JBoss doesn't provide a JSTL implementation, so we had to include one with the application.

The application displays a random quotation from an array of Einstein's quotes. The code to select the quote is a JSP scriptlet at the top of the page. In a larger application, we'd prefer that this code not be in the JSP. But for illustrative purposes, it's just fine. The application also manages a hit counter. That will be useful to us later, to detect when the application has been redeployed.

The static JSP and HTML files live in the top directory of the WAR file, so our quote.jspfile will go at the top of the directory structure in the quotes directory.

The next file, web.xml, goes into the WEB-INF directory. The web.xml file describes the web application and how the web container will deploy the application.

     <?xml version="1.0" ?>     <web-app xmlns="http://java.sun.com/xml/ns/j2ee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee                             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"         version="2.4">              <servlet>             <servlet-name>QuoteServlet</servlet-name>             <jsp-file>/quote.jsp</jsp-file>         </servlet>         <servlet-mapping>             <servlet-name>QuoteServlet</servlet-name>             <url-pattern>/quote</url-pattern>         </servlet-mapping>     </web-app> 

Notice that the quote.jsp file we looked at before is related to a servlet named QuoteServlet. This is the name of the servlet that the quote.jsp file is exposed as. Next you can see the URL pathname that we will use to refer to the servlet when we are in the web browser.

Any dependent JAR files for libraries you might use in your web application go in the lib directory. The classes directory contains the beans or servlets you've created for your application. We have no beans or servlets for our example application. That's it for the WAR file.

Let's look at the Ant build file that creates our WAR file from our sources and libraries. You can see the setup for development sources in Figure 2-2.

Developer's Notebook 2-2. Quote source directories


The Ant build file, build.xml, pulls together all the stuff for our application, and makes the WAR file. It also has tasks for deploying, undeploying and cleaning.

     <?xml version="1.0"?>          <!-- Build file for hello_world project for Chapter 2 of JBoss Notebook -->     <project name="Hello World Buildfile" default="main" basedir=".">         <!-- Standard Properties -->         <property name="top.dir" value="."/>         <property name="src.dir" value="${top.dir}/src"/>         <property name="lib.dir" value="${top.dir}/src/lib"/>         <property name="jboss.dir" value="/users/samjr/jboss-4.0.2"/>         <property name="jboss.deploy.dir"                   value="${jboss.dir}/server/default/deploy"/>              <target name="clean">             <echo message="In clean"/>             <delete file="${top.dir}/quote.war"/>         </target>              <target name="main">             <echo message="In main"/>             <war warfile="quote.war" webxml="${src.dir}/metadata/web.xml">                 <fileset dir="${src.dir}/appfiles"/>                 <lib dir="${lib.dir}"/>             </war>             <antcall target="deploy"/>         </target>              <target name="deploy">             <echo message="In deploy"/>             <copy file="${top.dir}/quote.war" todir="${jboss.deploy.dir}"/>         </target>              <target name="undeploy">             <echo message="In undeploy"/>             <delete>                 <fileset  dir="${jboss.deploy.dir}"                     includes="*quote*.war"/>             </delete>         </target>          </project> 


Note: You can also set the jboss.dir property from the command line using the -D option to Ant or an Ant properties file, but you'll probably find it more convenient to just edit the build file.

For this build.xml file to work for you you'll have to change the jboss.dir property to point to the directory in which you installed JBoss.

Open a terminal window and go to the quotes directory. Type ant to kick off the build. This command triggers the default build path, which is specified by the default property in the project tag. In our Ant build file, the default case is to call the main target. Our main target also runs the deploy target, so as soon as the application is packaged up in a WAR file, it is copied over to the server's deploy directory.

The most important part of the build.xml file for this example is the war tag in the main target. That war tag creates the WAR file we'll deploy by packing up the web.xmlfile, our JSP, and the JSTL libraries that we talked about before.

     [quote]$ ant     Buildfile: build.xml          main:          [echo] In main           [war] Building war: /Users/samjr/JBossNotebookWorkingCopies/quote/quote.war          deploy:          [echo] In deploy          [copy] Copying 1 file to /users/samjr/jboss-4.0.2/server/default/deploy          BUILD SUCCESSFUL     Total time: 4 seconds 

Web applications have to be deployed using the WAR file format in JBoss. There is no easy-to-include web content outside of a WAR file.


In the terminal window where you have JBoss running, you should see something like this:

     05:30:14,655 INFO  [Server] JBoss (MX MicroKernel) [4.0.2RC1 (build:     CVSTag=JBoss_4_0_2_RC1 date=200503140913)] Started in 53s:894ms     05:30:29,107 INFO  [TomcatDeployer] undeploy, ctxPath=/quote, warUrl=file:/     Users/samjr/jboss-4.0.2/server/default/tmp/deploy/tmp12811quote.war/     05:30:29,273 INFO  [TomcatDeployer] deploy, ctxPath=/quote, warUrl=file:/     Users/samjr/jboss-4.0.2/server/default/tmp/deploy/tmp12812quote.war/ 


Note: If you are running JBoss in a clustered environment, you can use the farm service to deploy or undeploy an application across the entire cluster.

The output shows that we deployed the application right after the server started. There aren't any stack traces (a good sign), and the word deploy appears right after [TomcatDeployer]. If there is already a WAR file of the same name, JBoss undeploys it and redeploys the new version of your application. In this example, we had our application deployed already. When we rebuilt and redeployed the application, JBoss took care of getting the old version out and putting the new version in. This is called hot deployment. This feature allows you to upgrade your application without taking the server offline.

What just happened?

You ran the build script, which created a WAR file with quote.jsp, two libraries (jstl.jar and standard.jar), and the web.xml file in it. Additionally, the build script copied the WAR file over to the deploy directory of the server's default configuration.


Note: This behavior is controlled by the deployment scanner service. Like all services, it is completely configurable. With it, you can control where JBoss looks for applications and how frequently it checks for updates.

Then you saw in the window where you see the basic logging output from the server that the web application did indeed deploy. You also saw how hot deployment allows you to redeploy an application in a live server.

If you didn't have a build script that copied the WAR file over to the deploy directory, you could do it by hand and you would still see the application being deployed in the server's terminal window. The build script did nothing besides copy the WAR file to the deployment directory. No special configuration was needed. JBoss just sensed that a new file was there to be deployed, scanned it to find the deployment descriptor, and then did its thing. Nice and easy.

What about...

...deployment errors?

If you had an error, you'd see it in the console log. This is usually accompanied by a stack trace or other contextual information to give you an idea of what the problem is. If you don't see any errors, you can be fairly certain the application deployed successfully. As an example, we tried to deploy a WAR file with an invalid web.xml file. This caused the following error message:

     17:48:16,033 ERROR [XmlFileLoader] Invalid XML: file=file:/private/tmp/     jboss-4.0.2/server/default/tmp/deploy/tmp2254quote.war//WEB-INF/web.xml@1:2     ...     17:48:17,464 ERROR [ContextConfig] Occurred at line 2 column 1     17:48:17,464 ERROR [ContextConfig] Marking this application unavailable due     to previous error(s)     17:48:17,464 ERROR [StandardContext] Error getConfigured     17:48:17,469 ERROR [StandardContext] Context startup failed due to previous     errors17:48:17,503 ERROR [WebModule] Starting failed jboss.web.deployment:     id=-110422429,war=quote.war     org.jboss.deployment.DeploymentException: URL file:/private/tmp/jboss-4.0.2/     server/default/tmp/deploy/tmp2254quote.war/ deployment failed     ...     17:48:17,522 WARN  [ServiceController] Problem starting service jboss.web.     deployment:id=-110422429,war=quote.war     org.jboss.deployment.DeploymentException: URL file:/private/tmp/jboss-4.0.2/     server/default/tmp/deploy/tmp2254quote.war/ deployment failed 


Note: Use the tail command on the log files to monitor what is being logged.

The output is much more verbose than what we've shown here, but the error messages give you a very clear picture of what is wrong.

What about getting more detailed information about the deployment process?

The server log file, server/default/logs/server.log, contains more detailed logging information about the deployment process. If you are trying to track down a non-critical deployment error, the information there can be very helpful. Here's an example:

     2005-03-21 05:30:29,178 DEBUG [org.jboss.deployment.MainDeployer] Starting     deployment of package: file:/Users/samjr/jboss-4.0.2/server/default/deploy/     quote.war     2005-03-21 05:30:29,179 DEBUG [org.jboss.deployment.MainDeployer] Starting     deployment (init step) of package at: file:/Users/samjr/jboss-4.0.2/server/     default/deploy/quote.war     2005-03-21 05:30:29,179 DEBUG [org.jboss.deployment.MainDeployer] Copying     file:/Users/samjr/jboss-4.0.2/server/default/deploy/quote.war -> /Users/     samjr/jboss-4.0.2/server/default/tmp/deploy/tmp12812quote.war     2005-03-21 05:30:29,190 DEBUG [org.jboss.deployment.MainDeployer] using     deployer org.jboss.web.tomcat.tc5.Tomcat5@54b5d4     2005-03-21 05:30:29,190 DEBUG [org.jboss.web.tomcat.tc5.Tomcat5] Begin init     2005-03-21 05:30:29,195 DEBUG [org.jboss.web.tomcat.tc5.Tomcat5] Unpacking     war to: /Users/samjr/jboss-4.0.2/server/default/tmp/deploy/tmp12812quote-     exp.war     2005-03-21 05:30:29,251 DEBUG [org.jboss.web.tomcat.tc5.Tomcat5] Replaced     war with unpacked contents          [more lines of info removed for brevity]          ] Initialized: {WebApplication: /Users/samjr/jboss-4.0.2/server/default/tmp/     deploy/tmp12812quote.war/, URL: file:/Users/samjr/jboss-4.0.2/server/     default/tmp/deploy/tmp12812quote.war/, classLoader: java.net.     FactoryURLClassLoader@dcf865:14481509} jboss.web:     J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/     quote     2005-03-21 05:30:29,579 DEBUG [org.jboss.web.WebModule] Started jboss.web.     deployment:id=-381072946,war=quote.war     2005-03-21 05:30:29,579 DEBUG [org.jboss.system.ServiceController] Starting     dependent components for: jboss.web.deployment:id=-381072946,war=quote.war     dependent components: [  ]     2005-03-21 05:30:29,579 DEBUG [org.jboss.webservice.ServiceDeployer]     handleNotification: org.jboss.deployment.SubDeployer.start,quote.war     2005-03-21 05:30:29,600 DEBUG [org.jboss.deployment.MainDeployer] End     deployment start on package: quote.war     2005-03-21 05:30:29,600 DEBUG [org.jboss.deployment.MainDeployer] Deployed     package: file:/Users/samjr/jboss-4.0.2/server/default/deploy/quote.war 

You can see that the WAR file is unpacked, and the unpacked version replaces the packed version, etc. We took out a lot to fit it in the book, but needless to say there is a lot to see and you should go look around.



JBoss. A Developer's Notebook
JBoss: A Developers Notebook
ISBN: 0596100078
EAN: 2147483647
Year: 2003
Pages: 106

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net