Configuring the JBoss application server
Who's the Boss?
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].
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:
-
bin
: This directory contains all the scripts required to start and stop the server. This is also where the JMX command-line tooltwiddle
resides, which you can use to manage the server. -
client
: Contains libraries that you might need for access from standalone clients. Standalone clients are, for example, GUI clients based on Swing or AWT, web service clients, or JMS clients. -
doc
: Mainly contains DTD files and XML schema files for the JBoss configuration files, which are XML-based. Sample configurations are located belowdocs/examples/
. -
lib
: Contains libraries for starting the JBoss AS. -
server
: Jboss comes with various configurations. Theserver
directory contains a number of subdirectories that each contain a specific configuration. When you launch the server, you can specify which configuration to use. Of course, you can modify the individual configurations or add new ones. Figure 2 shows theall
configuration directory. Compared with the default configuration, the JBoss Cluster Services are enabled here.
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.
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).
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:
-
conf
: Contains all the configuration files for the JBoss core service, the individual services, and the logging subsystem, log4j [4]. -
deploy
: I looked at this folder in the previous section. JBoss automatically identifies and dynamically deploys any applications copied to this directory. To remove an application, you simply need to delete it from thedeploy
directory, or, preferably, move it to anundeploy
directory. -
deployers
: Contains services for identifying various application and archive types in thedeploy
directory. -
lib
: Contains libraries used by all Java EE services in a common server configuration. Special libraries only used by one application are best provided by the application itself – for example, as part of a web archive.
Besides these standard directories, JBoss creates other folders at run time. The following list describes the most interesting of them:
-
log
: Contains the filesboot.log
,server.log
, and possiblyaudit.log
(depending on the configuration). Theboot.log
file contains all the log messages generated by the server's boot process up to the point where control passes to log4j. This service writes its messages to theserver.log
file. The Jboss security subsystem uses theaudit.log
file for safety-related messages. -
work
: This is where the JBoss web server keeps compiled Java class files and servlets. For the web application mentioned before, the following two files exist:
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).
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].