JNDI

Enable the plus module in order to be able to use JNDI resources in your webapp. If you already have the annotations module enabled, then it will already be enabled.

If you have extra jars associated with your JNDI resources, eg database drivers etc, that are not located inside your webapp then you should place those jars into your $jetty.base/lib/ext directory. If your base doesn’t already contain this directory, then enable the ext module, and Jetty will create the directory for you and ensure its contents are on the server’s classpath.

You can now declare JNDI resources and reference them within your webapps.

Declaring resources

You must declare the objects you want bound into the environment so that you can then hook them into your webapp via env-entry, resource-ref and resource-env-refs in web.xml, web-fragment.xml or override-web.xml.

You make these declarations in Jetty XML files that are either external or internal to your webapp. A server or context XML file is external to your webapp. The special WEB-INF/jetty-env.xml file is internal to your webapp. See the section on Jetty XML files for more information on how to choose in which XML file to place your declarations.

For now, let’s look at what you declare in the XML file, regardless of its location.

Declaring a JDNI resource to be referenced later in your webapp is accomplished by declaring new instances of the following types:

org.eclipse.jetty.plus.jndi.EnvEntry

Used for env-entry type of entries

org.eclipse.jetty.plus.jndi.Resource

Used for most other type of resources

org.eclipse.jetty.plus.jndi.Transaction

For a JTA manager

org.eclipse.jetty.plus.jndi.Link

For the link between a web.xml resource name and a naming entry

Declarations of each of these types follow a similar pattern:

<New class="org.eclipse.jetty.plus.jndi.xxxx"> (1)
  <Arg><!-- scope --></Arg> (2)
  <Arg><!-- name --></Arg>  (3)
  <Arg><!-- value --></Arg> (4)
</New>
1 Defines a resource to Jetty.
2 Specifies the scope of the resource.
3 Specifies the name of the resource which will be looked up by the webapp relative to the java:comp/env namespace.
4 Specifies the value of the resource.

org.eclipse.jetty.plus.jndi.EnvEntry

Sometimes it is useful to pass configuration information to a webapp at runtime that you either cannot or cannot conveniently code into a web.xml <env-entry>. In such cases, you can use the org.eclipse.jetty.plus.jndi.EnvEntry class, and optionally even override an entry of the same name in web.xml.

Here’s an example that defines the equivalent of an env-entry called mySpecialValue with value 4000 that overrides an <env-entry> declaration of the same name in web.xml:

<New class="org.eclipse.jetty.plus.jndi.EnvEntry"> (1)
  <Arg></Arg> (2)
  <Arg>mySpecialValue</Arg> (3)
  <Arg type="java.lang.Integer">4000</Arg> (4)
  <Arg type="boolean">true</Arg> (5)
</New>
1 Define an EnvEntry that corresponds to an <env-entry>.
2 Scoped at the JVM level.
3 The name of the entry, corresponding to a lookup by the webapp of java:comp/env/mySpecialValue.
4 The value of the entry, in this case the integer value 4000.
5 true means to override the value of an <env-entry> of the same name in web.xml.

Note that if you don’t want to override the web.xml value, simply omit the last argument, or set it to false.

The Servlet Specification allows binding only the following object types to an env-entry:

  • java.lang.String

  • java.lang.Integer

  • java.lang.Float

  • java.lang.Double

  • java.lang.Long

  • java.lang.Short

  • java.lang.Character

  • java.lang.Byte

  • java.lang.Boolean

Jetty is a little more flexible and allows you to also bind:

Be aware that if you take advantage of this feature, your web application is not portable.

org.eclipse.jetty.plus.jndi.Resource

You can configure any type of resource that you want to refer to in web.xml via a resource-ref or resource-env-ref by using the org.eclipse.jetty.plus.jndi.Resource type of naming entry.

You provide the scope, the name of the object (relative to java:comp/env) and a POJO, javax.naming.Reference or javax.naming.Referenceable instance.

Let’s examine how to configure some of the most common types of resources.

DataSources

In this example, we’ll configure a Derby DataSource named jdbc/myds:

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref refid="wac"/></Arg>
    <Arg>jdbc/myds</Arg>
    <Arg>
      <New class="org.apache.derby.jdbc.EmbeddedDataSource">
        <Set name="DatabaseName">test</Set>
        <Set name="createDatabase">create</Set>
      </New>
    </Arg>
  </New>
</Configure>

This would linked into the webapps JNDI namespace via an entry in a web.xml like so:

<resource-ref>
  <res-ref-name>jdbc/myds</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

When configuring Resources, ensure that the type of object you configure matches the type of object you expect to look up in java:comp/env. For database connection factories, this means that the object you register as a Resource must implement the javax.sql.DataSource interface.

Also note that the J2EE Specification recommends storing DataSources relative to jdbc/ and thus looked up by the application as java:comp/env/jdbc/xxx. Eg The Datasource bound in Jetty as jdbc/users would be looked up by the application as java:comp/env/jdbc/users

JMS Queues, Topics and ConnectionFactories

Jetty can bind any implementation of the JMS destinations and connection factories.

Here is an example of binding an ActiveMQ in-JVM connection factory:

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref refid='wac'/></Arg>
    <Arg>jms/connectionFactory</Arg>
    <Arg>
      <New class="org.apache.activemq.ActiveMQConnectionFactory">
        <Arg>vm://localhost?broker.persistent=false</Arg>
      </New>
    </Arg>
  </New>
</Configure>

The corresponding entry in web.xml to bind the ConnectionFactory into the webapp’s JNDI namespace would be:

<resource-ref>
  <res-ref-name>jms/connectionFactory</res-ref-name>
  <res-type>javax.jms.ConnectionFactory</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

The J2EE Specification recommends storing JMS connection factories under jms/. Eg The ConnectionFactory bound in Jetty as jms/inqueue would be looked up by the application as java:comp/env/jms/inqueue.

Mail

To configure access to javax.mail.Session from within a webapp, declare an org.eclipse.jetty.plus.jndi.Resource with an org.eclipse.jetty.jndi.factories.MailSessionReference that will hold the mail configuration and create the instance of the Session when it is referenced:

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref refid="wac"/></Arg>
    <Arg>mail/Session</Arg>
    <Arg>
      <New class="org.eclipse.jetty.jndi.factories.MailSessionReference"> (1)
        <Set name="user">fred</Set> (2)
        <Set name="password">OBF:1xmk1w261z0f1w1c1xmq</Set> (3)
        <Set name="properties"> (4)
          <New class="java.util.Properties">
            <Put name="mail.smtp.host">XXX</Put>
            <Put name="mail.from">me@me</Put>
            <Put name="mail.debug">true</Put>
          </New>
        </Set>
      </New>
    </Arg>
  </New>
</Configure>
1 Use the org.eclipse.jetty.jndi.factories.MailSessionReference class to hold the configuration.
2 Set the username for the mail instance.
3 Set the password for the mail instance - use Jetty’s secure password obfuscation to obscure the password.
4 Set all other applicable properties.

The webapp performs a lookup for java:comp/env/mail/Session at runtime and obtains a javax.mail.Session that has the correct configuration to permit it to send email via SMTP.

Jetty does not provide the javax.mail and javax.activation jars.

Note also that the J2EE Specification recommends storing JavaMail connection factories under mail/. Eg The MailSessionReference bound to jetty as mail/smtp would be looked up by the application as java:comp/env/mail/smtp.

org.eclipse.jetty.plus.jndi.Transaction

To perform distributed transactions with your resources, a transaction manager that supports the JTA interfaces is required. The transaction manager is looked up by the application as java:comp/UserTransaction.

Jetty does not ship with a JTA manager, but does provide the infrastructure to plug in the JTA manager of your choice.

Use the org.eclipse.jetty.plus.jndi.Transaction object in a Jetty XML file to configure the JTA manager.

The following example configures the Atomikos transaction manager:

<New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction">
  <Arg>
    <New class="com.atomikos.icatch.jta.J2eeUserTransaction"/>
  </Arg>
</New>

Jetty will automatically bind this JTA manager to the webapp’s JNDI namespace at java:comp/UserTransaction.

Usually, the name you provide for the org.eclipse.jetty.plus.jndi.Resource is the same name you reference in web.xml. This ensures that the two are linked together and thus accessible to your webapp.

However, if the names cannot be the same, then it is possible to effectively alias one to another using an org.eclipse.jetty.plus.jndi.Link.

Let’s look at an example.

Supposing you have a declaration for a Datasource named jdbc/workforce in a Jetty context XML file, but your web.xml wants to link to a <resource-ref> named jdbc/employees, and you cannot edit the web.xml. You can create a WEB-INF/jetty-env.xml file with an org.eclipse.jetty.plus.jndi.Link that ties together the names jdbc/workforce and jdbc/employees:

The context XML file declares jdbc/workforce:

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">
  <New class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg><Ref refid="wac"/></Arg>
    <Arg>jdbc/workforce</Arg>
    <Arg>
      <New class="org.apache.derby.jdbc.EmbeddedDataSource">
        <Set name="DatabaseName">test</Set>
        <Set name="createDatabase">create</Set>
      </New>
    </Arg>
  </New>
</Configure>

The web.xml refers to it as jdbc/employees:

<resource-ref>
  <res-ref-name>jdbc/employees</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

Create a WEB-INF/jetty-env.xml file with a org.eclipse.jetty.plus.jndi.Link to link these names together:

<New class="org.eclipse.jetty.plus.jndi.Link">
  <Arg><Ref refid='wac'/></Arg>
  <Arg>jdbc/employees</Arg> (1)
  <Arg>jdbc/workforce</Arg>  (2)
</New>
1 The name as referenced in the web.xml file.
2 The name as referenced in the context XML file.

Jetty XML files

You can define naming resources in three places:

Server XML file

Naming resources defined in a server XML file are scoped at either the JVM level or the org.eclipse.jetty.server.Server level. The classes for the resource must be visible at the Jetty container level. If instead the classes for the resource only exist inside your webapp, you must declare it in a WEB-INF/jetty-env.xml file.

Context XML file

Entries in a context XML file should be scoped at the level of the webapp to which they apply (although it is possible to use a less strict scoping level of Server or JVM, but not recommended). As with resources declared in a server XML file, classes associated with the resource must be visible on the container’s classpath.

WEB-INF/jetty-env.xml

Naming resources in a WEB-INF/jetty-env.xml file are scoped to the webapp in which the file resides. While you can enter JVM or Server scopes if you choose, we do not recommend doing so. The resources defined here may use classes from inside your webapp.

Resource scoping

Naming resources within Jetty belong to one of three different scopes, in increasing order of restrictiveness:

JVM scope: The name is unique across the JVM instance, and is visible to all application code. This scope is represented by a null first parameter to the resource declaration. For example:

<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg></Arg>  (1)
  <Arg>jms/connectionFactory</Arg>
  <Arg>
    <New class="org.apache.activemq.ActiveMQConnectionFactory">
       <Arg>vm://localhost?broker.persistent=false</Arg>
    </New>
  </Arg>
</New>
1 Empty first arg equates to JVM scope for the object bound to name jms/connectionFactory.

Server scope: The name is unique to a Server instance, and is only visible to applications associated with that instance. This scope is represented by referencing the Server instance as the first parameter to the resource declaration. For example:

<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg><Ref refid="Server"/></Arg>  (1)
  <Arg>jms/connectionFactory</Arg>
  <Arg>
    <New class="org.apache.activemq.ActiveMQConnectionFactory">
      <Arg>vm://localhost?broker.persistent=false</Arg>
    </New>
  </Arg>
</New>
1 We refer to the id Server which identifies the default org.eclipse.jetty.server.Server instance.

Webapp scope: The name is unique to the org.eclipse.jetty.webapp.WebAppContext instance, and is only visible to that application. This scope is represented by referencing the instance as the first parameter to the resource declaration. For example:

<New class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg><Ref refid='wac'/></Arg> (1)
  <Arg>jms/connectionFactory</Arg>
  <Arg>
    <New class="org.apache.activemq.ActiveMQConnectionFactory">
      <Arg>vm://localhost?broker.persistent=false</Arg>
    </New>
  </Arg>
</New>
1 We refer to an instance of an org.eclipse.jetty.webapp.WebAppContext which has been previously defined.