Introduction

Jetty supports java:comp/env lookups in web apps. This is an optional feature and you need to do some setup. However, if you are using the Hightide distribution of Jetty, this feature is already fully enabled, so you can skip any setup steps, and just read the sections on how to put objects into Jetty's JNDI so that you can retrieve them at runtime.

Feature

Enabling JNDI

Note:Skip this step if you are using the Hightide distribution of Jetty, because JNDI is automatically enabled.

Quick Setup

If you are using the standard distribution of jetty, and want to enable JNDI for all your webapps, then read this section. If you would like more information, see the Detailed Setup section.

Step1:
Edit the $JETTY_HOME/start.ini file.

Step2:
Modify the Server OPTIONS to include "plus", eg:

OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus

Step3:
Near the bottom of the file, in the section on Configuration files, add the following line after etc/jetty.xml:

etc/jetty-plus.xml

Step4:
Save the file.

You can now start jetty and use JNDI with your webapps. See below for information on how to add entries to the JNDI environment that can be looked up within webapps.

Detailed Setup

Setting up the list of Configurations

When deploying a webapp, jetty has an extensible list of Configurations that are applied to the webapp in a specific order. These Configurations do things like parse web.xml, set up the classpath for the webapp, parse WEB-INF/jetty-web.xml.

To use JNDI with jetty, you need a couple of extra Configurations that do things like reading WEB-INF/jetty-env.xml, setting up a java:comp/env context, and hooking up JNDI entries from the environment into your web app. The listing below shows the 2 extra Configurations in the correct order they must be defined:

This augmented list of Configurations for JNDI is predefined for you in the etc/jetty-plus.xml file.

To have jetty use etc/jetty-plus.xml and therefore enable JNDI for all webapps, edit the $JETTY_HOME/start.ini file, and add the following line in the Configuration section near the bottom of the file:

etc/jetty-plus.xml

Now skip down to the section on Adding JNDI Implementation Jars to the Jetty Classpath.

If you only want to use JNDI with specific web apps, then read on.

Applying JNDI to a Single Web App

If you only have a few webapps that you want to use with JNDI, you can apply the augmented list of Configurations specifically to those webapps. To do that, create a context XML file for each web app, and set up the Configuration classes. Here's an example of how that would look:

Now you're ready for the next step, which is to put the JNDI jars onto jetty's classpath, described in Adding JNDI Implementation Jars to the Jetty Classpath.

Adding JNDI Implementation Jars to the Jetty Classpath

Now that you have the JNDI configuration for the web app(s) set up, you need to ensure that the JNDI implementation Jars are on Jetty's classpath. These jars are optional, so won't be there by default. You add these into the classpath by using startup time OPTIONS.

One way to do this is to supply it on the command line like so:

java -jar start.jar OPTIONS=plus

Another, and more permanent, way of doing this is to edit the $JETTY_HOME/start.ini file and modify the OPTIONS section to include "plus":

OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus

Example Webapps

The Hightide distribution of jetty contains an example webapp to show you how to setup and access JNDI. When running the unmodified hightide distribution, it is available at http://localhost:8080/test-jndi/

Using JNDI

You can now configure naming resources to reference in a web.xml file and access from within the java:comp/env naming environment of the web app during execution. Specifically, you can configure support for the following web.xml elements:

You can also plug a JTA javax.transaction.UserTransaction implementation into Jetty so that web apps can lookup java:comp/UserTransaction to obtain a distributed transaction manager. See Configuring XA Transactions.

"org.eclipse.jetty.plus.jndi.Link" for link between a web.xml resource name and a NamingEntry. For more information, see the Configuring Links section.

You can define naming entries in three places:

jetty.xml

WEB-INF/jetty-env.xml

context xml file

Naming entries defined in a jetty.xml file are scoped at either the JVM level or the Server level. Naming entries in a jetty-env.xml file are scoped to the web app in which the file resides. While you can enter JVM or Server scopes if you choose, we do not recommend doing so. In most cases you define all naming entries that you want visible to a particular Server instance, or to the JVM as a whole in a jetty.xml file. Entries in a context xml file are scoped at the level of the web app to which they apply, although once again, you can supply a less strict scoping level of Server or JVM if you choose.

Configuring env-entries

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

This example defines a virtual env-entry called mySpecialValue with value 4000 that is unique within the whole JVM. It is put into JNDI at java:comp/env/mySpecialValue for _every_ web app deployed. Moreover, the boolean argument indicates that this value overrides an env-entry of the same name in web.xml. If you don't want to override, then omit this argument, or set it to false.

Configuring resource-refs and resource-env-refs

You can configure any type of resource that you want to refer to in a web.xml file as a <resource-ref> or <resource-env-ref>, 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 instance or a javax.naming.Reference instance or javax.naming.Referenceable instance.

The J2EE Specification recommends that DataSources be stored in java:comp/env/jdbc, JMS connection factories under java:comp/env/jms, JavaMail connection factories under java:comp/env/mail and URL connection factories under java:comp/env/url. For example:

Resource Type

Name in jetty.xml

Environment Lookup

javax.sql.DataSource

jdbc/myDB

java:comp/env/jdbc/myDB

javax.jms.QueueConnectionFactory

jms/myQueue

java:comp/env/jms/myQueue

javax.mail.Session

mail/myMailService

java:comp/env/mail/myMailService

Configuring DataSources

Here is an example of configuring a javax.sql.DataSource. Jetty can use any DataSource implementation available on its classpath. In this example, the DataSource is from the Derby relational database, but you can use any implementation of a javax.sql.DataSource. This example, configures it as scoped to a web app with the id of wac:

The code above creates an instance of org.apache.derby.jdbc.EmbeddedDataSource, calls the two setter methods setDatabaseName("test"); and setCreateDatabase("create"); and binds it into the JNDI scope for the web app. If you have the appropriate <resource-ref> setup in your web.xml, then it is available from application lookups as java:comp/env/jdbc/myds.

Careful!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.

Configuring JMS Queues, Topics and ConnectionFactories

Jetty can bind any implementation of the JMS destinations and connection factories. You just need to ensure the implementation Jars are available on Jetty's classpath. Here is an example of binding an ActiveMQ in JVM connection factory:

The setup above creates an instance of the org.eclipse.jetty.jndi.factories.MailSessionReference class, calls its setter methods setUser("fred");, setPassword("OBF:1xmk1w261z0f1w1c1xmq"); to set up the authentication for the mail system, and populates a set of Properties, setting them on the MailSessionReference instance. The result is that an application can look up java:comp/env/mail/Session at runtime and obtain access to a javax.mail.Session that has the necessary configuration to permit it to send email via SMTP.

{tip}
You can set the password to be plain text, or use Jetty's password obfuscation mechanism to make the config file more secure from prying eyes. But you cannot use the other Jetty encryption mechanisms of MD5 and Crypt because then the original password cannot be recovered, which is necessary for the mail system.
{tip}

Configuring XA Transactions

If you want to perform distributed transactions with your resources, you need a transaction manager that supports the JTA interfaces that you can look up as java:comp/UserTransaction in your web app. Jetty does not ship with one as standard, but you can plug in the one you prefer. You can configure a transaction manager using the org.eclipse.jetty.plus.jndi.Transaction object in a Jetty config file. The following example configures the Atomikos transaction manager:

You can refer to it in web.xml by a different name, and link it to the name in your org.eclipse.jetty.plus.jndi.Resource by using an org.eclipse.jetty.plus.jndi.Link type of NamingEntry. For the example above, you can refer to the jdbc/mydatasource resource as jdbc/mydatasource1 as follows:

<Newid="map1"class="org.eclipse.jetty.plus.jndi.Link"><Arg><Refid='wac'/></Arg><Arg>jdbc/mydatasource1</Arg><!-- name in web.xml --><Arg>jdbc/mydatasource</Arg><!-- name in container environment --></New>

This can be useful when you cannot change web.xml but need to link it to a resource in your deployment environment.

Setting JNDI Entries as Global or Scoped

As previously stated, you can control the visibility of your JNDI naming entries within your JVM, Server and WebAppContext instances. Naming entries at the _jvm scope_ are visible by any application code, and are available to bind to java:comp/env. Naming entries at the _Server scope_ do not interfere with entries of the same name in a different Server instance, and are available to bind to java:comp/env of any web apps deployed to that Server instance. Finally, the most specific scope are entries at the _webapp scope_. An entry of this type is only available to bind to java:comp/env of the web app in which it is defined.