Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "Jetty/Feature/JNDI"
m |
m |
||
Line 1: | Line 1: | ||
{{Jetty Feature | {{Jetty Feature | ||
| introduction = | | introduction = | ||
− | Jetty supports <code>java:comp/env</code> lookups in | + | Jetty supports <code>java:comp/env</code> lookups in web apps. This is an optional feature and you need to do some setup. However, if you are using the [http://dist.codehaus.org/jetty Hightide] distribution of Jetty, this feature is already fully enabled, so you can skip any setup steps, and just read the section on how to put objects into Jetty's JNDI so that you can retrieve them at runtime. |
| body == Enabling JNDI == | | body == Enabling JNDI == | ||
{{Note|Note: Skip this step if you are using the Hightide distribution of Jetty, because JNDI is automatically enabled.}} | {{Note|Note: Skip this step if you are using the Hightide distribution of Jetty, because JNDI is automatically enabled.}} | ||
− | You can enable JNDI for a particular web app or you can enable it by default for all | + | You can enable JNDI for a particular web app or you can enable it by default for all web apps. In either case, you need to re-define the list of configurations that can apply to a WebAppContext on deployment: |
<source lang="xml"> | <source lang="xml"> | ||
<Array id="plusConfig" type="java.lang.String"> | <Array id="plusConfig" type="java.lang.String"> | ||
Line 20: | Line 20: | ||
</source> | </source> | ||
− | ===Applying JNDI to a Single | + | ===Applying JNDI to a Single Web App=== |
− | To apply this list to a single | + | To apply this list to a single web app, create a context XML file that describes the setup of the particular web app, and instruct it to apply these special configurations on deployment: |
<source lang="xml"> | <source lang="xml"> | ||
Line 44: | Line 44: | ||
</source> | </source> | ||
− | ===Applying JNDI to All | + | ===Applying JNDI to All Web Apps=== |
− | Alternatively, you can apply these configurations to every | + | Alternatively, you can apply these configurations to every web app that you deploy. To do so, edit the <code>$JETTY_HOME/etc/jetty.xml</code> file (or create a new new file and put it on the runline or put it in <code>start.ini</code>) to add: |
<source lang="xml"> | <source lang="xml"> | ||
Line 70: | Line 70: | ||
{{tip|Tip:| | {{tip|Tip:| | ||
− | This example includes the <code>etc/jetty-plus.xml</code> configuration file that configures a WebAppDeployer to deploy all | + | This example includes the <code>etc/jetty-plus.xml</code> configuration file that configures a WebAppDeployer to deploy all web apps in the <code>webapps-plus</code> directory with JNDI. You can modify this file as desired, or merge it with your <code>etc/jetty.xml</code> file.}} |
=== 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 | + | 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: |
<source lang="bash"> | <source lang="bash"> | ||
Line 91: | Line 91: | ||
[[#Configuring env-entrys]] shows you how to set up overrides for <code><env-entry></code> elements in web.xml. [[#Configuring resource-refs and resource-env-refs]] discusses how to configure support resources such as <code>javax.sql.DataSource</code>. | [[#Configuring env-entrys]] shows you how to set up overrides for <code><env-entry></code> elements in web.xml. [[#Configuring resource-refs and resource-env-refs]] discusses how to configure support resources such as <code>javax.sql.DataSource</code>. | ||
− | You can also plug a JTA <code>javax.transaction.UserTransaction</code> implementation into Jetty so that | + | You can also plug a JTA <code>javax.transaction.UserTransaction</code> implementation into Jetty so that web apps can lookup <code>java:comp/UserTransaction</code> to obtain a distributed transaction manager. See [[#Configuring XA Transactions]]. |
You can define your naming resources with three scopes: | You can define your naming resources with three scopes: | ||
Line 99: | Line 99: | ||
# webapp scope–the name is unique to the WebAppContext instance. | # webapp scope–the name is unique to the WebAppContext instance. | ||
− | The section [[#Setting JNDI Entries as Global or Scoped to a | + | The section [[#Setting JNDI Entries as Global or Scoped to a web app]] explains ''scoping'', and shows you how to use it. Essentially, scoping ensures that JNDI bindings from one web app do not interfere with the JNDI bindings of another–unless of course you want them to. |
Line 136: | Line 136: | ||
# context xml file | # context xml file | ||
− | Naming entries defined in a <code>jetty.xml</code> file are scoped at either the JVM level or the Server level. Naming entries in a <code>jetty-env.xml</code> file are scoped to the | + | Naming entries defined in a <code>jetty.xml</code> file are scoped at either the JVM level or the Server level. Naming entries in a <code>jetty-env.xml</code> 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-entrys ==== | ==== Configuring env-entrys ==== | ||
− | Sometimes it is useful to pass configuration information to a | + | 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 <code><env-entry></code>. In such cases, you can use <code>org.eclipse.jetty.plus.jndi.EnvEntry</code>, and even override an entry of the same name in web.xml. |
<source lang="xml"> | <source lang="xml"> | ||
Line 151: | Line 151: | ||
</source> | </source> | ||
− | This example defines a virtual <code><env-entry></code> called <code>mySpecialValue</code> with value <code>4000</code> that is unique within the whole JVM. It is put into JNDI at <code>java:comp/env/mySpecialValue</code> for _every_ | + | This example defines a virtual <code><env-entry></code> called <code>mySpecialValue</code> with value <code>4000</code> that is unique within the whole JVM. It is put into JNDI at <code>java:comp/env/mySpecialValue</code> for _every_ web app deployed. Moreover, the boolean argument indicates that this value overrides an <code>env-entry</code> of the same name in web.xml. If you don't want to override, then omit this argument, or set it to <code>false</code>. |
− | See [[#Setting JNDI Entries as Global or Scoped | + | See [[#Setting JNDI Entries as Global or Scoped]] for information on other scopes. |
The Servlet Specification allows only the following types of object to be bound to an <code>env-entry</code>: | The Servlet Specification allows only the following types of object to be bound to an <code>env-entry</code>: | ||
Line 193: | Line 193: | ||
==== Configuring DataSources ==== | ==== Configuring DataSources ==== | ||
− | Here is an example of configuring a <code>javax.sql.DataSource</code>. Jetty can use any DataSource implementation available on its classpath. In this example, the DataSource is from the [http://db.apache.org/derby Derby] relational database, but you can use any implementation of a <code>javax.sql.DataSource</code>. This example, configures it as scoped to a | + | Here is an example of configuring a <code>javax.sql.DataSource</code>. Jetty can use any DataSource implementation available on its classpath. In this example, the DataSource is from the [http://db.apache.org/derby Derby] relational database, but you can use any implementation of a <code>javax.sql.DataSource</code>. This example, configures it as scoped to a web app with the id of 'wac': |
<source lang="xml"> | <source lang="xml"> | ||
Line 211: | Line 211: | ||
</source> | </source> | ||
− | The code above creates an instance of <code>org.apache.derby.jdbc.EmbeddedDataSource</code>, calls the two setter methods <code>setDatabaseName("test");</code> and <code>setCreateDatabase("create");</code> and binds it into the JNDI scope for the | + | The code above creates an instance of <code>org.apache.derby.jdbc.EmbeddedDataSource</code>, calls the two setter methods <code>setDatabaseName("test");</code> and <code>setCreateDatabase("create");</code> 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 <code>java:comp/env/jdbc/myds</code>. |
To lookup your DataSource in your servlet/filter/etc.: | To lookup your DataSource in your servlet/filter/etc.: | ||
Line 285: | Line 285: | ||
==== Configuring XA Transactions ==== | ==== 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 <code>java:comp/UserTransaction</code> in your | + | 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 <code>java:comp/UserTransaction</code> in your web app. Jetty does not ship with one, but you can plug in the one you prefer. You can configure a transaction manager using the <code>org.eclipse.jetty.plus.jndi.Transaction</code> object in a Jetty config file. The following example configures the [http://www.atomikos.com Atomikos] transaction manager: |
<source lang="xml"> | <source lang="xml"> | ||
Line 379: | Line 379: | ||
This can be useful when you cannot change web.xml but need to link it to a resource in your deployment environment. | 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 | + | === 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 <code>java:comp/env</code>. 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 <code>java:comp/env</code> of any | + | 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 <code>java:comp/env</code>. 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 <code>java:comp/env</code> 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 <code>java:comp/env</code> of the web app in which it is defined. |
The first parameter to the NamingEntry controls the scope. | The first parameter to the NamingEntry controls the scope. | ||
Line 437: | Line 437: | ||
== Examining a Demo Web Application == | == Examining a Demo Web Application == | ||
− | There is a demonstration | + | There is a demonstration web app which sets up examples of all of the JNDI resources discussed so far. |
− | To run this demonstration, you need to download the transaction manager of your choice and [http://db.apache.org/derby Derby]. At the time of writing, the | + | To run this demonstration, you need to download the transaction manager of your choice and [http://db.apache.org/derby Derby]. At the time of writing, the web app has been tested with both [http://jotm.objectweb.org JOTM] and with [http://www.atomikos.com Atomikos] transaction managers. |
=== Building the Demo === | === Building the Demo === | ||
− | The demo | + | The demo web app is included with Jetty [http://dist.codehaus.org/jetty Hightide] distribution. Alternatively, you can build it from sources located in <code>examples/test-jndi-webapp</code>. A <code>README.txt</code> file there explains how to build it, and how to add support for different transaction managers. |
* Run <code>mvn clean install</code> to build it. | * Run <code>mvn clean install</code> to build it. |
Revision as of 17:40, 14 February 2011
Contents
- 1 Introduction
- 2 Feature
- 3 Enabling JNDI =
- 3.1 Applying JNDI to a Single Web App
- 3.2 Applying JNDI to All Web Apps
- 3.3 Adding JNDI Implementation Jars to the Jetty Classpath
- 3.4 BInding Objects into Jetty JNDI
- 3.5 Examining a Demo Web Application
- 3.6 Additional Resources
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 section on how to put objects into Jetty's JNDI so that you can retrieve them at runtime.
Feature
Enabling JNDI =
You can enable JNDI for a particular web app or you can enable it by default for all web apps. In either case, you need to re-define the list of configurations that can apply to a WebAppContext on deployment:
<Array id="plusConfig" type="java.lang.String"> <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item> <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <!-- add --> <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item> <!-- add --> <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> </Array>
Applying JNDI to a Single Web App
To apply this list to a single web app, create a context XML file that describes the setup of the particular web app, and instruct it to apply these special configurations on deployment:
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> <Array id="plusConfig" type="java.lang.String"> <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item> <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <!-- add for JNDI --> <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item> <!-- add for JNDI --> <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> </Array> <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/my-cool-webapp</Set> <Set name="configurationClasses"><Ref id="plusConfig"/></Set> </Configure>
Applying JNDI to All Web Apps
Alternatively, you can apply these configurations to every web app that you deploy. To do so, 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:
<Configure id="Server" class="org.eclipse.jetty.server.Server"> <Call name="setAttribute"> <Arg>org.eclipse.jetty.webapp.configuration</Arg> <Arg> <Array type="java.lang.String"> <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item> <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item> <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item> <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> </Array> </Arg> </Call> </Configure>
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:
java -jar start.jar OPTIONS=plus
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 webapp during execution. Specifically, you can configure support for the following web.xml elements:
<env-entry/> <resource-ref/> <resource-env-ref/>
#Configuring env-entrys shows you how to set up overrides for <env-entry>
elements in web.xml. #Configuring resource-refs and resource-env-refs discusses how to configure support resources such as javax.sql.DataSource
.
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.
You can define your naming resources with three 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 #Setting JNDI Entries as Global or Scoped to a web app explains scoping, and shows you how to use it. Essentially, scoping ensures that JNDI bindings from one web app do not interfere with the JNDI bindings of another–unless of course you want them to.
BInding Objects into Jetty JNDI
You can bind four types of object into Jetty JNDI:
- An ordinary POJO instance.
- A java.naming.Reference instance.
- An object instance that implements the java.naming.Referenceable interface.
- A linkage between a name as referenced in web.xml and as referenced in the environment.
The binding for all of these object types follows the same pattern:
<New class=type of naming entry> <Arg>scope</Arg> <Arg>name to bind as</Arg> <Arg>the object to bind</Arg> </New>
Defining Naming Entries
The type of naming entry
can be:
-
"org.eclipse.jetty.plus.jndi.EnvEntry"
for <env-entry>s. -
"org.eclipse.jetty.plus.jndi.Resource"
for all other type of resources. -
"org.eclipse.jetty.plus.jndi.Transaction"
for a JTA manager. For detailed information, see the #Configuring XA Transactions section. -
"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-entrys
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.
<New class="org.eclipse.jetty.plus.jndi.EnvEntry"> <Arg></Arg> <Arg>mySpecialValue</Arg> <Arg type="java.lang.Integer">4000</Arg> <Arg type="boolean">true</Arg> </New>
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
.
See #Setting JNDI Entries as Global or Scoped for information on other scopes.
The Servlet Specification allows only the following types of object to be bound 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
However, Jetty is a little more flexible and allows you to also bind custom POJOs, javax.naming.Reference's and javax.naming.Referenceable's. Be aware that if you take advantage of this feature, your web application is *not portable*.
To use the EnvEntry
configured above, use code in your servlet/filter/etc., such as:
import javax.naming.InitialContext; InitialContext ic = new InitialContext(); Integer mySpecialValue = (Integer)ic.lookup("java:comp/env/mySpecialValue");
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':
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id="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>
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
.
To lookup your DataSource in your servlet/filter/etc.:
import javax.naming.InitialContext; import javax.sql.DataSource; InitialContext ic = new InitialContext(); DataSource myDS = (DataSource)ic.lookup("java:comp/env/jdbc/myds");
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:
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id='wac'/></Arg> <Arg>jms/connectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?broker.persistent=false</Arg> </New> </Arg> </New> </Configure>
For more information, see ActiveMQ and Jetty Integrating with ActiveMQ.
Configuring Mail
Jetty also provides infrastructure for access to javax.mail.Sessions from within an application:
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="mail" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id="wac"/></Arg> <Arg>mail/Session</Arg> <Arg> <New class="org.eclipse.jetty.jndi.factories.MailSessionReference"> <Set name="user">fred</Set> <Set name="password">OBF:1xmk1w261z0f1w1c1xmq</Set> <Set name="properties"> <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>
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 the original password cannot be recovered, which is necessary for the mail system. {tip}
We will be adding more examples of configuring database datasources (for example, using XAPool and DBCP) and jms connection factories, so check back. Contributions are also welcome.
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, 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:
<New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"> <Arg> <New class="com.atomikos.icatch.jta.J2eeUserTransaction"/> </Arg> </New>
See also the instructions for how to configure JOTM. Contributions of instructions for other transaction managers are welcome.
Configuring Links
The name you set for your NamingEntry should be the same name you use for it in web.xml. For example:
In a context xml file: <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id="wac"/></Arg> <Arg>jdbc/mydatasource</Arg> <Arg> <New class="org.apache.derby.jdbc.EmbeddedDataSource"> <Set name="DatabaseName">test</Set> <Set name="createDatabase">create</Set> </New> </Arg> </New> </Configure>
and in web.xml:
<resource-ref> <res-ref-name>jdbc/mydatasource</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <injection-target> <injection-target-class>com.acme.JNDITest</injection-target-class> <injection-target-name>myDatasource</injection-target-name> </injection-target> </resource-ref>
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:
In a context xml file:
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id="wac"/></Arg> <Arg>jdbc/mydatasource</Arg> <Arg> <New class="org.apache.derby.jdbc.EmbeddedDataSource"> <Set name="DatabaseName">test</Set> <Set name="createDatabase">create</Set> </New> </Arg> </New> </Configure> in a jetty-env.xml file: <source lang="xml"> <New id="map1" class="org.eclipse.jetty.plus.jndi.Link"> <Arg><Ref id='wac'/></Arg> <Arg>jdbc/mydatasource1</Arg> <!-- name in web.xml --> <Arg>jdbc/mydatasource</Arg> <!-- name in container environment --> </New>
and in web.xml:
<resource-ref> <res-ref-name>jdbc/mydatasource1</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <injection-target> <injection-target-class>com.acme.JNDITest</injection-target-class> <injection-target-name>myDatasource</injection-target-name> </injection-target> </resource-ref>
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.
The first parameter to the NamingEntry controls the scope.
The jvm scope is represented by a null parameter:
<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>jms/connectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?broker.persistent=false</Arg> </New> </Arg> </New>
The Server scope is represented by referencing the related Server object:
<Configure id="Server" class="org.eclipse.jetty.Server"> ... <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id="Server"/></Arg> <Arg>jms/connectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?broker.persistent=false</Arg> </New> </Arg> </New> </Configure>
The webapp scope is represented by referencing the related WebAppContext object:
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> ... <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg><Ref id='wac'/></Arg> <Arg>jms/connectionFactory</Arg> <Arg> <New class="org.apache.activemq.ActiveMQConnectionFactory"> <Arg>vm://localhost?broker.persistent=false</Arg> </New> </Arg> </New> </Configure>
As you can see, the most natural configuration 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
Examining a Demo Web Application
There is a demonstration web app which sets up examples of all of the JNDI resources discussed so far.
To run this demonstration, you need to download the transaction manager of your choice and Derby. At the time of writing, the web app has been tested with both JOTM and with Atomikos transaction managers.
Building the Demo
The demo web app is included with Jetty Hightide distribution. Alternatively, you can build it from sources located in examples/test-jndi-webapp
. A README.txt
file there explains how to build it, and how to add support for different transaction managers.
- Run
mvn clean install
to build it. - Edit
contexts/test-jndi.xml
and uncomment one of the transaction manager setups. - Edit
contexts/test-jndi.d/WEB-INF/jetty-env.xml
and uncomment one of the transaction manager setups. - Copy a
derby.jar
to the jettylib/
directory, and also copy all the necessary Jars for the flavor of transaction manager you are using. Instructions for some popular transaction managers are on the wiki at JNDI.
Run the demo:
java -jar start.jar OPTIONS=plus
The URL for the demonstration is at:
http://localhost:8080/test-jndi
Adding Support for a Different Transaction Manager
- Edit the
src/etc/templates/filter.properties
file, and add a new set of token and replacement strings following the pattern established for ATOMIKOS and JOTM. - Edit the
src/etc/templates/jetty-env.xml
file, and add configuration for new transaction manager following the pattern established for the other transaction managers. - Edit the
src/etc/templates/jetty-test-jndi.xml
file, and add configuration for the new transaction manager following the pattern established for the other transaction managers.
Additional Resources
For more information on setting up a JNDI datasource, see How to Configure JNDI Datasource page.
For documentation on how to configure jetty-env.xml, consult the reference guide.