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

+

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

{tip}

{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. Note that the other Jetty encryption mechanisms of MD5 and Crypt cannot be used as the original password cannot be recovered, which is necessary for the mail system.

+

You can set the password to be plain text, or use Jetty's [[Jetty/Howto/password obfuscation]] mechanism to make the config file more secure from prying eyes. Note that the other Jetty encryption mechanisms of MD5 and Crypt cannot be used as the original password cannot be recovered, which is necessary for the mail system.

{tip}

{tip}

Line 301:

Line 301:

In a context xml file:

In a context xml file:

−

<Configure id='wac' class="org.mortbay.jetty.webapp.WebAppContext">

+

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">

...

...

<New id="myds" class="org.eclipse.jetty.plus.jndi.Resource">

<New id="myds" class="org.eclipse.jetty.plus.jndi.Resource">

Line 335:

Line 335:

<source lang="xml">

<source lang="xml">

−

<Configure id='wac' class="org.mortbay.jetty.webapp.WebAppContext">

+

<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext">

...

...

<New id="myds" class="org.eclipse.jetty.plus.jndi.Resource">

<New id="myds" class="org.eclipse.jetty.plus.jndi.Resource">

Line 394:

Line 394:

The Server scope is represented by referencing the related Server object:

The Server scope is represented by referencing the related Server object:

<source lang="xml">

<source lang="xml">

−

<Configure id="Server" class="org.mortbay.jetty.Server">

+

<Configure id="Server" class="org.eclipse.jetty.Server">

...

...

<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">

<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">

Line 410:

Line 410:

The webapp scope is represented by referencing the related WebAppContext object:

The webapp scope is represented by referencing the related WebAppContext object:

Introduction

Jetty supports java:comp/env lookups in webapps. This is an optional feature, and as such some setup needs to be done. However, if you're using the [Hightide] distribution of jetty, then this feature is already fully enabled for you, so you can skip any setup steps, and read the section on how to put objects into jetty's JNDI so that you can retrieve them at runtime.

Feature

Setup

Deployment-time configuration

Skip this step if you are using the Hightide distribution of jetty as JNDI is automatically enabled for you. For non-Hightide distributions, you may enable JNDI either for a particular web app or you can enable it by default for all webapps. In either case, we need to re-define the list of configurations that can be applied to a WebAppContext on deployment:

Alternatively, we could apply these configurations to every webapp that is deployed. To do that, we edit the $JETTY_HOME/etc/jetty.xml file (or create a new new file and put it on the runline or put it in start.ini) to add:

Tip:We have included the etc/jetty-plus.xml configuration file that configures a WebAppDeployer to deploy all webapps in the webapps-plus directory with JNDI. You can modify this file as desired, or merge it with your etc/jetty.xml file.

Classpath jars

Now that we have the JNDI configuration for the webapp(s) set up, we need to ensure that the JNDI implementation jars are on jetty's classpath. These jars are optional, so won't be there by default. We add these into the classpath by using startup time OPTIONS:

java -jar start.jar OPTIONS=plus

Tip:If you prefer, you can edit the start.ini file and add "plus" to the default OPTIONS to lessen the verbosity of the runline.

You may now configure naming resources that can be referenced in a web.xml file and accessed from within the java:comp/env naming environment of the webapp during execution. Specifically, you may configure support for the following web.xml elements:

Furthermore, it is possible to plug a JTA javax.transaction.UserTransaction implementation into Jetty so that webapps can lookup java:comp/UserTransaction to obtain a distributed transaction manager. See #Configuring XA Transactions.

You can define your naming resources with 3 scopes:

jvm scope - the name is unique within the jvm

server scope - the name is unique to the Server instance

webapp scope - the name is unique to the WebAppContext instance

The section #Global or scoped to a webapp explains what scoping is, and shows you how to use it. Essentially, scoping ensures that JNDI bindings from one webapp do not interfere with the JNDI bindings of another - unless of course you wish them to.

Before we go any further, lets take a look at what kind of things can be bound into JNDI with Jetty.

"org.eclipse.jetty.plus.jndi.Link" for link between a web.xml resource name and a NamingEntry. See [#Configuring Links] for more info.

There are 3 places in which you can define naming entries:

jetty.xml

WEB-INF/jetty-env.xml

context xml file

Naming entries defined in a jetty.xml file will generally be scoped at either the jvm level or the Server level. Naming entries in a jetty-env.xml file will generally be scoped to the webapp in which the file resides, although you are able to enter jvm or Server scopes if you wish, that is not really recommended. In most cases you will 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 will generally be scoped at the level of the webapp to which it applies, although once again, you can supply a less strict scoping level of Server or JVM if you want.

Configuring env-entrys

Sometimes it is useful to be able to pass configuration information to a webapp at runtime that either cannot be or is not convenient to be coded into a web.xml <env-entry>. In this case, you can use org.eclipse.jetty.plus.naming.EnvEntry and even configure them to override an entry of the same name in web.xml.

This example will define a virtual <env-entry> called mySpecialValue with value 4000 that is unique within the whole jvm. It will be put into JNDI at java:comp/env/mySpecialValue for _every_ webapp deployed. Moreover, the boolean argument indicates that this value should override 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

Any type of resource that you want to refer to in a web.xml file as a <resource-ref> or <resource-env-ref> can be configured 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 are 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

Lets look at an example of configuring a javax.sql.DataSource. Jetty can use any DataSource implementation available on it's classpath. In our example, we'll use a DataSource from the Derby relational database, but you can use any implementation of a javax.sql.DataSource. In this example, we'll configure it as scoped to a webapp with the id of 'wac':

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

Careful!When configuring Resources, you need to ensure that the type of object you configure matches the type of object you expect to lookup 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 is able to bind any implementation of the JMS destinations and connection factories. You just need to ensure the implementation jars are available on Jetty's classpath.

The setup above creates an instance of the org.eclipse.jetty.jndi.factories.MailSessionReference class, calls it's setter methods setUser("fred");, setPassword("OBF:1xmk1w261z0f1w1c1xmq"); to set up the authentication for the mail system, then populates a set of Properties, setting them on the MailSessionReference instance. The result of this is that an application can lookup 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 Jetty/Howto/password obfuscation mechanism to make the config file more secure from prying eyes. Note that the other Jetty encryption mechanisms of MD5 and Crypt cannot be used as the original password cannot be recovered, which is necessary for the mail system.
{tip}

We will be adding more examples of configuring database datasources (eg using XAPool and DBCP) and jms connection factories, so check back regularly. Contributions are also welcome.

Configuring XA Transactions

If you want to be able to perform distributed transactions with your resources, you will need a transaction manager that supports the JTA interfaces that you can lookup as java:comp/UserTransaction in your webapp. Jetty does not ship with one, rather you may plug in the one of your preference. You can configure the one of your choice using the org.eclipse.jetty.plus.jndi.Transaction object in a jetty config file. In the following example, we will configure the Atomikos transaction manager:

If you wish, 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, we could refer to the jdbc/mydatasource resource as jdbc/mydatasource1 by doing:

In a context xml file:

<Configureid='wac'class="org.eclipse.jetty.webapp.WebAppContext">
...
<Newid="myds"class="org.eclipse.jetty.plus.jndi.Resource"><Arg><Refid="wac"/></Arg><Arg>jdbc/mydatasource</Arg><Arg><Newclass="org.apache.derby.jdbc.EmbeddedDataSource"><Setname="DatabaseName">test</Set><Setname="createDatabase">create</Set></New></Arg></New></Configure>
in a jetty-env.xml file:
<sourcelang="xml"><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.

Global or scoped to a webapp

As we said before, 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 be bound to java:comp/env. Naming entries at the _Server scope_ will not interfere with entries of the same name in a different Server instance, and are avilable to be bound to java:comp/env of any webapps deployed to that Server instance. Finally, the most specific scope are entries at the _webapp scope_. These are only available to be bound to java:comp/env of the webapp in which it is defined.

As you can see, the most natural config files in which to declare naming entries of each scope are:

etc/jetty.xml - jvm or Server scope

WEB-INF/jetty-env.xml or a context xml file - webapp scope

Demo Web Application

There is a demonstration webapp which sets up examples of all of the JNDI resources we've discussed so far.

In order to run this demonstration, you will need to download the transaction manager of your choice and Derby . At the time of writing, the webapp has been tested with both JOTM and with Atomikos transaction managers.

Building the Demo

As the demo webapp is not pre-built with the distribution, you first have to build it. It is located in examples/test-jndi-webapp. There is a README.txt file in there which explains how to build it, and how to add support for different transaction managers.

run mvn clean install to build it

then edit contexts/test-jndi.xml and uncomment one of the transaction manager setups

then edit contexts/test-jndi.d/WEB-INF/jetty-env.xml and uncomment one of the transaction manager setups

copy a derby.jar to the jetty lib/ directory, as well as copy all the necessary jars for the flavour of transaction manager you are using. There are instructions for some of the popular transaction managers on the wiki at JNDI