Web container configuration : use of jboss-web.xml

Author:Scott Stark <Scott.Stark@jboss.org>

What is jboss-web.xml?

To deploy your web application, you have to specify (nearly) everything about its setup using the standard web.xml descriptor. This file is bundled in the war archive in the WEB-INF directory. The content and syntax of this file in specified in the servlet2.2 specification.

An important point is that the specification does not allow you to add vendor-specific configuration in this file. While the web.xml is sufficient for most applications, there may be cases where you want to add JBoss-specific information in your deployment descriptor. This can be done by providing another file named jboss-web.xml in the WEB-INF directory.

The following sections will cover most common uses of the jboss-web.xml file. If you want to know all the details, you can get the DTD for jboss-web.dtd in the file section of the manual. A graphical view of the DTD is given in Figure 7.2

Figure 7.2. The jboss-web.xml DTD

Declaring Resource References

Resource references are links to resource factory bindings. They allow a servlet/JSP page developer to define a name relative to the ENC that does not depend on the deployment time binding of the resource. The jboss-web.xml descriptor maps from the developer defined resource name to the actual JNDI binding of the resource factory as it was configured in the deployment environment. An example web.xml descriptor that references JDBC, Mail and JMS resources and the corresponding jboss-web.xml descriptor is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>
    <servlet>
        <servlet-name>AServlet</servlet-name>
        <servlet-class>AServlet</servlet-class>
    </servlet>

    <!-- JDBC DataSources (java:comp/env/jdbc) -->
    <resource-ref>
        <description>The default DS</description>
        <res-ref-name>jdbc/DefaultDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    <!-- JavaMail Connection Factories (java:comp/env/mail) -->
    <resource-ref>
        <description>Default Mail</description>
        <res-ref-name>mail/DefaultMail</res-ref-name>
        <res-type>javax.mail.Session</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    <!-- JMS Connection Factories (java:comp/env/jms) -->
    <resource-ref>
        <description>Default QueueFactory</description>
        <res-ref-name>jms/QueFactory</res-ref-name>
        <res-type>javax.jms.QueueConnectionFactory</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

</web-app>

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <resource-ref>
        <res-ref-name>jdbc/DefaultDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <jndi-name>java:/DefaultDS</jndi-name>
    </resource-ref>
    <resource-ref>
        <res-ref-name>mail/DefaultMail</res-ref-name>
        <res-type>javax.mail.Session</res-type>
        <jndi-name>java:/Mail</jndi-name>
    </resource-ref>
    <resource-ref>
        <res-ref-name>jms/QueFactory</res-ref-name>
        <res-type>javax.jms.QueueConnectionFactory</res-type>
        <jndi-name>QueueConnectionFactory</jndi-name>
    </resource-ref>
</jboss-web>

Declaring an EJB reference

An EJB reference (see servlet2.2 specification, 9.9, p45) is when a servlet wants to call methods on a bean B. This call will look like this:.

public class AServlet extends HttpServlet
{
   ...
   protected void service(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException
   {
      ...
      InitialContext ctx = new InitialContext();  
      BHome home = (BHome) ctx.lookup("java:comp/env/ejb/myBean");
      B bean = home.create(pk);
      ...
    }
}

To be allowed this call, the servlet must declare a reference to the ejb its using in the its deployment descriptor. This is done by an <ejb-ref> tag in the web.xml file. Two types of references exist; internal and external.

Internal EJB reference

An EJB reference is called internal when the servlet is in the same application unit as the bean B. This means that the servlet and ejb is physically packaged in the same ear. In this case, you must provide the <ejb-link> tag, and its value must match the <ejb-name> of bean B. You don't have to provide anything in the jboss-web.xml file. Your web.xml file will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>AServlet</servlet-name>
        <servlet-class>AServlet</servlet-class>
    </servlet>

    <ejb-ref>
        <ejb-ref-name>ejb/BHome</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>BHome</home>
        <remote>B</remote>
        <ejb-link>Bean B</ejb-link>
    </ejb-ref>

</web-app>

Note that this only works if the ejb is using the default binding of its BHome interface which means the ejb-jar in which B is deployed does not use a jboss.xml descriptor to change the default binding. If B does change the default location of its JNDI binding, then the bean needs to be treated as an external bean as described in the next section.

External EJB reference

An EJB reference is called external when the bean B comes from another application unit, which may even be deployed on another server. It also refers to non-standard bindings of EJBs into JNDI in the same application unit. In this case, you cannot rely on the standard <ejb-link> tag in web.xml since there the beans are not covered in the same file. Instead, you must provide the full JNDI name of the bean B in jboss-web.xml. A full name is of the form:

protocol://host:1234/name/in/other/server Note that the <ejb-ref-name> tags in the 2 xml files must match.

Here is an example web.xml and jboss-web.xml with external EJB references:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>AServlet</servlet-name>
        <servlet-class>AServlet</servlet-class>
    </servlet>

    <ejb-ref>
        <ejb-ref-name>ejb/BHome</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>BHome</home>
        <remote>B</remote>
    </ejb-ref>
    <ejb-ref>
        <ejb-ref-name>ejb/RemoteBHome</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>BHome</home>
        <remote>B</remote>
    </ejb-ref>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <!-- A reference to an EJB in the same server with a custom JNDI binding -->
    <ejb-ref>
        <ejb-ref-name>ejb/BHome</ejb-ref-name>
        <jndi-name>someapp/ejbs/beanB</jndi-name>
    </ejb-ref>
    <!-- A reference to an EJB in an external server -->
    <ejb-ref>
        <ejb-ref-name>ejb/RemoteBHome</ejb-ref-name>
        <jndi-name>jnp://otherserver/application/beanB</jndi-name>
    </ejb-ref>
</jboss-web>

IMPORTANT NOTE: this will tell jboss where to look for bean B. You also have to tell jboss what bean B is: in case of an external ejb-reference to another application be sure to include bean B's home and remote interface in servlet war.

Declaring the Security Domain

The final element in the jboss-web.xml descriptor is the security-domain. This defines the JNDI name of the security manager implementation that should be used to perform authentication and authorization of web clients. This element only works with web containers that have been integrated into the JBoss server using the org.jboss.web.AbstractWebContainer integration point and are using its security interface. Currently both the contributed Tomcat and Jetty web containers support this. An example jboss-web with a security-domain element is:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <!-- Use the JaasSecurityMgr other security domain for authentication
      and authorization of secured web content.
     -->
    <security-domain>java:/jaas/other</security-domain>
</jboss-web>

See the JAAS HowTo and the JBossSX chapter for details on setting up security.