Copyright © 2007 Red Hat, Inc.
Copyright © 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).
Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
All other trademarks referenced herein are the property of their respective owners.
The GPG fingerprint of the security@redhat.com key is:
CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
1801 Varsity Drive
Raleigh, NC 27606-2072
USA
Phone: +1 919 754 3700
Phone: 888 733 4281
Fax: +1 919 754 3701
PO Box 13588
Research Triangle Park, NC 27709
USA
Nov, 2007
Abstract
This book is a guide to the configuration of the Jboss Application Server.
The primary focus of this book is the presentation of the standard JBoss 4.2 architecture components from both the perspective of their configuration and architecture. As a user of a standard JBoss distribution you will be given an understanding of how to configure the standard components. Note that this book is not an introduction to J2EE or how to use J2EE in applications. It focuses on the internal details of the JBoss server architecture and how our implementation of a given J2EE container can be configured and extended.
As a JBoss developer, you will be given a good understanding of the architecture and integration of the standard components to enable you to extend or replace the standard components for your infrastructure needs. We also show you how to obtain the JBoss source code, along with how to build and debug the JBoss server.
JBoss, a division of Red Hat, is the global leader in open source middleware software, combining enterprise-class JEMS open source software with the industry’s leading services and tools to provide simply a better way to transform your business to Service-Oriented Architecture (SOA).
JBoss, pioneered the disruptive Professional Open Source model, which combines the best of the open source and proprietary software worlds to make open source a safe choice for the enterprise and give CIOs peace of mind. This includes the royalty-free software, transparent development and active community inherent in open source and the accountability and professional support services expected of a traditional software vendor. The company finds innovative open source projects and professionalizes the project from a hobby into a livelihood by hiring the lead developer(s), often the founders themselves. JBoss provides the resources, core development and support services to enable popular open source projects to scale into enterprise-class software.
Coverage: North America and Europe on a direct basis. JBoss provides coverage worldwide via our extensive authorized partner network.
Mission Statement: JBoss' mission is to revolutionize the way enterprise middleware software is built, distributed, and supported through the Professional Open Source model. We are committed to delivering innovative and high quality technology and services that make JBoss the safe choice for enterprises and software providers.
Customers: Enterprise customers deploying JBoss technologies in mission-critical applications with professional services support from JBoss include Aviva Canada, Continental Airlines, La Quinta, NLG, MCI, Nielsen Media Research and Travelocity. For a current list of customer success stories, please visit the Customers section of our website.
Partners: JBoss works with software and hardware vendors, systems integrators and OEMs to deliver implementation services, frontline support, and certification for products embedded with JBoss technologies. For more information on the JBoss Certified Partner Program, please visit the Partners section of our website.
Professional Open Source(tm) from JBoss Inc. offers you:
Standards-based and stable Java Middleware technology
No cost open source product licenses
Backed by a professional and expert support staff
Comprehensive services including Professional Support, Training, and Consulting
A very large and active community of developers
An extensive worldwide network of authorized and certified partners
Benefits of Professional Open Source from JBoss Inc.:
Lowest possible total cost of ownership
Reliable and safe technology
Support, accountability, and trust from a stable company
Expedited problem resolution compared to commercial software vendors
The basic idea behind open source is very simple: When programmers can read, redistribute, and modify the source code for a piece of software, the software evolves. People improve it, people adapt it, people fix bugs. And this can happen at a speed that, if one is used to the slow pace of conventional software development, seems astonishing. Open Source is an often-misunderstood term relating to free software. The Open Source Initiative (OSI) web site provides a number of resources that define the various aspects of Open Source including an Open Source Definition at: http://www.opensource.org/docs/definition.html. The following quote from the OSI home page summarizes the key aspects as they relate to JBoss nicely:
We in the open source community have learned that this rapid evolutionary process produces better software than the traditional closed model, in which only very few programmers can see the source and everybody else must blindly use an opaque block of bits. Open Source Initiative exists to make this case to the commercial world. Open source software is an idea whose time has finally come. For twenty years it has been building momentum in the technical cultures that built the Internet and the World Wide Web. Now it's breaking out into the commercial world, and that's changing all the rules. Are you ready? | ||
| --The Open Source Initiative | ||
JBoss is the leader in the second generation of open source, which we have termed Professional Open Source. The Professional Open Source methodology is based on the following:
We hire and pay experts in the open source community to write exceptional and innovative software full-time.
We only use open source licenses that are friendly to end-user IT shops, independent software vendors, and the community itself.
Directly and through our authorized partners, we deliver the best support services available; all of which are backed up by the real product experts.
Unlike first generation open source providers, we control the direction and source code for our projects. We can ensure that all bug fixes and patches are rolled into future versions of our products.
By combining enterprise-proven technology, business-friendly open source licenses, and world-class support services, we have made Professional Open Source the safe choice for end-user enterprises and independent software vendors alike.
Table of Contents
EJB3 (Enterprise JavaBean 3.0) provides the core component model for Java EE 5 applications. An EJB3 bean is a managed component that is automatically wired to take advantage of all services the J2EE server container provides, such as transaction, security, persistence, naming, dependency injection, etc. The managed component allows developers to focus on the business logic, and leave the cross-cutting concerns to the container as configurations. As an application developer, you need not create or destroy the components yourself. You only need to ask for an EJB3 bean from the Java EE container by its name, and then you can call its methods with all configured container services applied. You can get access to an EJB3 bean from either inside or outside of the J2EE container.
JBoss AS 4.2 supports EJB3 out of the box. For JBoss AS 4.0.x, you can add support for EJB3 by manually installing the JBoss EJB3 deployer, or installing the server from a JEMS GUI installer and select a EJB3 profile.
The details of the EJB3 component programming model is beyond the scope of this guide. Most EJB3 interfaces and annotations are part of the Java EE 5 standard and hence they are the same for all Java EE 5 compliant application servers. Interested readers should refer to the EJB3 specification or numerous EJB3 books to learn more about EJB3 programming.
In this chapter, we only cover EJB3 configuration issues that are specific to the JBoss AS. For instance, we discuss the JNDI naming conventions for EJB3 components inside the JBoss AS, the optional configurations for the Hibernate persistence engine for entity beans, as well as custom options in the JBoss EJB3 deployer.
Session beans are widely used to provide transactional services for local and remote clients. To write a session bean, you need an interface and an implementation class.
@Local
public interface MyBeanInt {
public String doSomething (String para1, int para2);
}
@Stateless
public class MyBean implements MyBeanInt {
public String doSomething (String para1, int para2) {
... implement the logic ...
}
}
When you invoke a session bean method, the method execution is automatically managed by the transaction manager and the security manager in the server. You can specify the transactional or security properties for each method using annotations on the method. A session bean instance can be reused by many clients. Depending on whether the server maintains the bean's internal state between two clients, the session bean can be stateless or stateful. Depending on whether the bean is available to remote clients (i.e., clients outside of the current JVM for the server), the session bean can be local or remote. All these are configurable via standard annotations on the beans.
After you define a session bean, how does the client get access to it? As we discussed, the client does not create or destroy EJB3 components, it merely asks the server for a reference of an existing instance managed by the server. That is done via JNDI. In JBoss AS, the default local JNDI name for a session bean is dependent on the deployment packaging of the bean class.
If the bean is deployed in a standalone JAR file in the jboss-as/production/deploy directory, the bean is accessible via local JNDI name MyBean/local, where MyBean is the implementation class name of the bean as we showed earlier. The "local" JNDI in JBoss AS means that the JNDI name is relative to java:comp/env/.
If the JAR file containing the bean is packaged in an EAR file, the local JNDI name for the bean is myapp/MyBean/local, where myapp is the root name of the EAR archive file (e.g., myapp.ear, see later for the EAR packaging of EJB3 beans).
Of course, you should change local to remote if the bean interface is annotated with @Remote and the bean is accessed from outside of the server it is deployed on. Below is the code snippet to get a reference of the MyBean bean in a web application (e.g., in a servlet or a JSF backing bean) packaged in myapp.ear, and then invoke a managed method.
try {
InitialContext ctx = new InitialContext();
MyBeanInt bean = (MyBeanInt) ctx.lookup("myapp/MyBean/local");
} catch (Exception e) {
e.printStackTrace ();
}
... ...
String result = bean.doSomething("have fun", 1);
... ...
What the client gets from the JNDI is essentially a "stub" or "proxy" of the bean instance. When the client invokes a method, the proxy figures out how to route the request to the server and marshal together the response.
If you do not like the default JNDI names, you can always specify your own JNDI binding for any bean via the @LocalBinding annotation on the bean implementation class. The JNDI binding is always "local" under the java:comp/env/ space. For instance, the following bean class definition results in the bean instances available under JNDI name java:comp/env/MyService/MyOwnName.
@Stateless
@LocalBinding (jndiBinding="MyService/MyOwnName")
public class MyBean implements MyBeanInt {
public String doSomething (String para1, int para2) {
... implement the logic ...
}
}
Java EE 5 allows you to inject EJB3 bean instances directly into the web application via annotations without explicit JNDI lookup. This behavior is not yet supported in JBoss AS 4.2. However, the JBoss Enterprise Platform provides an integration framework called JBoss Seam. JBoss Seam brings EJB3 / JSF integration to new heights far beyond what Java EE 5 provides. Please see more details in the JBoss Seam reference guide bundled with the platform.
EJB3 session beans allow you to implement data accessing business logic in transactional methods. To actually access the database, you will need EJB3 entity beans and the entity manager API. They are collectively called the Java Persistence API (JPA).
EJB3 Entity Beans are Plain Old Java Objects (POJOs) that map to relational database tables. For instance, the following entity bean class maps to a relational table named customer. The table has three columns: name, age, and signupdate. Each instance of the bean corresponds to a row of data in the table.
@Entity
public class Customer {
String name;
public String getName () {
return name;
}
public void setName (String name) {
this.name = name;
}
int age;
public int getAge () {
return age;
}
public void setAge (int age) {
this.age = age;
}
Date signupdate;
public Date getSignupdate () {
return signupdate;
}
public void setSignupdate (Date signupdate) {
this.signupdate = signupdate;
}
}
Besides simple data properties, the entity bean can also contain references to other entity beans with relational mapping annotations such as @OneToOne, @OneToMany, @ManyToMany etc. The relationships of those entity objects will be automatically set up in the database as foreign keys. For instance, the following example shows that each record in the Customer table has one corresponding record in the Account table, multiple corresponding records in the Order table, and each record in the Employee table has multiple corresponding records in the Customer table.
@Entity
public class Customer {
... ...
Account account;
@OneToOne
public Account getAccount () {
return account;
}
public void setAccount (Accout account) {
this.account = account;
}
Employee salesRep;
@ManyToOne
public Employee getSalesRep () {
return salesRep;
}
public void setSalesRep (Employee salesRep) {
this.salesRep = salesRep;
}
Vector <Order> orders;
@OneToMany
public Vector <Order> getOrders () {
return orders;
}
public void setOrders (Vector <Order> orders) {
this.orders = orders;
}
Using the EntityManager API, you can create, update, delete, and query entity objects. The EntityManager transparently updates the underlying database tables in the process. You can obtain an EntityManager object in your EJB3 session bean via the @PersistenceContext annotation.
@PersistenceContext
EntityManager em;
Customer customer = new Cutomer ();
// populate data in customer
// Save the newly created customer object to DB
em.persist (customer);
// Increase age by 1 and auto save to database
customer.setAge (customer.getAge() + 1);
// delete the customer and its related objects from the DB
em.remove (customer);
// Get all customer records with age > 30 from the DB
List <Customer> customers = em.query (
"select c from Customer where c.age > 30");
The detailed use of the EntityManager API is beyond the scope of this book. Interested readers should refer to the JPA documentation or Hibernate EntityManager documentation.
The EntityManager API is great, but how does the server know which database it is supposed to save / update / query the entity objects? How do we configure the underlying object-relational-mapping engine and cache for better performance and trouble shooting? The persistence.xml file gives you complete flexibility to configure the EntityManager.
The persistence.xml file is a standard configuration file in JPA. It has to be included in the META-INF directory inside the JAR file that contains the entity beans. The persistence.xml file must define a persistence-unit with a unique name in the current scoped classloader. The provider attribute specifies the underlying implementation of the JPA EntityManager. In JBoss AS, the default and only supported / recommended JPA provider is Hibernate. The jta-data-source points to the JNDI name of the database this persistence unit maps to. The java:/DefaultDS here points to the HSQL DB embedded in the JBoss AS. Please refer to Appendix B, Use Alternative Databases with JBoss AS on how to setup alternative databases for JBoss AS.
<persistence>
<persistence-unit name="myapp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
... ...
</properties>
</persistence-unit>
</persistence>
Since you might have multiple instances of persistence-unit defined in the same application, you typically need to explicitly tell the @PersistenceContext annotation which unit you want to inject. For instance, @PersistenceContext(name="myapp") injects the EntityManager from the persistence-unit named "myapp".
However, if you deploy your EAR application in its own scoped classloader and have only one persistence-unit defined in the whole application, you can omit the "name" on @PersistenceContext. See later in this chapter for EAR packaging and deployment.
The properties element in the persistence.xml can contain any configuration properties for the underlying persistence provider. Since JBoss AS uses Hibernate as the EJB3 persistence provider, you can pass in any Hibernate options here. Please refer to the Hibernate and Hibernate EntityManager documentation for more details. Here we will just give an example to set the SQL dialect of the persistence engine to HSQL, and to create tables from the entity beans when the application starts and drop those tables when the application stops.
<persistence>
<persistence-unit name="myapp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
To use an alternative database other than the built-in HSQL DB to back your entity beans, you need to first define the data source for the database and register it in the JNDI. This is done via the *-ds.xml files in the deploy directory. Please see Section 5.3, “Configuring JDBC DataSources” for more details. Examples of *-ds.xml files for various databases are available in jboss-as/docs/examples/jca directory in the server.
Then, in the persistence.xml, you need to change the jta-data-source attribute to point to the new data source in JNDI (e.g., java:/MysqlDS if you are using the default mysql-ds.xml to setup a MySQL external database).
In most cases, Hibernate tries to automatically detect the database it connects to and then automatically selects an appropriate SQL dialect for the database. However, we have found that this detection does not always work, especially for less used database servers. We recommend you to set the hibernate.dialect property explicitly in persistence.xml. Here are the Hibernate dialect for database servers officially supported on the JBoss platform.
Oracle 9i and 10g: org.hibernate.dialect.Oracle9Dialect
Microsoft SQL Server 2005: org.hibernate.dialect.SQLServerDialect
PostgresSQL 8.1: org.hibernate.dialect.PostgreSQLDialect
MySQL 5.0: org.hibernate.dialect.MySQL5Dialect
DB2 8.0: org.hibernate.dialect.DB2Dialect
Sybase ASE 12.5: org.hibernate.dialect.SybaseDialect
Hibernate has many configuration properties. For the properties that you do not specify in the persistence.xml file, JBoss AS will provide a reasonable set of default values. The default Hibernate property values are specified in the jboss-as/server/production/deploy/ejb3.deployer/MEAT-INF/persistence.properties file. Below is the persistence.properties file bundled in JBoss AS 4.2. Notice the options that are commented out. They give you an idea of available properties in your persistence.xml file.
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
#hibernate.connection.release_mode=after_statement
#hibernate.transaction.flush_before_completion=false
#hibernate.transaction.auto_close_session=false
#hibernate.query.factory_class=org.hibernate.hql.ast.ASTQueryTranslatorFactory
#hibernate.hbm2ddl.auto=create-drop
#hibernate.hbm2ddl.auto=create
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
# Clustered cache with TreeCache
#hibernate.cache.provider_class=org.jboss.ejb3.entity.TreeCacheProviderHook
#hibernate.treecache.mbean.object_name=jboss.cache:service=EJB3EntityTreeCache
#hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.jndi.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
hibernate.jndi.java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
hibernate.bytecode.use_reflection_optimizer=false
# I don't think this is honored, but EJB3Deployer uses it
hibernate.bytecode.provider=javassist
Messaging driven beans are specialized EJB3 beans that receive service requests via JMS messages instead of proxy method calls from the "stub". So, a crucial configuration parameter for the message driven bean is to specify which JMS message queue its listens to. When there is an incoming message in the queue, the server invokes the beans's onMessage() method, and passes in the message itself for processing. The bean class specifies the JMS queue it listens to in the @MessageDriven annotation. The queue is registered under the local JNDI java:comp/env/ name space.
@MessageDriven(activationConfig =
{
@ActivationConfigProperty(propertyName="destinationType",
propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",
propertyValue="queue/MyQueue")
})
public class MyJmsBean implements MessageListener {
public void onMessage (Message msg) {
// ... do something with the msg ...
}
// ... ...
}
When a message driven bean is deployed, its incoming message queue is automatically created if it does not exist already. To send a message to the bean, you can use the standard JMS API.
try {
InitialContext ctx = new InitialContext();
queue = (Queue) ctx.lookup("queue/MyQueue");
QueueConnectionFactory factory =
(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
cnn = factory.createQueueConnection();
sess = cnn.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
} catch (Exception e) {
e.printStackTrace ();
}
TextMessage msg = sess.createTextMessage(...);
sender = sess.createSender(queue);
sender.send(msg);
Please refer to the JMS specification or books to learn how to program in the JMS API.
EJB3 bean classes are packaged in regular JAR files. The standard configuration files, such as ejb-jar.xml for session beans, and persistence.xml for entity beans, are in the META-INF directory inside the JAR. You can deploy EJB3 beans as standalone services in JBoss AS or as part of an enterprise application (i.e., in an EAR archive). In this section, we discuss those two deployment options.
When you drop JAR files into the jboss-as/server/production/deploy/ directory, it will be automatically picked up and processed by the server. All the EJB3 beans defined in the JAR file will then be available to other applications deployed inside or outside of the server via JNDI names like MyBean/local, where MyBean is the implementation class name for the session bean. The deployment is done via the JBoss EJB3 deployer in jboss-as/server/production/ejb3.deployer/. The META-INF/persistence.properties file we discussed earlier to configure the default behavior of EJB3 entity manager is located in the EJB3 deployer.
The EJB3 deployer automatically scans JARs on the classpath to look for EJB3 annotations. When it finds classes with EJB3 annotations, it would deploy them as EJB3 services. However, scanning all JARs on the classpath could be very time-consuming if you have large applications with many JARs deployed. In the jboss-as/server/production/ejb3.deployer/META-INF/jboss-service.xml file, you can tell the EJB3 deployer to ignore JARs you know do not contain EJB3 beans. The non-EJB3 JAR files shipped with the JBoss AS are already listed in the jboss.ejb3:service=JarsIgnoredForScanning MBean service:
... ...
<mbean code="org.jboss.ejb3.JarsIgnoredForScanning"
name="jboss.ejb3:service=JarsIgnoredForScanning">
<attribute name="IgnoredJars">
snmp-adaptor.jar,
otherimages.jar,
applet.jar,
jcommon.jar,
console-mgr-classes.jar,
jfreechart.jar,
juddi-service.jar,
wsdl4j.jar,
... ...
servlets-webdav.jar
</attribute>
</mbean>
... ...
You can add any non-EJB3 JARs from your application to this list so that the server do not have to waste time scanning them. This could significantly improve the application startup time in some cases.
Most Java EE applications are deployed as EAR archives. An EAR archive is a JAR file that typically contains a WAR archive for the web pages, servlets, and other web-related components, one or several EJB3 JARs that provide services (e.g., data access and transaction) to the WAR components, and some other support library JARs required by the application. An EAR file also have deployment descriptors such as application.xml and jboss-app.xml. Below is the basic structure of a typical EAR application.
myapp.ear
|+ META-INF
|+ applications.xml and jboss-app.xml
|+ myapp.war
|+ web pages and JSP /JSF pages
|+ WEB-INF
|+ web.xml, jboss-web.xml, faces-config.xml etc.
|+ lib
|+ tag library JARs
|+ classes
|+ servlets and other classes used by web pages
|+ myapp.jar
|+ EJB3 bean classes
|+ META-INF
|+ ejb-jar.xml and persistence.xml
|+ lib
|+ Library JARs for the EAR
Notice that in JBoss AS, unlike in many other application servers, you do not need to declare EJB references in the web.xml file in order for the components in the WAR file to access EJB3 services. You can obtain the references directly via JNDI as we discussed earlier in the chapter.
A typical application.xml file is as follows. It declares the WAR and EJB3 JAR archives in the EAR, and defines the web content root for the application. Of course, you can have multiple EJB3 modules in the same EAR application. The application.xml file could also optionally define a shared classpath for JAR files used in this application. The JAR file location defaults to lib in JBoss AS -- but it might be different in other application servers.
<application>
<display-name>My Application</display-name>
<module>
<web>
<web-uri>myapp.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
<module>
<ejb>myapp.jar</ejb>
</module>
<library-directory>lib</library-directory>
</application>
The jboss-app.xml file provides JBoss-specific deployment configuration for the EAR application. For instance, it can specify the deployment order of modules in the EAR, deploy JBoss-specific application modules in the EAR, such as SARs (Service ARchive for MBeans) and HARs (Hibernate ARchive for Hibernate objects), provide security domain and JMX MBeans that can be used with this application, etc. You can lear more about the possible attributes in jboss-app.xml in its DTD: http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd.
A common use case for jboss-app.xml is to configure whether this EAR file should be deployed in its own scoped classloader to avoid naming conflicts with other applications. If your EAR application is deployed in its own scoped classloader and it only has one persistence-unit defined in its EJB3 JARs, you will be able to use @PersistenceContext EntotyManager em to inject EntityManager to session beans without worrying about passing the persistence unit name to the @PersistenceContext annotation. The following jboss-app.xml specifies a scoped classloader myapp:archive=myapp.ear for the EAR application.
<jboss-app>
<loader-repository>
myapp:archive=myapp.ear
</loader-repository>
</jboss-app>
The EAR deployment is configured by the jboss-as/server/production/deploy/ear-deploy.xml file. This file contains three attributes as follows.
<server>
<mbean code="org.jboss.deployment.EARDeployer"
name="jboss.j2ee:service=EARDeployer">
<!--
A flag indicating if ear deployments should
have their own scoped class loader to isolate
their classes from other deployments.
-->
<attribute name="Isolated">false</attribute>
<!--
A flag indicating if the ear components should
have in VM call optimization disabled.
-->
<attribute name="CallByValue">false</attribute>
<!--
A flag the enables the default behavior of
the ee5 library-directory. If true, the lib
contents of an ear are assumed to be the default
value for library-directory in the absence of
an explicit library-directory. If false, there
must be an explicit library-directory.
-->
<attribute name="EnablelibDirectoryByDefault">true</attribute>
</mbean>
</server>
If you set the Isolated parameter to true, all EAR deployment will have scoped classloaders by default. There will be no need to define the classloader in jboss-app.xml. The CallByValue attribute specifies whether we should treat all EJB calls as remote calls. Remote calls have a large additional performance penalty compared with local call-by-reference calls, because objects involved in remote calls have to be serialized and de-serialized. For most of our applications, the WAR and EJB3 JARs are deployed on the same server, hence this value should be default to false and the server uses local call-by-reference calls to invoke EJB methods in the same JVM. The EnablelibDirectoryByDefault attribute specifies whether the lib directory in the EAR archive should be the default location for shared library JARs.
Deploying applications on JBoss AS is very easy. You just need to copy the application into the jboss-as/server/production/deploy directory. You can replace default with different server profiles such as all or minimal or production. We will cover those later in this chapter. JBoss AS constantly scans the deploy directory to pick up new applications or any changes to existing applications. So, you can "hot deploy" application on the fly while JBoss AS is still running.
You can deploy several different types of enterprise applications in JBoss AS:
The WAR application archive (e.g., myapp.war) packages a Java EE web application in a JAR file. It contains servlet classes, view pages, libraries, and deployment descriptors such as web.xml, faces-config.xml, and jboss-web.xml etc..
The EAR application archive (e.g., myapp.ear) packages a Java EE enterprise application in a JAR file. It typically contains a WAR file for the web module, JAR files for EJB modules, as well as deployment descriptors such as application.xml and jboss-app.xml etc..
The SAR application archive (e.g., myservice.sar) packages a JBoss service in a JAR file. It is mostly used by JBoss internal services. Please see more in Chapter 3, The JBoss JMX Microkernel.
The *-ds.xml file defines connections to external databases. The data source can then be reused by all applications and services in JBoss AS via the internal JNDI.
You can deploy XML files with MBean service definitions. If you have the appropriate JAR files available in the deploy or lib directories, the MBeans specified in the XML files will be started. This is the way how you start many JBoss AS internal services, such as the JMS queues.
You can also deploy JAR files containing EJBs or other service objects directly in JBoss AS.
The WAR, EAR, and SAR deployment packages are really just JAR files with special XML deployment descriptors in directories like META-INF and WEB-INF. JBoss AS allows you to deploy those archives as expanded directories instead of JAR files. That allows you to make changes to web pages etc on the fly without re-deploying the entire application. If you do need to re-deploy the exploded directory without re-start the server, you can just "touch" the deployment descriptors (e.g., the WEB-INF/web.xml in a WAR and the META-INF/application.xml in an EAR) to update their timestamps.
The JBoss Enterprise Platform ships with four server configurations. You can choose which configuration to start by passing the -c parameter to the server startup script. For instance, command run.sh -c all would start the server in the all configuration. Each configuration is contained in a directory named jboss-as/server/[config name]/. You can look into each server configuration's directory to see the default services, applications, and libraries supported in the configuration.
The minimal configuration starts the core server container without any of the enterprise services. It is a good starting point if you want to build a customized version of JBoss AS that only contains the servers you need.
The default configuration is the mostly common used configuration for application developers. It supports the standard J2EE 1.4 and most of the Java EE 5.0 programming APIs (e.g., JSF and EJB3).
The all configuration is the default configuration with clustering support and other enterprise extensions.
The production configuration is based on the all configuration but with key parameters pre-tuned for production deployment.
The detailed services and APIs supported in each of those configurations will be discussed throughout this book. In this section, we focus on the optimization we did for the production configuration.
To start the server in the production configuration, you can use the following command under Linux / Unix:
cd /path/to/jboss-as
RUN_CONF=server/production/run.conf bin/run.sh -c production
Or, you can simply copy the jboss-as/server/production/run.conf file to jboss-as/bin directory and start the server with run.sh -c production command. Below is a list of optimizations we specifically did for the production configuration:
In the jboss-as/server/production/run.conf file, we expanded the memory size of the server to 1.7 GB. We added the -server tag to JVM startup command on all platforms except for Darwin (Mac OS X). If the JVM is BEA jRockit, the -Xgc:gencon parameter is also added.
We configured the key generation algorithm to use the database to generate HiLo keys in order to generate the correct keys in a cluster environment (see deploy/uuid-key-generator.sar/META-INF/jboss-service.xml).
We removed the test JMS queues from deploy-hasingleton/jms/jbossmq-destinations-service.xml. Those queues are setup primarily for ease of application development. Production applications should configure their own JMS queues.
We set the ScanPeriod parameter to 60000 in conf/jboss-minimal.xml and conf/jboss-service.xml, so that JBoss AS does not spend too much time constantly scanning the deploy directory for new or updated deployments.
We removed the connection monitoring in deploy/jbossjca-service.xml. The connection monitoring feature helps catch unclosed connections that would otherwise cause leaks in the connection pools in development. However, it is a global point of contention that should be turned off (false) in production.
Logging is a big contention point in many production applications. In the production configuration, we removed the console logging and increased the logging level to WARN and ERROR for most packages. Please see details in conf/jboss-log4j.xml.
In addition to the standard optimization in the production configuration, there are a couple of simple techniques you can use to improve the performance and stability of your server.
The production configuration increases the JVM heap memory size to 1.7 GB. You should probably change it to fit your own server. For instance, if have a 64 bit server with several GBs of RAM, you can probably increase this value as long as you also use a 64 bit JVM. If your server has less than 2 GB RAM, you should decrease that value accordingly. In the production/run.conf file, the -Xmx and -Xms parameters specify the maximum and minimum heap sizes respectively. It is recommended that you set the -Xmx and -Xms to the same value to avoid dynamic re-sizing of the heap, which is a source of instability in many JVMs. You could also consider turing on parallel GC options if you are using the Sun JVM on a multi-core machine. The following is an example setup you might use a reference. Please see the Sun JVM documentation for more details on this startup parameters.
JAVA_OPTS="-Xms1740m -Xmx1740m -XX:PermSize=256m -XX:MaxPermSize=512
-XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled"
In the embedded Tomcat module, you can turn off the development mode so that the server does not constantly monitor the changes in JSP files. To do that, edit the deploy/jboss-web.deployer/conf/web.xml file and add the development attribute to the JspServlet.
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
... ...
<init-param>
<param-name>development</param-name>
<param-value>false</param-value>
</init-param>
... ...
In Tomcat, you could adjust the size of the thread pool. If you have multi-core CPUs or more than one CPUs on your server, it might be beneficial to increase the thread pool beyond the default 250. On the other hand, if you have a slow server, decreasing the thread pool will decrease the overhead on the server. The thread pool size can be adjusted via the deploy/jboss-web.deployer/server.xml file.
... ...
<Connector port="8080" address="${jboss.bind.address}"
maxThreads="250" maxHttpHeaderSize="8192"
emptySessionPath="true" protocol="HTTP/1.1"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
... ...
In addition, JBoss AS needs to use a relational database to store runtime data. In a production environment, you should use a production quality database to replace the embedded HSQL database. Please see Appendix B, Use Alternative Databases with JBoss AS for more information on how to setup alternative databases for the JBoss AS.
Table of Contents
Modularly developed from the ground up, the JBoss server and container are completely implemented using component-based plug-ins. The modularization effort is supported by the use of JMX, the Java Management Extension API. Using JMX, industry-standard interfaces help manage both JBoss/Server components and the applications deployed on it. Ease of use is still the number one priority, and the JBoss Server architecture sets a new standard for modular, plug-in design as well as ease of server and application management.
This high degree of modularity benefits the application developer in several ways. The already tight code can be further trimmed down to support applications that must have a small footprint. For example, if EJB passivation is unnecessary in your application, simply take the feature out of the server. If you later decide to deploy the same application under an Application Service Provider (ASP) model, simply enable the server's passivation feature for that web-based deployment. Another example is the freedom you have to drop your favorite object to relational database (O-R) mapping tool, such as TOPLink, directly into the container.
This chapter will introduce you to JMX and its role as the JBoss server component bus. You will also be introduced to the JBoss MBean service notion that adds life cycle operations to the basic JMX management component.
The success of the full Open Source J2EE stack lies with the use of JMX (Java Management Extension). JMX is the best tool for integration of software. It prov ides a common spine that allows the user to integrate modules, containers, and plug-ins. Figure 3.1, “The JBoss JMX integration bus and the standard JBoss components” shows the role of JMX as an integration spine or bus into which components plug. Components are declared as MBean services that are then loaded into JBoss. The components may subsequently be administered using JMX.
Before looking at how JBoss uses JMX as its component bus, it would help to get a basic overview what JMX is by touching on some of its key aspects.
JMX components are defined by the Java Management Extensions Instrumentation and Agent Specification, v1.2, which is available from the JSR003 Web page at http://jcp.org/en/jsr/detail?id=3. The material in this JMX overview section is derived from the JMX instrumentation specification, with a focus on the aspects most used by JBoss. A more comprehensive discussion of JMX and its application can be found in JMX: Managing J2EE with Java Management Extensions written by Juha Lindfors (Sams, 2002).
JMX is a standard for managing and monitoring all varieties of software and hardware components from Java. Further, JMX aims to provide integration with the large number of existing management standards. Figure 3.2, “The Relationship between the components of the JMX architecture” shows examples of components found in a JMX environment, and illustrates the relationship between them as well as how they relate to the three levels of the JMX model. The three levels are:
Instrumentation, which are the resources to manage
Agents, which are the controllers of the instrumentation level objects
Distributed services, the mechanism by which administration applications interact with agents and their managed objects