Have you noticed that simply saying “I am a Java programmer” isn’t enough these days? It conveys a little bit of information, but not enough to make any serious decisions. It’s kind of like saying, “I play sports” or “I like food.” A recruiter can assume that a Java programmer has a passing familiarity with curly braces and semicolons, but little else.
The Java programming language runs on an incredibly diverse set of hardware—from cell phones and PDAs down to embedded chips on a credit card; every major desktop and laptop, regardless of operating system or hardware manufacturer; entry-level workgroup servers up to clusters of high-end servers; and even mainframes.
The mantra in the heady early days of Java was, “Write once, run anywhere.” The original ideal of having the same application run anywhere from a cell phone to a large-scale cluster of servers turned out to be more marketing hype than business reality, although the “run anywhere” part of the slogan has proven remarkably prescient.
Modern Java developers often define themselves by the hardware they specialize in. J2ME developers eke amazing functionality out of resource-starved micro-devices with limited networking capabilities. J2SE programmers have mastered daunting but robust GUI frameworks such as Swing and SWT for rich desktop application development. And J2EE software engineers are masters of the server-side domain.
Saying that you are a J2EE programmer begins to narrow the field a bit, but our hypothetical recruiter still doesn’t have enough information to place you in the proper job. J2EE is a loose collection of server-side technologies that are related, but are by no means homogenous.
Some J2EE experts specialize in web-related technologies—JSPs, Servlets, and the diverse landscape of web frameworks such as Jakarta Struts or Sun’s Java Server Faces. Others are back-end specialists that focus more on the transactional integrity and reliability of business processing that uses technologies such as EJBs, JMS, and relational databases. (We’ll define these acronyms later in the book.) There is even a new breed of Web Services specialists that use the J2EE product suite and a host of related XML technologies, such as SOAP and WSDL, to offer a Service Oriented Architecture to Java and non-Java clients alike.
Asking any one specialist to describe the J2EE toolkit brings to mind the story of the blind men and the elephant. Each blind man describes the elephant based on the part he touches—the one holding the trunk describes a very different animal than the one holding the tusk or the ear.
This book attempts to describe the whole elephant in the context of JBoss, an open source J2EE container. Like the technology it implements, JBoss is not a single monolithic application. Rather, it is a family of interrelated services that correspond to each item in the J2EE collection.
Each chapter in this book explores one of the J2EE services, but unlike the blind men, we show how one technology works in conjunction with the others. A J2EE application is often greater than the sum of its parts, and understanding the J2EE collection means understanding how each piece is interrelated.
Before we get too far into things, we should explain why we chose the title JBoss at Work for this book. Understanding the authors’ backgrounds should help.
Both of us are practicing software engineers who have worked together off and on for years. More importantly, both of us are former presidents of the Denver Java Users Group (http://www.denverjug.org). When we polled the group for potential interest in a given subject, the same phrase came up over and over again: “I don’t want to be an expert in it, I just want to make it work.”
“I just want to make it work” really resonates with us because we feel the same way. An ever-growing number of technologies fall under the J2EE umbrella, and there are at least two or three competing implementations of each. Just trying to keep up is a never-ending battle.
There is a 1,000-page book out there for each topic we cover in only 20 to 30 pages. JBoss At Work isn’t intended to be an exhaustive discussion of every facet of the J2EE collection. This book is meant to be a brief survey of each subject aimed at the working professional with limited time—“Give me an overview, show me some working code, and make it snappy....” (Think of it as 12 months of JUG presentations collected in a single volume, minus the PowerPoint slides and cold pizza.)
JBoss fits the “I just want to make it work” gestalt to a T. Depending on the speed of your Internet connection, you can have it downloaded, unzipped, and running in less than five minutes. Turning services on and off is as simple as adding or removing files from a directory. The fact that it’s free means that you don’t get bogged down with per-seat or per-CPU licensing costs. JBoss is both a great learning tool and a production-quality deployment environment.
But any tool as powerful as JBoss also has pitfalls and complexities. The biggest disservice we could do is show you how to write applications that are tied to a specific application server, JBoss or otherwise. The “Write Once, Run Anywhere” promise of J2EE development may not happen automatically, but you can take steps to minimize the impact of moving from one application server to the next. In addition to your code being more portable, being a non-partisan J2EE developer means that you and your skills are more portable as you move from one job to the next.
We have tried to come up with an application that uses each layer of the J2EE collection in some sort of meaningful way. By design, this book is short on academic discussions and long on working code examples. Showing a coherent business application in action will hopefully give you a clearer idea of how the various layers interact, as opposed to a series of disjointed “Hello World” examples exercising each layer in isolation.
The JAW Motors application supports a fictitious automobile dealership. Each chapter progressively adds a new J2EE technology that solves a specific business problem. Viewing cars on a website involves JSP pages and some form of persistence (JDBC or Hibernate). Performing a credit check sends a JMS message and an email response using JavaMail. Purchasing a car requires the transactional support of Stateless Session Beans. Sharing data from the JAW Motors inventory with other dealerships involves setting up Web Services.
In addition to showing how JBoss works, we hope that these examples answer the how and why of each technology: how is it used, and why it should (or shouldn’t) be used. Just because a hammer can sink a screw in drywall doesn’t necessarily mean that it is the best tool for the job. The measure of a successful J2EE application isn’t how many of the technologies it uses; it is how effectively each technology is used.
Source code for the JAW Motors application is available for download from http://www.jbossatwork.com. We encourage you to download the files and build them as you follow along in the book. We want you to literally see JBoss at work, not just read about it.
Before we get too far, let’s make sure that you have all necessary tools to build and deploy the application to JBoss.
Making JBoss work involves more than just downloading and running JBoss. A cook certainly needs to know how to run the oven, but a lot of preliminary work must happen before the dish is ready for baking.
Professional chefs call this set up process “mis en place.” They sharpen knives and place cutting boards within arms’ reach. They prepare ahead of time ingredients they can safely cut up and measure before the dinner rush. Everything that can be done in terms of efficiency is handled up front so the culinary artist isn’t distracted by mundane details.
Similarly, making JBoss work effectively requires you to do a bunch of work up front. Code must be compiled and packaged up in a specific way. You must wade through endless deployment descriptors. If one tiny piece of information doesn’t match up with its companion in another file, the application will not deploy properly, and all of your hard work will be for nothing.
The mis en place of JBoss development involves other tools that make it easy to handle the mundane details of building and deploying your application. As in JBoss, you can download and use all of these tools for free:
Let’s talk briefly about how to install and configure them.
It probably goes without saying that the first thing you’ll need is a working installation of Java. JBoss 4.0.2 is compatible with J2SE 1.4 or higher. We use J2SE 1.4.2 in this book, although nothing should prevent you from running the examples in Java 5.
Download the full JDK (Java 2 Development Kit) from Sun’s web site (http://java.sun.com). Follow Sun’s instructions for installing the JDK on your operating system. Next, create an environment variable called JAVA_HOME that points to the Java installation directory. Finally, add $JAVA_HOME/bin to the system path so you can run Java from the command line.
To verify your Java installation, type
java -version at a command prompt. You
should see Example 1-1.
We use Ant 1.6.5 to compile, package, and deploy the examples in this book. You can download it from http://ant.apache.org.
To install Ant, simply unzip the downloaded file to the directory of your choice. Next, create an environment variable called ANT_HOME that points to the Ant installation directory. Finally, add $ANT_HOME/bin to the system path so you can run Ant from the command line.
To verify your Ant installation, type
ant -version at a command prompt. You should
see Example 1-2.
We use XDoclet 1.2.3 to generate J2EE deployment descriptors, web.xml, and various other J2EE configuration files for the JAW Motors application. XDoclet is a combination of custom Ant tasks and special attributes that you include in your source code. You can download it from http://xdoclet.sourceforge.net.
To install XDoclet, unzip the downloaded file into the directory of your choice. Next, create an environment variable called XDOCLET_HOME that points to the XDoclet installation directory.
To verify your XDoclet installation, change to the
$XDOCLET_HOME/samples directory and type
ant at a command prompt. You should see
rosencrantz:/Library/xdoclet-1.2.3/samples sdavis$ ant [many lines deleted for clarity] compile: [echo] +---------------------------------------------------+ [echo] | | [echo] | C O M P I L I N G S O U R C E S | [echo] | | [echo] +---------------------------------------------------+ [javac] Compiling 109 source files to /Library/xdoclet-1.2.3/samples/target/classes jar: [echo] You can find the generated sources in the /samples/target/gen-src [echo] directory and the compiled classes in the /samples/target/classes [echo] directory. Enjoy! BUILD SUCCESSFUL Total time: 1 minute 23 seconds rosencrantz:/Library/xdoclet-1.2.3/samples sdavis$
Now that we have all prerequisites in place, we can get to the reason why you are here: installing and running JBoss.
Download the JBoss Application Server Version 4.0.2 from http://www.jboss.org. Since it is written in Java, the same installation files will work on Windows, Linux, Unix, or Mac OS X. Any platform that has a JVM can run JBoss.
To install JBoss, simply unzip the downloaded file to the directory of your choice. Next, create an environment variable called JBOSS_HOME that points to the JBoss installation directory. Finally, add $JBOSS_HOME/bin to the system path so you can run JBoss from the command line.
To verify your JBoss installation, type
run at a command prompt (run.bat for Windows
run.sh for Linux/Unix/Mac
users). You should see something like this in your terminal
rosencrantz:/Library/jboss/bin sdavis$ ./run.sh =========================================== ============================== JBoss Bootstrap Environment JBOSS_HOME: /Library/jboss JAVA: /System/Library/Frameworks/JavaVM.framework/home/bin/java JAVA_OPTS: -server -Xms128m -Xmx128m -Dprogram.name=run.sh CLASSPATH: /Library/jboss/bin/run.jar:/System/Library/Frameworks/ JavaVM.framework/home/lib/tools.jar =========================================== ============================== 22:14:03,159 INFO [Server] Starting JBoss (MX MicroKernel)... 22:14:03,177 INFO [Server] Release ID: JBoss [Zion] 4.0.2 (build: CVSTag=JBoss_4_0_2 date=200505022023) 22:14:03,181 INFO [Server] Home Dir: /Library/jboss-4.0.2 [many lines deleted for clarity...] 22:14:55,890 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http-0.0.0.0-8080 22:14:56,396 INFO [ChannelSocket] JK: ajp13 listening on /0.0.0.0:8009 22:14:56,519 INFO [JkMain] Jk running ID=0 time=0/240 config=null 22:14:56,530 INFO [Server] JBoss (MX MicroKernel) [4.0.2 (build: CVSTag=JBoss_4_0_2 date=200505022023)] Started in 53s:238ms
If you don’t see any exceptions scroll by, JBoss is up and running
when you see the final line:
Started in xx
ms. To stop JBoss, press
Now that we’re sure that everything runs, let’s explore JBoss a bit more closely.
JBoss has directory structure that resembles most open source projects (as shown in Figure 1-1). We’re going to briefly point out what each directory holds, and then quickly move along. You’ll rarely need to make changes to them. JBoss is configured and ready to run out of the box. You’ll spend most of your time messing around with the server/ directory. This is where you deploy your application.
Figure 1-1 shows a brief overview of each directory:
Start up and shut down scripts.
JAR files used by external client applications that remotely access JNDI resources.
Strangely, the JBoss documentation is not found here. (It can be downloaded from http://www.jboss.com/products/jbossas/docs.) Instead, you’ll find various subdirectories:
XML DTDs describing the structure of J2EE standard and JBoss-specific deployment descriptors. In J2EE 1.4, DTDs have been deprecated in favor of Schemas. The DTDs are preserved here to support previous versions of the J2EE. JBoss still uses DTDs for JBoss-specific descriptors.
Subdirectories with sample JBoss descriptors. The
most notable among them is the
jca subdirectory that holds
sample DataSource configuration files (
*-ds.xml) for most of the major
relational databases. We’ll discuss this directory in more
detail in the JDBC chapter.
Licenses for all the different services.
XML Schemas (XSDs) describing the structure of J2EE 1.4 standard deployment descriptors.
Unit and functional tests for JBoss.
JAR files that make up JBoss.
Sub-directories for the various server configurations. This is where you deploy your applications.
Earlier in the chapter we said that JBoss was a family of
interrelated services. This family of services is called a Server
Configuration. Three named server configurations are in the
all. The only difference among the three are
the specific services that run at startup.
Includes only JNDI and logging services. As the name implies, it does not include any of the other standard J2EE services (EJBs, JMS, or a web container).
This is the “kitchen sink” server configuration. It includes everything in the default configuration plus services like clustering.
You can easily create your own Server Configuration by simply copying one of these directories, giving it a unique name, and adding or removing services as you wish. We’ll stick with the default ones for this book, but feel free to experiment on your own.
When we started JBoss previously, it ran using the
default configuration. Try starting JBoss
with the minimal configuration. At a command prompt, type
run -c minimal. JBoss should start up in a
fraction of the time it took last time. You also should see far fewer
lines in the console output than you did last time.
ctrl+C at a command
prompt to stop JBoss, and then
default to run the default server configuration again.
Notice all of the additional services that start up in the default
JBoss is really just a thin JMX (Java Management Extenstions) microkernel. JMX is a framework that allows you to interact with live, running code. You can start and stop services, gather metrics, and even change parameters on the fly. Services that implement the JMX interface are called “managed beans,” or MBeans.
Each of the J2EE services that run inside JBoss is an MBean. Log4j, Tomcat, and Hibernate are all MBeans. We’ll talk about how to selectively turn them on and off in the next section.
You don’t need to know anything about JMX to deploy an application to JBoss. You really don’t need to know it to configure JBoss, either—you’ll just see the terminology come up from time to time. JBoss is a great example of the power of JMX. (For more information on JMX, see Java Management Extensions by J. Steven Perry.)
A server configuration has three core subdirectories: conf/, deploy/, and lib/. Like the main JBoss directories, you’ll make changes to them only on rare occasions. Generally, you’ll simply drop your EAR or WAR file in the deploy/ directory and let JBoss handle the rest.
Includes configuration files for core services such as Log4J and JAAS
Deployment directory for both dynamic JBoss services (MBeans) and your custom applications (EARs and WARs)
JAR files to support the dynamic JBoss services (MBeans).
Look around the default/conf/ directory. The main Server Configuration file is jboss-service.xml. The only reason why you might edit this file is to change a port that a specific service runs on. Edit these values with care—the ports assigned to these services are well known. Changing them could cause downstream services to fail.
Change to the default/lib/ directory. These JAR files make up the J2EE services. You might drop an occasional database driver in here, but all the JARs that your application uses should be included in the WAR or EAR lib/ directory.
Now change to the default/deploy/ directory. This is where we’ll deploy the JAW application in just a bit. For now, let’s play around with the JBoss MBeans.
Make sure that you have JBoss open in one console window and the default/deploy/ directory open in another. While JBoss runs, it constantly polls this directory looking for changes to the configuration. Let’s dynamically undeploy an MBean to see this process in action.
The easiest way to see the process is to create a $JBOSS_HOME/server/default/undeploy/ directory. (It can be named anything you like, but “undeploy” is a common choice.) Move the hsqldb-ds.xml file to the undeploy/ directory and watch the JBoss console. You should see the Hypersonic database service shut down and all of the related services reconfigure themselves. Now move the file back from the undeploy/ directory to the deploy/ directory. Once again, JBoss recognizes the change in configuration and adjusts itself accordingly.
Adding and removing services while JBoss is running is called "hot deployment.” As you’ll see in the next section, you can hot deploy EARs and WARs as well.
Now that we’ve played around with JBoss a bit, let’s deploy our first application.
J2EE applications are generally bundled up as Enterprise Archives (EARs) or Web Archives (WARs). JBoss services can be bundled up as Service Archives (SARs). While each application technically is nothing more than a simple Java Archive (JAR), they have special internal directory structures and configuration files that must be present for the sake of the application server. (We will discuss EARs and WARs in greater detail later in the book.)
Knowing when to use these different file types and where to place them can be confusing. Here are some basic principles:
$JBOSS_HOME/lib is for the application server’s dependent libraries. These file types should always be packaged as JARs. You should never put your own JARs in this directory.
$JBOSS_HOME/server/[server configuration]/lib is for the Server Configuration’s dependent libraries. These, too, should always be JARs. You may add an occasional database driver JAR to this directory.
$JBOSS_HOME/server/[server configuration]/deploy is for SARs, WARs, and EARs. Plain old JARs will be ignored if placed here directly, although all three types of files may themselves contain JARs.
If you haven’t done so already, go to http://www.jbossatwork.com and download the code examples. Once you’ve unzipped the downloaded file, copy jaw.war from the ch01/ 01a-test directory to $JBOSS_HOME/server/default/deploy. In the JBoss console window, you should see the deployed test application.
Note that our WAR is treated no differently than an MBean. If you move jaw.war to the undeploy/ directory, JBoss will dynamically unload it, as it did with Hypersonic earlier.
Now that you’ve had a chance to see JBoss at work, let’s begin writing our web application. The next chapter walks you through the basics of building and deploying a WAR.