Nuts and Bolts JBoss Server Lead image: HONGQI ZHANG, 123RF.com
HONGQI ZHANG, 123RF.com
 

Configuring the JBoss application server

Who's the Boss?

Web-based, enterprise-capable applications often rely on the vendor-independent Java Platform, Enterprise Edition. We provide an introduction to Java EE based on the JBoss application server. By Thorsten Scherf

Java EE provides a development platform based on various software components and services that has become pretty much the standard for developing enterprise applications. Clearly defined APIs allow components from a variety of vendors to collaborate without any trouble. Every Java EE--based application naturally needs the appropriate environment to run in, and the environment must provide the required components and services, such as transaction management, name and directory services, persistency and deployment services, and a security framework (Figure 1). A complete list is available in the Java EE specifications [1].

An application server comprises various components that can access an Enterprise Information System.
Figure 1: An application server comprises various components that can access an Enterprise Information System.

On the commercial scene, two widely used heavyweights, IBM WebSphere and BEA WebLogic, support this specification. JBoss provides a Java application server as an open source product under the GNU Lesser General Public License (LGPL). It provides all the necessary software components, services, and containers defined by the specification and adds its own server-specific configuration options. For example, JBoss has a container for Enterprise JavaBeans (EJB) [2] and a web server based on Tomcat that supports servlets and JavaServer Pages (JSP).

History and Architecture

JBoss was developed in the 1990s by Marc Fleury as a pure EJB container. As its popularity increased and the server became more widespread, the JBoss community expanded and extended the product until, finally, application server version 3 (AS3) became a full-fledged Java EE server. In 2004, Fleury founded JBoss, a company that offers professional consulting and training services for JBoss. In 2006, the company was acquired by Linux distribution Red Hat, where it is now a part of the JBoss Enterprise Middleware Suite (JEMS). However, a community version of JBoss still exists, and anyone can download it from the Internet [3].

Early versions of JBoss were based on a Java Management Extension (JMX) kernel. All of the application server's services were loaded as Managed Beans (MBeans) into the JMX kernel to provide their functionality. The AS4 JBoss version saw migration to a microcontainer architecture, which now uses lightweight Plain Old Java Objects (POJOs) instead of MBeans. JBoss still supports MBeans, however, because the JMX kernel now relies on the microcontainer as a POJO itself. The project plans to implement all of the MBeans as pure POJOs in the future, thus removing the need to deploy the JMX kernel.

Installation

The JBoss application server is available as a ZIP file. Before you launch into the installation, make sure your system has either the current Java Development Kit (JDK) or a Java Runtime Environment (JRE).

Earlier versions of the JBoss AS required a JDK, because it provided a compiler for Java code. The compiler is needed to compile JSP files. Current versions – that is, AS5 or AS6 – can make do with a JRE, because the JBoss distribution includes an Eclipse JDT library, which can also compile Java code. If the system on which you are installing JBoss is a development machine, you will probably prefer to use the JDK. After installing the Java environment, make sure the JAVA_HOME variable points to the Java root directory (Listing 1).

Listing 1: Java Environment

01 # export JAVA_HOME=/usr/lib/jvm/jre-1.6.0-openjdk
02 # echo $JAVA_HOME
03 /usr/lib/jvm/jre-1.6.0-openjdk
04 # java -version
05 java version "1.6.0_18"
06 OpenJDK Runtime Environment (IcedTea6 1.8.3) (fedora-46.1.8.3.fc13-i386)
07 OpenJDK Server VM (build 14.0-b16, mixed mode)

After you complete these preparations, you can unpack the JBoss AS ZIP archive in a directory of your choice (e.g., /opt) and modify the JBOSS_HOME variable so it points to the installation directory. A basic understanding of the server directory structure is important for managing the server. After unpacking the archive, you will find various folders in the root directory (Figure 2), including:

Each JBoss configuration directory contains a number of subdirectories that let you modify the server behavior.
Figure 2: Each JBoss configuration directory contains a number of subdirectories that let you modify the server behavior.

You can select a specific server configuration to define which Java EE services and components the JBoss AS will start. If none of the existing configurations matches your requirements, you can easily copy one of the existing folders, rename the folder, and modify the copy to match your needs. I will describe this process later in the article.

To launch the JBoss server with all of its services, you can type the following:

# /opt/jboss-5.1.0.GA/bin/run.sh -c all

Then, you will see the startup messages for the individual services on the console. A status line that appears at the end shows how long the startup procedure took (Listing 2).

Listing 2: Startup Status

01 19:58:19,965 INFO  [ServerImpl] JBoss  (Microcontainer) [5.1.0.GA (build:SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 54s:991ms

Alternatively, you can launch the server in the background and write status messages for individual services to a logfile, so you don't clutter up the console with the server:

/opt/jboss-5.1.0.GA/bin/run.sh -c all > console.log &

At this point, you should also be able to access the server's web container (Figure 3). The startup page provides access to various online resources and internal JBoss applications that you can use to manage the server.

After starting the server, the startup page for the web container provides access to various applications and online resources.
Figure 3: After starting the server, the startup page for the web container provides access to various applications and online resources.

Getting Started

Next, I'll move on to deploying a Java-based web application using the JBoss web service. The service is based on the popular Tomcat for dynamic content, but it can also use the Apache Portable Runtime (APR) if you need a fast solution for serving up static content. JBoss natively supports hot deployment with the integrated web server. To allow this, copy the required web application into a specific directory in your current server configuration, and JBoss will deploy the application.

But, before you begin, you need to create and prepare the application. Because the development of complex applications is beyond the scope of this article, I'll just use the ubiquitous Hello World application as a substitute – in this case, as a JavaServer Page. JBoss builds the application dynamically, creates a servlet, and uses a web interface to serve it up to a client.

You can choose from several methods for deploying the application, such as, in the form of a web archive (WAR). For the archive, you first need to create a matching directory structure with the JSP file in the root directory. Here, you also need a WEB-INF directory with a deployment descriptor with a name of web.xml. This deployment descriptor is part of the JEE specification that allows servlets from other servers to run on JBoss.

JBoss reads server-specific configuration instructions from the WEB-INF/jboss-web.xml file; these instructions include the configuration for a security domain for your application. Thus, you can authenticate and authorize users, among other things, before they access the application. The JSP file is shown in Listing 3; the following code shows the deployment descriptor:

Listing 3: JSP Web Application in hello.jsp

01 <html><head><title>JSP Test</title>
02   <%!
03     String message = "Hello, World.";
04     String s04 = "Hello, Linux Magazine!";
05   %>
06 </head>
07 <body bgcolor="white">
08   <h2><%= message%></h2>
09   <font color="blue"><h1><%= s04%></h1></font color>
10   <%= new java.util.Date() %>
11 </body></html>
<web-app>
  <display-name>Hello World</display-name>
</web-app>

Thanks to the jar tool, you can now assemble a WAR file (Listing 4), which you then need to copy to the hot deployment directory of the active JBoss configuration directory:

Listing 4: Creating a WAR Package with jar

# jar -cvf helloworld.war *.jsp WEB-INF/
added manifest
adding: hello.jsp(in = 159) (out= 131)(deflated 17%)
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/web.xml(in = 63) (out= 48)(deflated 23%)
# cp helloworld.war ../../jboss-5.1.0.GA/server/all/deploy/
20:15:48,905 INFO  [TomcatDeployment] deploy,ctxPath=/helloworld

JBoss immediately notices the new web application and deploys it without delay. A quick visit to http://localhost:8080/helloworld/hello.jsp in the web browser confirms that everything is working (Figure 4).

You can admire the output from the web application in your browser.
Figure 4: You can admire the output from the web application in your browser.

Instead of copying the WAR file to the deployment directory, you can also use the twiddle admin tool that I referred to previously. The deploy operation in the JBoss jboss.system:service=MainDeployer MBean lets you deploy the web application even if you don't have write permissions for the deployment directory. One disadvantage of this method is that the application will not automatically launch when the server is rebooted.

# ./twiddle.sh invoke "jboss.system:service=MainDeployer" deploy/opt/examples/HelloWorld/helloworld.war

Instead of compressed archive files, JBoss can also handle complete directory structures. Sometimes it's easier to use a directory than an archive because you can add or remove individual files from a directory without needing to create a new archive every time you make a change. You don't need to reboot the server after a change; JBoss will detect the change automatically by the updated timestamps of the files. Before you deploy whole directories, make sure they have the correct suffixes; otherwise, the server will not know which deployer to use (Listing 5).

Listing 5: Directory-Based Deployment

# mv /opt/examples/helloworld/ /opt/examples/helloworld.war/
# rm -f /opt/jboss-5.1.0.GA/server/all/deploy/helloworld.war
10:25:22,371 INFO  [TomcatDeployment] undeploy, ctxPath=/helloworld
# cp -r /opt/examples/helloworld.war/ /opt/jboss-5.1.0.GA/server/all/deploy/
10:25:22,412 INFO  [TomcatDeployment] deploy, ctxPath=/helloworld

Server Configuration

Now that I've shown how to deploy a simple web application on the JBoss AS, I'll take a closer look at the server configuration. As mentioned previously, the JBoss AS has several configuration directories. When I booted the server in the example, I selected the all configuration. The configuration folder /opt/jboss-5.1.0.GA/server/all contains several subdirectories. Again, you'll need a basic understanding of the individual directories, as follows:

Besides these standard directories, JBoss creates other folders at run time. The following list describes the most interesting of them:

work/jboss.web/localhost/helloworld/org/apache/jsp/hello_jsp.classwork/jboss.web/localhost/helloworld/org/apache/jsp/hello_jsp.java

If you need to modify the server, the configuration files below conf/ are the most interesting. I will look at JBoss server logging here as an example. As I said previously, JBoss relies on the log4j logging framework. The conf/jboss-log4j.xml configuration file contains the default configurations of two appenders. These entities decide where to send the messages from the JBoss services or deployed applications. The first appender writes all of its messages from all log levels (TRACE, DEBUG, INFO, WARN, ERROR, and FATAL) to the log/server.log file and creates a new file with an appropriate date suffix every day (Listing 6).

Listing 6: The JBoss Default File Appender

01 <appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
02       <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
03         <param name="File" value="${jboss.server.log.dir}/server.log"/>
04         <param name="Append" value="true"/>
05         <param name="DatePattern" value="'.'yyyy-MM-dd"/>
06       <layout class="org.apache.log4j.PatternLayout">
07          <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
08       </layout>
09 </appender>

If you want the server to rotate the logfile, instead, once it reaches a specific size limit, you need to modify the appender parameters accordingly (Listing 7).

Listing 7: Appender with Modified Parameters

01 <appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
02       <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
03         <param name="File" value="${jboss.server.log.dir}/server.log"/>
04         <param name="Append" value="false"/>
05         <param name="MaxFileSize" value="10MB"/>
06         <param name="MaxBackupIndex" value="20"/>
07       <layout class="org.apache.log4j.PatternLayout">
08          <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
09       </layout>
10 </appender>

The second appender CONSOLE sends the output to the console. This process only starts at the INFO log level, as specified by the <param name="Threshold" value="INFO"/> parameter in the appender configuration. This step helps prevent filling up the console log with too many log messages. Of course, you could also create files for the individual files or log levels.

The Limit categories category gives you settings that relate to an appender with a specific name (you must specify this as a reference), and that define the logging for a specific class or application derived from this class, as of a specific log level. The configuration file provides a good selection of examples:

Security

In all of the examples so far, I've launched the JBoss server with the all configuration setting, which makes all the services and server components available. This approach might be okay for test and developer systems, but definitely not for a production system. The adage here is: Less is more. Services you don't need are an unnecessary security risk and should be disabled or, better still, removed.

The all configuration tells JBoss to start 25 different services, whereas the default configuration only starts 15.

The main difference between the two configurations is that all provides a full set of cluster services, but default does not. If you don't need a cluster, you will be fine with the standard configuration. However, it is still a good idea to slim down this configuration if you don't need all of the services.

To do this, first create a new configuration directory based on the default configuration:

# cp -r /opt/jboss-5.1.0.GA/server/default /opt/jboss-5.1.0.GA/server/custom

You can now disable all the services you don't need in the custom directory. For example, you will not want to display the JBoss startup page on a production server. You can remove it by deleting or renaming custom/deploy/ROOT.war.

If you don't need the mail service, you can delete the custom/deploy/mail-service.xml and custom/lib/mail*.jar files. A quick check of the deploy and lib directories will help you identify other unnecessary services.

By default, JBoss offers a number of management tools, such as the JMX Console, which you can access via http://localhost:8080/jmx-console/. Anybody can read and modify the server's MBeans at the console. In other words, the changes to the logging subsystem could have been implemented at the JMX console. This web application thus provides a powerful, but also dangerous, option for configuring the complete JBoss server. On a production system, you will probably want to remove the console (deploy/jmx-console.war) or secure access to it by user authentication.

Authentication and Authorization

The JBoss security system is based on the Java Authentication and Authorization Service (JAAS). Security domains are used to define which logging modules are used for a specific application. Prebuilt login modules exist for access to databases, LDAP servers, or plain files.

If a web application is configured for a specific security domain, the user needs to authenticate for access; then, if authentication and authorization are successful, the user will be assigned a specific role. On the basis of the role, the administrator can define the parts of the web application that the user is allowed to access. In Listing 8 you can see a security domain that has been defined for the JMX Console.

Listing 8: Security Domain for JMX Console

01 <application-policy name="jmx-console">
02   <authentication>
03     <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
04       flag="required">
05       <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
06       <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
07     </login-module>
08   </authentication>
09 </application-policy>

The listing shows a simple login module that uses file-based user authentication and authorization. More complex examples for access to a database, or an LDAP server, can be found in the conf/login-config.xml file. For an application to be aware of the security domain it uses, you need to define the domain in Jboss's own deployment descriptor, jboss-web.xml.

In this file, you can enter the domain name that the application uses for logging in to the server via the Java Naming and Directory Interface (JNDI). In the case of the JMX Console, you need to modify the deploy/jmx-console.war/WEB-INF/jboss-web.xml file (Listing 9).

Listing 9: jboss-web.xml

01 <jboss-web>
02     <security-domain>java:/jaas/jmx-console</security-domain>
03 </jboss-web>

Now you can see which security domain and which login modules are used for JMX Console; however, you still need a ruleset to define who can access which resources. The regular deployment descriptor, deploy/jmx-console.war/WEB-INF/web.xml, is used to provide this information (Listing 10). Only users with a specific role are allowed to access the console.

Listing 10: Ruleset for the JMX Console

01 <security-constraint>
02    <web-resource-collection>
03      <web-resource-name>HtmlAdaptor</web-resource-name>
04      <description>An example security config that only allows users with the
05          role JBossAdmin to access the HTML JMX console web application
06      </description>
07      <url-pattern>/*</url-pattern>
08      <http-method>GET</http-method>
09      <http-method>POST</http-method>
10    </web-resource-collection>
11    <auth-constraint>
12      <role-name>JBossAdmin</role-name>
13    </auth-constraint>
14 </security-constraint>

Next, you just need the user account data. As specified by the login module for the application, these data are taken from two files: props/jmx-console-users.properties for the usernames and passwords and props/jmx-console-roles.properties for role and account mappings. In this example, a user must be assigned to the JBossAdmin role for access to the console. If all of this works, you should see a window that prompts you for authentication when you access http://localhost:8080/jmx-console/ (Figure 5).

A user login is required to access the console.
Figure 5: A user login is required to access the console.

Other web applications can be configured for user authentication and authorization in a similar way. The important thing is to register the security domain you will be using with JNDI first.

Secure Communications

Finally, I'll look at the configuration for secure access to a web application. This process is extremely important if the application transfers confidential data and autonomously authenticates users – including transfer of passwords. You need to add a web connector to the JBoss server for a secure HTTPS connection, but before you configure it, you'll need to create a certificate store. The store contains an X.509 certificate, which can be self-signed or provided by an external Certificate Authority (CA). You can use the Java keytool application to create a certificate store (Listing 11).

Listing 11: Creating a Certificate Store

01 # keytool -genkey -alias example -keystore tuxgeek.keystore -keyalg RSA
02 keytool -genkey -alias example -keystore tuxgeek.keystore -keyalg RSA
03 Enter keystore password:
04 Re-enter new password:
05 What is your first and last name?
06   [Unknown]:  tiffy.tuxgeek.de
07 What is the name of your organizational unit?
08   [Unknown]:  World
09 What is the name of your organization?
10   [Unknown]:  Universe
11 What is the name of your City or Locality?
12   [Unknown]:  Gelsenkirchen
13 What is the name of your State or Province?
14   [Unknown]:  NRW
15 What is the two-letter country code for this unit?
16   [Unknown]:  DE
17 Is CN=tiffy.tuxgeek.de, OU=World, O=Universe, L=Gelsenkirchen, ST=NRW, C=DE correct?
18   [no]:  yes
19
20 Enter key password for <example>
21     (RETURN if same as keystore password):
22 Re-enter new password:
23
24 # keytool -list -keystore tuxgeek.keystore
25 Enter keystore password:
26
27 Keystore type: JKS
28 Keystore provider: SUN
29
30 Your keystore contains 1 entry
31
32 example, Mar 25, 2011, PrivateKeyEntry,
33 Certificate fingerprint (MD5): AC:D5:CB:5C:13:9D:EF:F2:85:6B:AB:89:49:F8:48:3A

Finally, to enable the web connector's HTTPS port, you need to add the certificate store, including the corresponding password, to the JBoss web service configuration file, deploy/jbossweb.sar/server.xml (Listing 12).

Listing 12: HTTPS Port for the Web Connector

01 <Connector protocol="HTTP/1.1" SSLEnabled="true"
02   port="8443" address="${jboss.bind.address}"
03   scheme="https" secure="true" clientAuth="false"
04          keystoreFile="${jboss.server.home.dir}/conf/tuxgeek.keystore"
05   keystorePass="redhat" sslProtocol = "TLS"
06 />

From now on, all web applications can use the secure HTTPS port 8443 for encrypted data transmission.

Conclusions

Besides the approaches detailed in this article, you have many other options for configuring the JBoss server. One very important topic that I didn't cover here is the ability to modularize complex applications using Enterprise JavaBeans and thus abstract the business logic from the application. The use of J2EE Connector Architecture to link to data stores and the configuration of high-availability server systems are also interesting topics that I will look into in the future. For more information on this and other topics, check out the comprehensive documentation page provided by the JBoss project [5].