CHAPTER 9 Integrating Servlet Containers

This chapter describes the steps for integrating a third party Web container into the JBoss application server framework. A Web container is a J2EE server component that enables access to servlets and JSP pages. The most widely used servlet container is Tomcat, and this is the default web container used by JBoss.

Integrating a servlet container into JBoss consists of mapping web-app.xml JNDI information into the JBoss JNDI namespace using an optional jboss-web.xml descriptor as well as delegating authentication and authorization to the JBoss security layer. The org.jboss.web.AbstractWebContainer class exists to simplify these tasks. The focus of the first part of this chapter is how to integrate a Web container using the AbstractWebContainer class. The chapter concludes with a discussion on configuration topices like the use of secure socket layer (SSL) encryption with the JBoss/Tomcat bundle, as well as how to configure Apache with the JBoss/Tomcat bundle.

The AbstractWebContainer Class

The org.jboss.web.AbstractWebContainer class is an implementation of a template pattern for web container integration into JBoss. Web container providers wishing to integrate their container into a JBoss server should create a subclass of AbstractWebContainer and provide the web container specific setup and war deployment steps. The AbstractWebContainer provides support for parsing the standard J2EE web.xml web application deployment descriptor JNDI and security elements as well as support for parsing the JBoss specific jboss-web.xml descriptor. Parsing of these deployment descriptors is performed to generate an integrated JNDI environment and security context. We have already seen the most of the elements of the jboss-web.xml descriptor in other chapters. See The complete jboss-web.xml descriptor DTD.. provides an overview of the jboss-web.xml descriptor DTD for reference. The complete DTD with comments can be found in the JBOSS_DIST/docs/dtd.

FIGURE 9-1. The complete jboss-web.xml descriptor DTD.

The two elements that have not been discussed are the context-root and virtual-host. The context-root element allows one to specify the prefix under which web application is located. This is only applicable to stand-alone web application deployment as a WAR file. Web applications included as part of an EAR must set the root using the context-root element of the EAR application.xml descriptor. The sample jboss-web.xml descriptor shown in See A sample jboss-web.xml descriptor for mapping a war to the root context. illustrates mapping a war to the root context.

  1. A sample jboss-web.xml descriptor for mapping a war to the root context

<jboss-web>

<!-- An empty context root map the war to the root context,

e.g., http://localhost:8080/ -->

<context-root />

</jboss-web>

The virtual-host element specifies the DNS name of the virtual host to which the web application should be deployed. The details of setting up virtual hosts for servlet contexts depends on the particular servlet container. We will look at examples of using the virtual-host element when we look at the Tomcat servlet containers later in this chapter.

The AbstractWebContainer Contract

The AbstractWebContainer is an abstract class that implements the org.jboss.web.AbstractWebContainerMBea n interface used by the JBoss J2EE deployer to delegate the task of installing war files needing to be deployed. See Key methods of the AbstractWebContainer class.. presents some of the key AbstractWebContainer methods.

  1. Key methods of the AbstractWebContainer class.

149:public abstract class AbstractWebContainer

150: extends SubDeployerSupport

151: implements AbstractWebContainerMBean

152:{

153: public static interface WebDescriptorParser

154: {

175: public void parseWebAppDescriptors(ClassLoader loader, WebMetaData metaData) throws Exception;

183: public DeploymentInfo getDeploymentInfo();

184: }

 

267: public boolean accepts(DeploymentInfo sdi)

268: {

269: String warFile = sdi.url.getFile();

270: return warFile.endsWith("war") || warFile.endsWith("war/");

271: }

 

396: public synchronized void start(DeploymentInfo di) throws DeploymentException

397: {

398: Thread thread = Thread.currentThread();

399: ClassLoader appClassLoader = thread.getContextClassLoader();

400: try

401: {

402: // Create a classloader for the war to ensure a unique ENC

403: URL[] empty = {};

404: URLClassLoader warLoader = URLClassLoader.newInstance(empty, di.ucl);

405: thread.setContextClassLoader(warLoader);

406: WebDescriptorParser webAppParser = new DescriptorParser(di);

407: String webContext = di.webContext;

408: if( webContext != null )

409: {

410: if( webContext.length() > 0 && webContext.charAt(0) != '/' )

411: webContext = "/" + webContext;

412: }

413: // Get the war URL

414: URL warURL = di.localUrl != null ? di.localUrl : di.url;

416: if (log.isDebugEnabled())

417: {

418: log.debug("webContext: " + webContext);

419: log.debug("warURL: " + warURL);

420: log.debug("webAppParser: " + webAppParser);

421: }

423: // Parse the web.xml and jboss-web.xml descriptors

424: WebMetaData metaData = (WebMetaData) di.metaData;

425: parseMetaData(webContext, warURL, di.shortName, metaData);

426: WebApplication warInfo = new WebApplication(metaData);

427: warInfo.setDeploymentInfo(di);

428: performDeploy(warInfo, warURL.toString(), webAppParser);

429: deploymentMap.put(warURL.toString(), warInfo);

431: // Generate an event for the startup

432: super.start(di);

433: }

434: catch(DeploymentException e)

435: {

436: throw e;

437: }

438: catch(Exception e)

439: {

440: throw new DeploymentException("Error during deploy", e);

441: }

442: finally

443: {

444: thread.setContextClassLoader(appClassLoader);

445: }

446: }

 

461: protected abstract void performDeploy(WebApplication webApp, String warUrl,

462: WebDescriptorParser webAppParser) throws Exception;

 

469: public synchronized void stop(DeploymentInfo di)

470: throws DeploymentException

471: {

472: URL warURL = di.localUrl != null ? di.localUrl : di.url;

473: String warUrl = warURL.toString();

474: try

475: {

476: performUndeploy(warUrl);

477: // Remove the web application ENC...

478: deploymentMap.remove(warUrl);

480: // Generate an event for the stop

481: super.stop(di);

482: }

483: catch(DeploymentException e)

484: {

485: throw e;

486: }

487: catch(Exception e)

488: {

489: throw new DeploymentException("Error during deploy", e);

490: }

491: }

 

496: protected abstract void performUndeploy(String warUrl) throws Exception;

 

540: public void setConfig(Element config)

541: {

542: }

 

551: protected void parseWebAppDescriptors(DeploymentInfo di, ClassLoader loader,

552: WebMetaData metaData)

553: throws Exception

554: {

555: log.debug("AbstractWebContainer.parseWebAppDescriptors, Begin");

556: InitialContext iniCtx = new InitialContext();

557: Context envCtx = null;

558: Thread currentThread = Thread.currentThread();

559: ClassLoader currentLoader = currentThread.getContextClassLoader();

560: try

561: {

562: // Create a java:comp/env environment unique for the web application

563: log.debug("Creating ENC using ClassLoader: "+loader);

564: ClassLoader parent = loader.getParent();

565: while( parent != null )

566: {

567: log.debug(".."+parent);

568: parent = parent.getParent();

569: }

570: currentThread.setContextClassLoader(loader);

571: metaData.setENCLoader(loader);

572: envCtx = (Context) iniCtx.lookup("java:comp");

574: // Add a link to the global transaction manager

575: envCtx.bind("UserTransaction", new LinkRef("UserTransaction"));

576: log.debug("Linked java:comp/UserTransaction to JNDI name: UserTransaction");

577: envCtx = envCtx.createSubcontext("env");

578: }

579: finally

580: {

581: currentThread.setContextClassLoader(currentLoader);

582: }

584: Iterator envEntries = metaData.getEnvironmentEntries();

585: log.debug("addEnvEntries");

586: addEnvEntries(envEntries, envCtx);

587: Iterator resourceEnvRefs = metaData.getResourceEnvReferences();

588: log.debug("linkResourceEnvRefs");

589: linkResourceEnvRefs(resourceEnvRefs, envCtx);

590: Iterator resourceRefs = metaData.getResourceReferences();

591: log.debug("linkResourceRefs");

592: linkResourceRefs(resourceRefs, envCtx);

593: Iterator ejbRefs = metaData.getEjbReferences();

594: log.debug("linkEjbRefs");

595: linkEjbRefs(ejbRefs, envCtx, di);

596: Iterator ejbLocalRefs = metaData.getEjbLocalReferences();

597: log.debug("linkEjbLocalRefs");

598: linkEjbLocalRefs(ejbLocalRefs, envCtx, di);

599: String securityDomain = metaData.getSecurityDomain();

600: log.debug("linkSecurityDomain");

601: linkSecurityDomain(securityDomain, envCtx);

602: log.debug("AbstractWebContainer.parseWebAppDescriptors, End");

603: }

 

605: protected void addEnvEntries(Iterator envEntries, Context envCtx)

606: throws ClassNotFoundException, NamingException

607: {

615: }

 

617: protected void linkResourceEnvRefs(Iterator resourceEnvRefs, Context envCtx)

618: throws NamingException

619: {

649: }

 

651: protected void linkResourceRefs(Iterator resourceRefs, Context envCtx)

652: throws NamingException

653: {

683: }

 

685: protected void linkEjbRefs(Iterator ejbRefs, Context envCtx, DeploymentInfo di)

686: throws NamingException

687: {

717: }

 

719: protected void linkEjbLocalRefs(Iterator ejbRefs, Context envCtx, DeploymentInfo di)

720: throws NamingException

721: {

763: }

 

774: protected void linkSecurityDomain(String securityDomain, Context envCtx)

775: throws NamingException

776: {

794: }

 

840: public String[] getCompileClasspath(ClassLoader loader)

841: {

864: }

 

1058:}

Lines 267-271 correspond to the accepts method implemented by JBoss deployers to indicate which type of deployments they accepts. The AbstractWebContainer handles the deployments of WARs as jars or unpacked directories.

Lines 396-446 correspond to the start method. This method is a template pattern method implementation. The argument to the deploy method is the WAR deployment info object. This contains the URL to the WAR, the UnifiedClassLoader for the WAR, the parent archive such as an EAR, and the J2EE application.xml context-root if the WAR is part of an EAR.

The first step of the start method is to save the current thread context ClassLoader and then create another URLClassCloader (warLoader) using the WAR UnifiedClassLoader as its parent. This warLoader is used to ensure a unique JNDI ENC (enterprise naming context) for the WAR will be created. This is done by the code on lines 403-404. Chapter 3 mentioned that the java:comp context's uniqueness was determined by the ClassLoader that created the java:comp context. The warLoader ClassLoader is set as the current thread context ClassLoader , on line 405, before the performDeploy call is made. Next, the web.xml and jboss-web.xml descriptors are parsed by calling parseMetaData on line 425. Next, the Web container-specific subclass is asked to perform the actual deployment of the WAR through the performDeploy call on line 429. The WebApplication object for this deployment is stored in the deployed application map using the warUrl as the key on line 429. The final step at line 444 is to restore the thread context ClassLoader to the one that existed at the start of the method.

Lines 461-462 give the signature for the abstract performDeploy method. This method is called by the start method and must be overridden by subclasses to perform the Web container specific deployment steps. A WebApplication is provided as an argument, and this contains the metadata from the web.xml descriptor, and the jboss-web.xml descriptor. The metadata contains the context-root value for the web module from the J2EE application.xml descriptor, or if this is a stand-alone deployment, the jboss-web.xml descriptor. The metadata also contains any jboss-web.xml descriptor virtual-host value. On return from performDeploy , the WebApplication must be populated with the ClassLoader of the servlet context for the deployment. The warUrl argument is the string for the URL of the Web application WAR to deploy. The webAppParser argument is a callback handle the subclass must use to invoke the parseWebAppDescriptors method to set up the Web application JNDI environment. This callback provides a hook for the subclass to establish the Web application JNDI environment before any servlets are created that are to be loaded on startup of the WAR. A subclass' performDeploy method implementation needs to be arranged so that it can call the parseWebAppDescriptors before starting any servlets that need to access JNDI for JBoss resources like EJBs, resource factories, and so on. One important setup detail that needs to be handled by a subclass implementation is to use the current thread context ClassLoader as the parent ClassLoader for any Web container-specific ClassLoader created. Failure to do this results in problems for Web applications that attempt to access EJBs or JBoss resources through the JNDI ENC.

Lines 469-717 correspond to the stop method. This is a template pattern method implementation. Line 476 of this method calls the subclass performUndeploy method to perform the container-specific undeployment steps. Next, at line 478, the warUrl is unregistered from the deployment map. The warUrl argument is the string URL of the WAR as originally passed to the performDeploy method.

Line 496 gives the signature of the abstract performUndeploy method. This method is called as part of the stop method template as shown on line 476. A call to performUndeploy asks the subclass to perform the Web container-specific undeployment steps.

Lines 540-542 correspond to the setConfig method. This method is a stub method that subclasses can override if they want to support an arbitrary extended configuration beyond that which is possible through MBean attributes. The config argument is the parent DOM element for an arbitrary hierarchy given by the child element of the Config attribute in the mbean element specification of the jboss-service.xml descriptor of the web container service. You'll see an example use of this method and config value when you look at the MBean that supports embedding Tomcat into JBoss.

Lines 551- 603 correspond to the parseWebAppDescriptors method. This is invoked from within the subclass performDeploy method when it invokes the webAppParser.parseWebAppDescriptors callback to setup Web application ENC (java:comp/env) env-entry, resource-env-ref, resource-ref, local-ejb-ref and ejb-ref element values declared in the web.xml descriptor. The creation of the env-entry values does not require a jboss-web.xml descriptor. The creation of the resource-env-ref, resource-ref, and ejb-ref elements does require a jboss-web.xml descriptor for the JNDI name of the deployed resources/EJBs. Because the ENC context is private to the Web application, the Web application ClassLoader is used to identify the ENC. The loader argument is the ClassLoader for the Web application, and may not be null. The metaData argument is the WebMetaData argument passed to the subclass performDeploy method. The implementation of the parseWebAppDescriptors uses the metadata information from the WAR deployment descriptors and then creates the JNDI ENC bindings by calling methods shown on lines 584-601.

The addEnvEntries method on lines 605-615 creates the java:comp/env Web application env-entry bindings that were specified in the web.xml descriptor.

The linkResourceEnvRefs method on lines 617-649 maps the java:comp/env/xxx Web application JNDI ENC resource-env-ref web.xml descriptor elements onto the deployed JNDI names using the mappings specified in the jboss-web.xml descriptor.

The linkResourceRefs method on lines 651-683 maps the java:comp/env/xxx Web application JNDI ENC resource-ref web.xml descriptor elements onto the deployed JNDI names using the mappings specified in the jboss-web.xml descriptor.

The linkEjbRefs method on lines 685-717 maps the java:comp/env/ejb Web application JNDI ENC ejb-ref web.xml descriptor elements onto the deployed JNDI names using the mappings specified in the jboss-web.xml descriptor.

The linkEjbLocalRefs method on lines 719-763 maps the java:comp/env/ejb Web application JNDI ENC ejb-local-ref web.xml descriptor elements onto the deployed JNDI names using the ejb-link mappings specified in the web.xml descriptor.

The linkSecurityDomain method on lines 774-794 creates a java:comp/env/security context that contains a securityMgr binding pointing to the AuthenticationManager implementation and a realmMapping binding pointing to the RealmMapping implementation that is associated with the security domain for the Web application. Also created is a subject binding that provides dynamic access to the authenticated Subject associated with the request thread. If the jboss-web.xml descriptor contained a security-domain element, the bindings are javax.naming.LinkRef s to the JNDI name specified by the security-domain element, or subcontexts of this name. If there was no security-domain element, the bindings are to org.jboss.security.plugins.NullSecurityManager instance that simply allows all authentication and authorization checks.

Lines 840-864 correspond to the getCompileClasspath method. This is a utility method available for Web containers to generate a classpath that walks up the ClassLoader chain starting at the given loader and queries each ClassLoader for the URLs it serves to build a complete classpath of URL strings. This is needed by some JSP compiler implementations (Jasper for one) that expect to be given a complete classpath for compilation.

Creating an AbstractWebContainer Subclass

To integrate a web container into JBoss you need to create a subclass of AbstractWebContainer and implement the required performDeploy(WebApplication, String, WebDescriptorParser) and performUndeploy(String) methods as described in the preceding section. The following additional integration points should be considered as well.

Use the Thread Context Class Loader

Although this issue was noted in the performDeploy method description, we'll repeat it here since it is such a critical detail. During the setup of a WAR container, the current thread context ClassLoader must be used as the parent ClassLoader for any web container specific ClassLoader that is created. Failure to do this will result in problems for web applications that attempt to access EJBs or JBoss resources through the JNDI ENC.

Integrate Logging Using log4j

JBoss uses the Apache log4j logging API as its internal logging API. For a web container to integrate well with JBoss it needs to provide a mapping between the web container logging abstraction to the log4j API. As a subclass of AbstractWebContainer , your integration class has access to the log4j interface via the super.log instance variable or equivalently, the superclass getLog method. This is an instance of the org.jboss.logging.Logger class that wraps the log4j category. The name of the log4j category is the name of the container subclass.

Delegate web container authentication and authorization to JBossSX

Ideally both web application and EJB authentication and authorization are handled by the same security manager. To enable this for your web container you must hook into the JBoss security layer. This typically requires a request interceptor that maps from the web container security callouts to the JBoss security API. Integration with the JBossSX security framework is based on the establishment of a "java:comp/env/security" context as described in the linkSecurityDomain method comments in the previous section. The security context provides access to the JBossSX security manager interface implementations associated with the web application for use by subclass request interceptors. An outline of the steps for authenticating a user using the security context is presented in See A pseudo-code description of authenticating a user via the JBossSX API and the java:comp/env/security JNDI context.. in quasi pseudo-code. See A pseudo-code description of authorization a user via the JBossSX API and the java:comp/env/security JNDI context.. provides the equivalent process for the authorization of a user.

  1. A pseudo-code description of authenticating a user via the JBossSX API and the java:comp/env/security JNDI context.

// Get the username and password from the request context...

HttpServletRequest request = ...;

String username = getUsername(request);

String password = getPassword(request);

// Get the JBoss security manager from the ENC context

InitialContext iniCtx = new InitialContext();

AuthenticationManager securityMgr = (AuthenticationManager)

iniCtx.lookup("java:comp/env/security/securityMgr");

SimplePrincipal principal = new SimplePrincipal(username);

if( securityMgr.isValid(principal, password) )

{

// Indicate the user is allowed access to the web content...

// Propagate the user info to JBoss for any calls into made by the servlet

SecurityAssociation.setPrincipal(principal);

SecurityAssociation.setCredential(password.toCharArray());

}

else

{

// Deny access...

}

  1. A pseudo-code description of authorization a user via the JBossSX API and the java:comp/env/security JNDI context.

// Get the username & required roles from the request context...

HttpServletRequest request = ...;

String username = getUsername(request);

String[] roles = getContentRoles(request);

// Get the JBoss security manager from the ENC context

InitialContext iniCtx = new InitialContext();

RealmMapping securityMgr = (RealmMapping)

iniCtx.lookup("java:comp/env/security/realmMapping");

SimplePrincipal principal = new SimplePrincipal(username);

Set requiredRoles = new HashSet(java.util.Arrays.asList(roles));

if( securityMgr.doesUserHaveRole(principal, requiredRoles) )

{

// Indicate user has the required roles for the web content...

}

else

{

// Deny access...

}

JBoss/Tomcat-4.1.x bundle notes

In this section we'll discuss configuration issues specific to the JBoss/Tomcat-4.x integration bundle. The Tomcat-4.1.x release, which is also known by the name Catalina, is the latest Apache Java servlet container. It supports the Servlet 2.3 and JSP 1.2 specifications. The JBoss/Tomcat integration layer is controlled by the JBoss MBean service configuration. The MBean used to embed the Tomcat-4.1.x series of web containers is the org.jboss.web.tomcat.tc4.EmbeddedTomcatService service, and it is a subclass of the AbstractWebContainer class. Its configurable attributes include:

FIGURE 9-2. An overview of the Tomcat-4.1.24 configuration DTD supported by the EmbeddedCatalinaService41 Config attribute.

The integration of Tomcat with JBoss depends on the jboss-service.xml descriptor found in the deploy/jbossweb-tomcat.sar/META-INF directories of the default and all configuration file sets. You will only find this descriptor in the bundled release of JBoss/Tomcat. This bundle also include the Tomcat distribution as the jbossweb-tomcat41.sar directory. Currently this is the jakarta-tomcat-4.1.29-LE-jdk14 distribution.

The Embedded Tomcat Configuration Elements

This section provides an overview of the Tomcat configuration elements that may appear as child elements of the EmbeddedTomcatService Config attribute.

Server

The Server element is the root element of the Tomcat servlet container configuration. There are no attributes of this element that are supported by the embedded service.

Service

A Service is a container of one or more Connectors and a single Engine. The only supported attribute is:

  • name, a unique name by which the service is known.

Connector

A Connector element configures a transport mechanism that allows clients to send requests and receive responses from the Service it is associated with. Connectors forward requests to the Service Engine and return the results to the requesting client. There are currently three connector implementations, HTTP, AJP and Warp. All connectors support these attributes:

  • className, the fully qualified name of the class of the connector implementation. The class must implement the org.apache.catalina.Connector interface. The embedded service defaults to the org.apache.catalina.connector.http.HttpConnector , which is the HTTP connector implementation.
  • enableLookups, a flag that enables DNS resolution of the client hostname as accessed via the ServletRequest.getRemoteHost method. This flag defaults to false.
  • redirectPort, the port to which non-SSL requests will be redirected when a request for content secured under a transport confidentiality or integrity constraint is received. This defaults to the standard https port of 443.
  • secure, sets the ServletRequest.isSecure method value flag to indicate whether or not the transport channel is secure. This flag defaults to false.scheme, sets the protocol name as accessed by the ServletRequest.getScheme method. The scheme defaults to http.
The HTTP Connector

The HTTP connector is an HTTP 1.1 protocol connector that allows Tomcat to function as a stand-alone web server. This is now deprecated in favor of the Coyote connector, but this is the only connector which currently works with the JBoss SSL socket factory that integrates with the JBossSecurityDomain service. The key attributes specific to this connector are:

  • className: org.apache.catalina.connector.http.HttpConnector for the tomcat-4.1.x version of the web container.
  • acceptCount: The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 10.
  • allowChunking: If set to true, chunked output is allowed when processing HTTP/1.1 requests. This is set to true by default.
  • address. For servers with more than one IP address, this attribute specifies which address will be used for listening on the specified port. By default, this port will be used on all IP addresses associated with the server.
  • bufferSize: The size (in bytes) of the buffer to be provided for input streams created by this connector. By default, buffers of 2048 bytes will be provided.
  • connectionTimeout: The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. The default value is 60000 (i.e. 60 seconds).
  • debug: The debugging detail level of log messages generated by this component, with higher numbers creating more detailed output. If not specified, this attribute is set to zero (0). Whether or not this shows up in the log further depends on the log4j category "org.jboss.web.catalina.EmbeddedCatalinaService41" threshold.
  • maxProcessors: The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 20.
  • minProcessors: The number of request processing threads that will be created when this Connector is first started. This attribute should be set to a value smaller than that set for maxProcessors. The default value is 5.
  • port: The TCP port number on which this Connector will create a server socket and await incoming connections. Your operating system will allow only one server application to listen to a particular port number on a particular IP address.

proxyName: If this Connector is being used in a proxy configuration, configure this attribute to specify the server name to be returned for calls to request.getServerName(). See Proxy Support for more information.

  • proxyPort: If this Connector is being used in a proxy configuration, configure this attribute to specify the server port to be returned for calls to request.getServerPort(). See Proxy Support for more information.
  • tcpNoDelay: If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances. This is set to true by default.

Additional attribute descriptions may be found in the Tomcat website document: http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/http11.html

The Coyote Connector

The CoyoteConnector is the default HTTP/1.1 connector that enables Catalina to function as a stand-alone web server, in addition to its ability to execute servlets and JSP pages. In addition, it can be configured to handle the AJP 1.3 protocols uses with the Apache mod_jk and mod_jk2 modules. The supported attributes are:

  • className: org.apache.coyote.tomcat4.CoyoteConnector for the tomcat-4.1.x version of the web server.
  • acceptCount: The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 10.
  • address. For servers with more than one IP address, this attribute specifies which address will be used for listening on the specified port. By default, this port will be used on all IP addresses associated with the server.
  • bufferSize: The size (in bytes) of the buffer to be provided for input streams created by this connector. By default, buffers of 2048 bytes will be provided.
  • compression: The Connector may use HTTP/1.1 GZIP compression in an attempt to save server bandwidth. The acceptable values for the parameter is "off" (disable compression), "on" (allow compression, which causes text data to be compressed), "force" (forces compression in all cases), or a numerical integer value (which is equivalent to "on", but specifies the minimum amount of data before the output is compressed). If the content-length is not known and compression is set to "on" or more aggressive, the output will also be compressed. If not specified, this attribute is set to "false".
  • connectionLinger: The number of milliseconds during which the sockets used by this Connector will linger when they are closed. The default value is -1 (socket linger is disabled).
  • connectionTimeout: The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. The default value is 60000 (i.e. 60 seconds).
  • debug: The debugging detail level of log messages generated by this component, with higher numbers creating more detailed output. If not specified, this attribute is set to zero (0). Whether or not this shows up in the log further depends on the log4j category "org.jboss.web.catalina.EmbeddedCatalinaService41" threshold.
  • disableUploadTimeout: This flag allows the servlet container to use a different, longer connection timeout while a servlet is being executed, which in the end allows either the servlet a longer amount of time to complete its execution, or a longer timeout during data upload. If not specified, this attribute is set to "false".
  • maxProcessors: The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 20.
  • minProcessors: The number of request processing threads that will be created when this Connector is first started. This attribute should be set to a value smaller than that set for maxProcessors. The default value is 5.
  • port: The TCP port number on which this Connector will create a server socket and await incoming connections. Your operating system will allow only one server application to listen to a particular port number on a particular IP address.
  • proxyName: If this Connector is being used in a proxy configuration, configure this attribute to specify the server name to be returned for calls to request.getServerName(). See Proxy Support for more information.
  • proxyPort: If this Connector is being used in a proxy configuration, configure this attribute to specify the server port to be returned for calls to request.getServerPort(). See Proxy Support for more information.
  • tcpNoDelay: If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances. This is set to true by default.

Additional information on the Coyote connector may be found on the this Tomcat site page: http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/coyote.html .

Engine

Each Service must have a single Engine configuration. An Engine handles the requests submitted to a Service via the configured connectors. The child elements supported by the embedded service include Host, Logger, DefaultContext, Valve and Listener. The supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.Engine interface implementation to use. If not specifies this defaults to org.apache.catalina.core.StandardEngine.
  • defaultHost, the name of a Host configured under the Engine that will handle requests with host names that do not match a Host configuration.
  • name, a logical name to assign the Engine. It will be used in log messages produced by the Engine.

Additional information on the Engine element may be found in the Tomcat website document http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/engine.html .

Host

A Host element represents a virtual host configuration. It is a container for web applications with a specified DNS hostname. The child elements supported by the embedded service include Alias , Logger , DefaultContext , Valve and Listener . The supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.Host interface implementation to use. If not specifies this defaults to org.apache.catalina.core.StandardHost .
  • name, the DNS name of the virtual host. At least one Host element must be configured with a name that corresponds to the defaultHost value of the containing Engine.

Additional information on the Host element may be found in the Tomcat website document http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/host.html .

Alias

The Alias elment is an optional child element of the Host element. Each Alias content specifies an alternate DNS name for the enclosing Host .

DefaultContext

The DefaultContext element is a configuration template for web application contexts. It may be defined at the Engine or Host level. The child elements supported by the embedded service include WrapperLifecycle , InstanceListener , WrapperListener , and Manager . The supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.core.DefaultContext implementation. This defaults to org.apache.catalina.core.DefaultContext and if overriden must be a subclass of . DefaultContext .
  • cookies, a flag indicating if sessions will be tracked using cookies. The default is true.
  • crossContext, A flag indicating if the ServletContext.getContext(String path) method should return contexts for other web applications deployed in the calling web application's virtual host. The default is false.
Manager

The Manager element is an optional child of the DefaultContext configuration that defines a session manager. The supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.Manager interface implementation. This defaults to org.apache.catalina.session.StandardManager.

Logger

The Logger element specifies a logging configuration for Engine , Host s, and DefaultContext s. The supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.Logger interface implementation. This defaults to org.jboss.web.catalina.Log4jLogger . and should be used for integration with JBoss server log4j system.

Valve

A Valve element configures a request pipeline element. A Valve is an implementation of the org.apache.catalina.Valve interface, and several standard Valve s are available for use. The most commonly used Valve allows one to log access requests. Its supported attributes include:

  • className, the fully qualified class name of the org.apache.catalina.Valve interface implementation. This must be org.jboss.web.catalina.valves.AccessLogValu e.
  • directory, the directory path into which the access log files will be created.
  • pattern, a pattern specifier that defines the format of the log messages. This defaults to "common".
  • prefix, the prefix to add to each log file name. This defaults to "access_log".
  • suffix, the suffix to add to each log file name. This default to the empty string "" meaning that no suffix will be added.

Additional information on the Valve element and the available valve implementations may be found in the Tomcat website document http://jakarta.apache.org/tomcat/tomcat-4.1-doc/config/valve.html .

Listener

A Listener element configures a component life-cycle listener. You add a life-cycle listener using a Listener element with a className attribute giving the fully qualified name of the org.apache.catalina.LifecycleListener interface along with any additional properties supported by the listener implementation.

Using SSL with the JBoss/Tomcat bundle

There are a few ways one can configure HTTP over SSL for the embedded Tomcat servlet container.The main difference is whether or not you use the JBoss specific connector socket factory that allows one to obtain the JSSE server certificate information from a JBossSX SecurityDomain. This requires establishing a SecurityDomain using the org.jboss.security.plugins.JaasSecurityDomain MBean. These two steps are similar to the procedure we used in Chapter 8 to enable RMI with SSL encryption. A jbossweb-tomcat41.sar/META-INF/jboss-service.xml configuration file that illustrates the setup of only an SSL connector via this approach is given in See The JaasSecurityDoman and EmbeddedCatalinaSX MBean configurations for setting up Tomcat-4.x to use SSL as its primary connector protocol...This configuration includes the same JaasSecurityDomain setup as Chapter 8, but since the descriptor is not being deployed as part of a SAR that includes the chap8.keystore, you need to copy the chap8.keystore to the server/default/conf directory.

  1. The JaasSecurityDoman and EmbeddedCatalinaSX MBean configurations for setting up Tomcat-4.x to use SSL as its primary connector protocol.

<?xml version="1.0" encoding="UTF-8"?>

<!-- An example tomcat config that only uses SSL connectors.

-->

 

<!-- The service configuration for the embedded Tomcat4 web container

-->

<server>

 

<!-- The SSL domain setup -->

<mbean code="org.jboss.security.plugins.JaasSecurityDomain"

name="Security:name=JaasSecurityDomain,domain=RMI+SSL">

<constructor>

<arg type="java.lang.String" value="RMI+SSL"/>

</constructor>

<attribute name="KeyStoreURL">chap8.keystore</attribute>

<attribute name="KeyStorePass">rmi+ssl</attribute>

</mbean>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<!-- Get the flag indicating if the normal Java2 parent first class

loading model should be used over the servlet 2.3 web container first

model.

-->

<attribute name="Java2ClassLoadingCompliance">true</attribute>

 

<attribute name="LenientEjbLink">true</attribute>

 

<!-- A flag indicating if the JBoss Loader should be used. This loader

uses a unified class loader as the class loader rather than the tomcat

specific class loader.

-->

<attribute name="UseJBossWebLoader">true</attribute>

 

<!-- The name of the request attribute under with the authenticated JAAS

Subject is stored on successful authentication. If null or empty then

the Subject will not be stored.

-->

<attribute name="SubjectAttributeName">j_subject</attribute>

 

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="localhost">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

<Host name="localhost">

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="localhost_access" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

 

<!-- This valve clears any caller identity set by the realm

and provides access to the realm about the existence of an

authenticated caller to allow a web app to run with a realm

that support unauthenticated identities. It also establishes

any run-as principal for the servlet being accessed.

-->

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

</Host>

</Engine>

 

<!-- SSL/TLS Connector configuration using the SSL domain keystore -->

<Connector className = "org.apache.catalina.connector.http.HttpConnector"

port = "443" scheme = "https" secure = "true">

<Factory className = "org.jboss.web.tomcat.security.SSLServerSocketFactory"

securityDomainName = "java:/jaas/RMI+SSL" clientAuth = "false"

protocol = "TLS"/>

</Connector>

</Service>

</Server>

</attribute>

</mbean>

 

</server>

A quick test of this config can be made by accessing the JMX console web application using this URL https://localhost/jmx-console/index.jsp .

Note: if your running on a *nix system (Linux, Solaris, OS X) that only allows root to open ports below 1024 you will need to change the port number above to something like 8443.

Alternatively, if one wants to support both access using non-SSL and SSL, you can do this by adding another connector configuration to the EmbeddedCatalinaService41 MBean. A jboss-service.xml configuration file that illustrates such a setup of SSL is given in See The JaasSecurityDoman and EmbeddedCatalinaSX MBean configurations for setting up Tomcat-4.x to use both non-SSL and SSL enabled HTTP connectors...

  1. The JaasSecurityDoman and EmbeddedCatalinaSX MBean configurations for setting up Tomcat-4.x to use both non-SSL and SSL enabled HTTP connectors.

<?xml version="1.0" encoding="UTF-8"?>

<!-- An example tomcat config that only uses both non-SSL and SSL connectors.

-->

 

<!-- The service configuration for the embedded Tomcat4 web container

-->

<server>

 

<!-- The SSL domain setup -->

<mbean code="org.jboss.security.plugins.JaasSecurityDomain"

name="Security:name=JaasSecurityDomain,domain=RMI+SSL">

<constructor>

<arg type="java.lang.String" value="RMI+SSL"/>

</constructor>

<attribute name="KeyStoreURL">chap8.keystore</attribute>

<attribute name="KeyStorePass">rmi+ssl</attribute>

</mbean>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<!-- Get the flag indicating if the normal Java2 parent first class

loading model should be used over the servlet 2.3 web container first

model.

-->

<attribute name="Java2ClassLoadingCompliance">true</attribute>

 

<attribute name="LenientEjbLink">true</attribute>

 

<!-- A flag indicating if the JBoss Loader should be used. This loader

uses a unified class loader as the class loader rather than the tomcat

specific class loader.

-->

<attribute name="UseJBossWebLoader">true</attribute>

 

<!-- The name of the request attribute under with the authenticated JAAS

Subject is stored on successful authentication. If null or empty then

the Subject will not be stored.

-->

<attribute name="SubjectAttributeName">j_subject</attribute>

 

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="localhost">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

<Host name="localhost">

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="localhost_access" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

 

<!-- This valve clears any caller identity set by the realm

and provides access to the realm about the existence of an

authenticated caller to allow a web app to run with a realm

that support unauthenticated identities. It also establishes

any run-as principal for the servlet being accessed.

-->

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

</Host>

</Engine>

 

<!-- HTTP Connector configuration -->

<Connector className = "org.apache.catalina.connector.http.HttpConnector"

port = "8080" redirectPort = "443"/>

<!-- SSL/TLS Connector configuration using the SSL domain keystore -->

<Connector className = "org.apache.catalina.connector.http.HttpConnector"

port = "443" scheme = "https" secure = "true">

<Factory className = "org.jboss.web.catalina.security.SSLServerSocketFactory"

securityDomainName = "java:/jaas/RMI+SSL" clientAuth = "false"

protocol = "TLS"/>

</Connector>

</Service>

</Server>

</attribute>

</mbean>

 

</server>

You can also setup SSL using the standard Coyote connector. This connector does not support custom SSL socket factories well however and the org.jboss.web.catalina.security.SSLServerSocketFactory cannot be used. Instead you need to add a Factory element to the Coyote Connector, to set up the required SSL socket factory. The Factory element supports the following attributes:

  • algorithm: The certificate encoding algorithm to be used. If not specified, the default value is SunX509.
  • className: The fully qualified class name of the SSL server socket factory implementation class. You must specify org.apache.coyote.tomcat4.CoyoteServerSocketFactory here. Using any other socket factory will not cause an error, but the server socket will not be using SSL.
  • clientAuth: Set to true if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. A false value (which is the default) will not require a certificate chain unless the client requests a resource protected by a security constraint that uses CLIENT-CERT authentication.
  • keystoreFile: The pathname of the keystore file where you have stored the server certificate to be loaded. By default, the pathname is the file ".keystore" in the operating system home directory of the user that is running Tomcat.
  • keystorePass: The password used to access the server certificate from the specified keystore file. The default value is "changeit".
  • keystoreType: The type of keystore file to be used for the server certificate. If not specified, the default value is "JKS".
  • protocol: The version of the SSL protocol to use. If not specified, the default is "TLS".

A jboss-service.xml configuration file that illustrates such a setup of SSL is given in See An EmbeddedCatalinaService41 MBean configurations for setting up Tomcat-4.1.x to use SSL enabled HTTP with the Coyote connector...

  1. An EmbeddedCatalinaService41 MBean configurations for setting up Tomcat-4.1.x to use SSL enabled HTTP with the Coyote connector.

 

<?xml version="1.0" encoding="UTF-8"?>

 

<!-- An embedded Tomcat4.1.x web container that uses only an SSL/Coyote connector -->

<server>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<!-- Get the flag indicating if the normal Java2 parent first class

loading model should be used over the servlet 2.3 web container first

model.

-->

<attribute name="Java2ClassLoadingCompliance">true</attribute>

 

<attribute name="LenientEjbLink">true</attribute>

 

<!-- A flag indicating if the JBoss Loader should be used. This loader

uses a unified class loader as the class loader rather than the tomcat

specific class loader.

-->

<attribute name="UseJBossWebLoader">true</attribute>

 

<!-- The name of the request attribute under with the authenticated JAAS

Subject is stored on successful authentication. If null or empty then

the Subject will not be stored.

-->

<attribute name="SubjectAttributeName">j_subject</attribute>

 

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="localhost">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

<Host name="localhost">

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="localhost_access" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

 

<!-- This valve clears any caller identity set by the realm

and provides access to the realm about the existence of an

authenticated caller to allow a web app to run with a realm

that support unauthenticated identities. It also establishes

any run-as principal for the servlet being accessed.

-->

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

</Host>

</Engine>

 

<!-- SSL/TLS Connector configuration -->

<Connector className = "org.apache.coyote.tomcat4.CoyoteConnector"

address="${jboss.bind.address}" port = "8443" scheme = "https" secure = "true">

<Factory className = "org.apache.coyote.tomcat4.CoyoteServerSocketFactory"

keystoreFile="${jboss.server.home.dir}/conf/server.keystore"

keystorePass="tc-ssl"

protocol = "TLS"/>

</Connector>

</Service>

</Server>

</attribute>

<depends>jboss:service=TransactionManager</depends>

</mbean>

 

</server>

All approaches work so which you choose is a matter of preference, with the caveat that the CoyoteConnector is the preferred and more performant connector at this point. Note that if you try to test this configuration using the self-signed certificate from the Chapter 8 chap8.keystore and attempt to access content over an https connection, your browser should display a warning dialog indicating that it does not trust the certificate authority that signed the certificate of the server you are connecting to. For example, when the first configuration example was tested, IE 5.5 showed the initial security alert dialog listed in See The Internet Explorer 5.5 security alert dialog... See The Internet Explorer 5.5 SSL certificate details dialog.. shows the server certificate details. This is the expected behavior as anyone can generate a self-signed certificate with any information they want, and a web browser should warn you when such a secure site is encountered.

FIGURE 9-3. The Internet Explorer 5.5 security alert dialog.
FIGURE 9-4. The Internet Explorer 5.5 SSL certificate details dialog.

Setting up Virtual Hosts with the JBoss/Tomcat-4.x bundle

As of the 2.4.5 release, support for virtual hosts has been added to the servlet container layer. Virtual hosts allow you to group web applications according to the various DNS names by which the machine running JBoss is known. As an example, consider the jbossweb-tomcat41.sar/META-INF/jboss-service.xml configuration file given in See An example virtual host configuration... This configuration defines a default host named localhost and a second host named vhost1.mydot.com. The vhost2.mydot.com also has the alias www.mydot.com associated with it.

  1. An example virtual host configuration.

<?xml version="1.0" encoding="UTF-8"?>

 

<!-- An example vhost configuration -->

<server>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<!-- Get the flag indicating if the normal Java2 parent first class

loading model should be used over the servlet 2.3 web container first

model.

-->

<attribute name="Java2ClassLoadingCompliance">true</attribute>

 

<attribute name="LenientEjbLink">true</attribute>

 

<!-- A flag indicating if the JBoss Loader should be used. This loader

uses a unified class loader as the class loader rather than the tomcat

specific class loader.

-->

<attribute name="UseJBossWebLoader">true</attribute>

 

<!-- The name of the request attribute under with the authenticated JAAS

Subject is stored on successful authentication. If null or empty then

the Subject will not be stored.

-->

<attribute name="SubjectAttributeName">j_subject</attribute>

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="vhost1">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

 

<Host name="vhost1">

<Alias>vhost1.mydot.com</Alias>

 

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="vhost1" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

</Host>

 

<Host name="vhost2">

<Alias>vhost2.mydot.com</Alias>

<Alias>www.mydot.com</Alias>

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="vhost2" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

</Host>

</Engine>

 

<!-- A HTTP/1.1 Connector on port 8080 -->

<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"

address="${jboss.bind.address}" port="8080" minProcessors="5"

maxProcessors="100" enableLookups="true" acceptCount="10" debug="0"

connectionTimeout="20000" useURIValidationHack="false"/>

</Service>

</Server>

</attribute>

<depends>jboss:service=TransactionManager</depends>

</mbean>

 

</server>

When a WAR is deployed, it will be by default associated with the virtual host whose name matches the defaultHost attribute of the containing Engine . To deploy a WAR to a specific virtual host you need to use the jboss-web.xml descriptor and the virtual-host element. For example, to deploy a WAR to the virtual host www.mydot.com virtual host alias, the following jboss-web.xml descriptor would be need to be included in the WAR WEB-INF directory. This demonstrates that an alias of the virtual host can be used in addition to the Host name attribute value.

  1. An example jboss-web.xml descriptor for deploying a WAR to the www.starkinternational.com virtual host

<jboss-web>

<context-root>/</context-root>

<virtual-host>www.mydot.com</virtual-host>

</jboss-web>

Serving External Static Content

You can serve external static files from web apps by adding an external directory content to the Tomcat configuration. For example, to serve shared images from a C:/tmp/images directory, edit jbossweb-tomcat41.sar/META-INF/jboss-service.xml and add a Context entry to the Config element as shown in See An example configuration for including external static content..

  1. An example configuration for including external static content

<?xml version="1.0" encoding="UTF-8"?>

<!-- An example tomcat config that includes an external context.

 

With this you can reference the /images path from any war deployed

to the Host. For example, a test-ex.war index.html page accessible

at http://localhost/test-ex/index.html that includes images from

the external context:

 

test-ex.war/index.html

<html>

 

<body>

<h1>External Images</h1>

<ul>

<li><img src="/images/img1.jpg" alt="Image1"></li>

<li><img src="/images/img1.jpg" alt="Image2"></li>

<li><img src="/images/img1.jpg" alt="Image3"></li>

</ul>

</body>

 

</html>

-->

<server>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<attribute name="Java2ClassLoadingCompliance">true</attribute>

<attribute name="LenientEjbLink">true</attribute>

<attribute name="UseJBossWebLoader">true</attribute>

<attribute name="SubjectAttributeName">j_subject</attribute>

 

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="localhost">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

<Host name="localhost">

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="localhost_access" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

 

<!-- This valve clears any caller identity set by the realm

and provides access to the realm about the existence of an

authenticated caller to allow a web app to run with a realm

that support unauthenticated identities. It also establishes

any run-as principal for the servlet being accessed.

-->

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true">

 

<!-- Add a static context /images using directory /tmp/images -->

<Context path="/images" docBase="/tmp/images" debug="1"

reloadable="true" crossContext="true">

</Context>

</Host>

</Engine>

 

<!-- A HTTP/1.1 Connector on port 8080 -->

<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"

address="${jboss.bind.address}" port="8080" minProcessors="5"

maxProcessors="100" enableLookups="true" acceptCount="10" debug="0"

connectionTimeout="20000" useURIValidationHack="false"/>

</Service>

</Server>

</attribute>

<depends>jboss:service=TransactionManager</depends>

</mbean>

 

</server>

One thing to note about the docBase attribute on the Context element. This must be seen as an absolute path by the java.io.File object on the platform. This means on win32 platforms that the path must begin with the drive spec, for example, "C:/tmp/images".

Using Apache with the JBoss/Tomcat-4.x bundle

To enable the use of Apache as a front-end web server that delegates servlet requests to a JBoss/Tomcat bundle, you need to configure an appropriate connector in the EmbeddedTomcatService MBean definition. For example, to configure the use of the Ajpv13 protocol connector with the Apache mod_jk module, you would use a configuration like that given in See An example EmbeddedTomcatService MBean configuration that supports integration with Apache using the Ajpv13 protocol connector...

  1. An example EmbeddedTomcatService MBean configuration that supports integration with Apache using the Ajpv13 protocol connector.

<?xml version="1.0" encoding="UTF-8"?>

 

<!-- An example AJP configuration -->

<server>

 

<mbean code="org.jboss.web.tomcat.tc4.EmbeddedTomcatService"

name="jboss.web:service=WebServer">

 

<attribute name="Java2ClassLoadingCompliance">true</attribute>

<attribute name="LenientEjbLink">true</attribute>

<attribute name="UseJBossWebLoader">true</attribute>

<attribute name="SubjectAttributeName">j_subject</attribute>

 

<attribute name="Config">

<Server>

<Service name="JBoss-Tomcat">

<Engine name="MainEngine" defaultHost="localhost">

<Logger className="org.jboss.web.tomcat.Log4jLogger"

verbosityLevel="debug" category="org.jboss.web.localhost.Engine"/>

<Host name="localhost">

 

<!-- Access logger -->

<Valve className="org.apache.catalina.valves.AccessLogValve"

prefix="localhost_access" suffix=".log"

pattern="common" directory="${jboss.server.home.dir}/log"/>

 

<Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

<!-- Default context parameters -->

<DefaultContext cookies="true" crossContext="true" override="true"/>

 

</Host>

</Engine>

 

<!-- A AJP 1.3 Connector on port 8009 -->

<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"

address="${jboss.bind.address}" port="8009" minProcessors="5"

maxProcessors="75" enableLookups="true" redirectPort="8443"

acceptCount="10" debug="0" connectionTimeout="20000"

useURIValidationHack="false"

protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/>

</Service>

</Server>

</attribute>

<depends>jboss:service=TransactionManager</depends>

</mbean>

 

</server>

The configuration of the Apache side proceeds as it normally would as bundling Tomcat inside of JBoss does not affect the how Apache interacts with Tomcat. For example, a fragment of an httpd.conf configuration to test the See An example EmbeddedTomcatService MBean configuration that supports integration with Apache using the Ajpv13 protocol connector.. setup with a WAR deployed with a context root of "/jbosstest" might look like:

...

LoadModule jk_module libexec/mod_jk.so

AddModule mod_jk.c

<IfModule mod_jk.c>

JkWorkersFile /tmp/workers.properties

JkLogFile /tmp/mod_jk.log

JkLogLevel debug

JkMount /jbosstest/* ajp13

</IfModule>

Other Apache to Tomcat configurations would follow the same pattern. All that would change it the Connector element definition that is placed into the EmbeddedTomcatService MBean configuration.

Using Clustering

As of the JBoss 3.0.1 release, there is support for clustering in the Tomcat embedded service. The steps to setup clustering of Tomcat embedded containers is:

  1. If you are using a load balancer, make sure that your setup uses sticky sessions. This means that if a user that starts a session on node A, all subsequent requests are forwarded to node A as long node A is up and running. For configuration of the Apache webserver sticky sessions see http://www.ubeans.com/tomcat/index.html for details.
  2. Make sure that cluster-service.xml and jbossha-httpsession.sar are in your configuration file set deploy directory, e.g. {JBOSS_HOME}/server/default/deploy. The cluster-service.xml is not included in the default configuration, but can be found in JBOSS_DIST/server/all/deploy. The jbossha-httpsession.sar can be found in the JBOSS_DIST/docs/examples/clustering directory. You also need the jgroups.jar. This can be found in the JBOSS_DIST/server/all/lib directory.
  3. Start JBoss to check if your setup works. Look at the JMX management console ( http://localhost:8080/jmx-console/ ). Find the MBean jboss:service=ClusteredHttpSession. The "StateString" must be "Started". If it is "Stopped" look in the server's logfile.
  4. To enable clustering of your web applications you must mark them as distributable using the servlet 2.3 web.xml descriptor. For example:
    <?xml version="1.0"?>
    <!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    " http://java.sun.com/dtd/web-app_2_3.dtd ">

    <web-app>
    <distributable/>
    ...
    </web-app>
  5. Deploy your war as usual and it should now be clustered.

© 2002-2004 JBoss Inc. All rights reserved.