JNDI

For each specific environment there is a specific Jetty module that you must enable in order to use JNDI resources in your web application:

  • For Jetty Static and Core web applications, the plus module.

  • For Jakarta EE {8,9,10,11} web applications, the correspondent ee{8,9,10,11}-plus module.

If you have already enabled an annotations module suitable for your environment, an appropriate plus module will already have been enabled, and you do not need to explicitly enable a plus module.

If your JNDI resources need extra libraries, for example database driver libraries, that are not located inside your web application, then you must ensure they are on the environment class-path/module-path.

You can enable the ext module for Jetty Core web applications, or the specific ee{8,9,10,11}-ext module for Jakarta EE web applications, and place your extra libraries respectively in $JETTY_BASE/lib/ext or $JETTY_BASE/lib/ee{8,9,10,11}/ext to make them available in the environment class-path/module-path.

You can now define JNDI resources and reference them within your web applications.

Defining resources

JNDI resources are referenced by web application via JNDI names.

For Jakarta EE web applications, the JNDI names must be declared via env-entry, resource-ref and resource-env-refs in web.xml, web-fragment.xml or Jetty’s override-web.xml.

The resources are bound to their JNDI names in Jetty XML files that are either external or internal to your web application.

External Jetty XML files are those used to deploy the web application, as defined in this section.

Internal Jetty XML files are those present inside the web application directory or packaged file, as defined in this section.

For Jakarta EE web applications, the file WEB-INF/jetty-ee{8,9,10,11}-env.xml is processed before other internal Jetty XML files such as WEB-INF/jetty-ee{8,9,10,11}-web.xml, so that JNDI resources can be bound and later possibly processed by WEB-INF/jetty-ee{8,9,10,11}-web.xml.

See the section on Jetty XML files for more information on how to choose in which XML file to place the definitions of your JNDI resources.

The definitions of your JNDI resources are instances of the following types:

org.eclipse.jetty.plus.jndi.EnvEntry

Used for env-entry resources in web.xml.

org.eclipse.jetty.plus.jndi.Resource

Used for other type of resources.

org.eclipse.jetty.plus.jndi.Transaction
org.eclipse.jetty.ee{8,9,10,11}.plus.jndi.Transaction

Used for a JTA transaction manager.

org.eclipse.jetty.plus.jndi.Link

Used for linking between a web.xml resource name and a naming entry.

Definitions of each of these types follow this pattern:

<New class="org.eclipse.jetty.plus.jndi.<resource-class>"> (1)
  <Arg><!-- scope --></Arg> (2)
  <Arg><!-- name --></Arg>  (3)
  <Arg><!-- value --></Arg> (4)
</New>
1 Defines a resource of the given class to Jetty.
2 Specifies the scope of the resource.
3 Specifies the name of the resource which will be looked up by the web application relative to the java:comp/ or 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 web application 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 Defines an EnvEntry that corresponds to an <env-entry> in web.xml.
2 Scoped at the JVM level.
3 The name of the entry, corresponding to a lookup by the web application 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:

  • Instances of any object.

  • javax.naming.Reference instances.

  • javax.naming.Referenceable instances.

Be aware that if you take advantage of this flexibility, your web application is not portable across Servlet containers.

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 either the resource, or a javax.naming.Reference or a javax.naming.Referenceable instance.

DataSources

This example configures a Derby DataSource named jdbc/myds:

<Configure id="wac" class="org.eclipse.jetty.ee11.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 be linked into the web application’s 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 from 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 Jakarta specification recommends storing DataSources relative to jdbc/ and thus looked up by the web application as java:comp/env/jdbc/<datasource-name>.

For example, the Datasource bound in Jetty as jdbc/users would be looked up by the web 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.ee11.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 web application’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 Jakarta specification recommends storing JMS connection factories under jms/.

For example, 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 jakarta.mail.Session from within a web application, define an org.eclipse.jetty.plus.jndi.Resource with an org.eclipse.jetty.ee{8,9,10,11}.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.ee11.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.ee11.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.ee11.factories.MailSessionReference class to hold the configuration.
2 Set the username for the mail instance.
3 Set the password for the mail instance — use the Jetty Password tool to obfuscate the password.
4 Set all other applicable properties.

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

Note also that the Jakarta specification recommends storing Jakarta Mail connection factories under mail/.

For example, the MailSessionReference bound to jetty as mail/smtp would be looked up by the web application as java:comp/env/mail/smtp.

Jetty does not provide the jakarta.mail and jakarta.activation libraries.

org.eclipse.jetty.plus.jndi.Transaction

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

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

If the JTA implementation of jakarta.transaction.UserTransaction implements javax.naming.Reference, then you should use the org.eclipse.jetty.plus.jndi.Transaction object in a Jetty XML file to register it in JNDI:

<New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction">
  <Arg><Property name="environment" default="ee11"/></Arg> (1)
  <Arg>
    <New class="org.acme.jta.MyUserTransactionReference" /> (2)
  </Arg>
</New>
1 The scope of the resource.
2 The transaction manager instance implementing jakarta.transaction.UserTransaction and javax.naming.Reference.

If your JTA implementation of UserTransaction does not implement javax.naming.Reference, then you should use the Jakarta specific Jetty class to register it in JNDI:

<New id="tx" class="org.eclipse.jetty.ee11.plus.jndi.Transaction">
  <Arg><Property name="environment" default="ee11"/></Arg> (1)
  <Arg>
    <New class="org.acme.jta.MyUserTransaction" /> (2)
  </Arg>
</New>
1 The scope of the resource.
2 The transaction manager instance implementing jakarta.transaction.UserTransaction.

Jetty will automatically bind this transaction manager to the web application’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 web application.

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.

Suppose you have a definition 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-ee{8,9,10,11}-env.xml file with an org.eclipse.jetty.plus.jndi.Link that ties together the names jdbc/workforce and jdbc/employees:

The Jetty Context XML file defines jdbc/workforce:

<Configure id="wac" class="org.eclipse.jetty.ee11.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-ee{8,9,10,11}-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 Jetty Context XML file.

Jetty XML files

You can define naming resources in three places:

Server XML file

Resources defined in a server XML file are scoped at the JVM, org.eclipse.jetty.server.Server or environment level. Note that the classes for the resource must be accessible at the time that the XML is processed.

For example, environment resources that depend on an external library should be defined in an XML file that is processed after the environment class-path has been properly configured. This can be achieved by using the ee{8,9,10,11}-ext module, with the external library in the $JETTY_BASE/lib/ee{8,9,10,11}/ext/ directory, or with a custom module that contains an [environment] clause and a [lib] clause.

Context XML file

Resources defined in a context XML file should be scoped at the level of the web application to which they apply (it is possible to use a less strict scoping level of Server or JVM, but not recommended). As the Context XML file executes before the web application classes are available, the classes for your resource must be external to the web application, either on the container or on environment class-path.

WEB-INF/jetty-ee{8,9,10,11}-env.xml

Resources defined in a WEB-INF/jetty-ee{8,9,10,11}-env.xml file are scoped to the web application in which the file resides. The resources defined by this file may use classes from inside your web application.

WEB-INF/jetty-ee{8,9,10,11}-web.xml

Resources defined in a WEB-INF/jetty-ee{8,9,10,11}-web.xml file are scoped to the web application in which the file resides. The resources defined by this file may use classes from inside your web application. This file is processed after WEB-INF/jetty-ee{8,9,10,11}-env.xml.

Resource scoping

Resources within Jetty are defined in different scopes, in increasing order of restrictiveness:

JVM scope

The resource 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 definition. 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 The scope is null or the empty string to indicate the JVM scope for the resource.
Environment scope

The resource is unique within a Jetty environment. The scope is represented by referencing the name of the environment as the first parameter to the resource definition. For example:

<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg>ee11</Arg>  (1)
  <Arg>jms/connectionFactory</Arg>
  <Arg>
    <New class="org.apache.activemq.ActiveMQConnectionFactory">
      <Arg>vm://localhost?broker.persistent=false</Arg>
    </New>
  </Arg>
</New>
1 The scope is the name of the environment to indicate the environment scope for the resource.
Web application scope

The resource is unique to the org.eclipse.jetty.ee{8,9,10,11}.webapp.WebAppContext instance, and is only visible to that application. The scope is represented by referencing the context instance as the first parameter to the resource definition. 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 The scope is the org.eclipse.jetty.ee{8,9,10,11}.webapp.WebAppContext instance, to indicate the web application scope for the resource.