Jump to: navigation, search

Difference between revisions of "Jetty/Feature/JNDI"

< Jetty‎ | Feature
Line 86: Line 86:
 
</source>
 
</source>
  
[[#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|#res-ref|How to configure a resource] 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>.
  
Furthermore, it is possible to plug a JTA <code>javax.transaction.UserTransaction</code> implementation into Jetty so that webapps can lookup <code>java:comp/UserTransaction</code> to obtain a distributed transaction manager. See [Configuring XA Transactions|#tx|How to setup JTA].
+
Furthermore, it is possible to plug a JTA <code>javax.transaction.UserTransaction</code> implementation into Jetty so that webapps can lookup <code>java:comp/UserTransaction</code> to obtain a distributed transaction manager. See [[#Configuring XA Transactions]].
  
 
You can define your naming resources with 3 scopes:
 
You can define your naming resources with 3 scopes:
Line 96: Line 96:
 
# webapp scope - the name is unique to the WebAppContext 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.
+
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.
 
Before we go any further, lets take a look at what kind of things can be bound into JNDI with Jetty.
Line 123: Line 123:
 
* <code>"org.mortbay.jetty.plus.naming.EnvEntry"</code> for <env-entry>s
 
* <code>"org.mortbay.jetty.plus.naming.EnvEntry"</code> for <env-entry>s
 
* <code>"org.mortbay.naming.plus.Resource"</code> for all other type of resources
 
* <code>"org.mortbay.naming.plus.Resource"</code> for all other type of resources
* <code>"org.mortbay.plus.naming.Transaction"</code> for a JTA manager. We'll take a closer look at this in the [[#Configuring_XA_Transactions]] section.
+
* <code>"org.mortbay.plus.naming.Transaction"</code> for a JTA manager. We'll take a closer look at this in the [[#Configuring XA Transactions]] section.
* <code>"org.mortbay.plus.naming.Link"</code> for link between a web.xml resource name and a NamingEntry. See [#Configuring_Links] for more info.
+
* <code>"org.mortbay.plus.naming.Link"</code> 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:
 
There are 3 places in which you can define naming entries:
Line 132: Line 132:
 
# context xml file
 
# context xml file
  
Naming entries defined in a <code>jetty.xml</code> file will generally be scoped at either the jvm level or the Server level. Naming entries in a [jetty-env.xml|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 |ContextDeployer] 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.
+
Naming entries defined in a <code>jetty.xml</code> file will generally be scoped at either the jvm level or the Server level. Naming entries in a <code>jetty-env.xml</code> 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 ===
 
=== Configuring env-entrys ===
Line 148: Line 148:
 
This example will define a virtual <code><env-entry></code> called <code>mySpecialValue</code> with value <code>4000</code> that is unique within the whole jvm. It will be put into JNDI at <code>java:comp/env/mySpecialValue</code> for _every_ webapp deployed. Moreover, the boolean argument indicates that this value should override 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>.
 
This example will define a virtual <code><env-entry></code> called <code>mySpecialValue</code> with value <code>4000</code> that is unique within the whole jvm. It will be put into JNDI at <code>java:comp/env/mySpecialValue</code> for _every_ webapp deployed. Moreover, the boolean argument indicates that this value should override 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 [Global or scoped to a webapp|#global|Global or scoped to a webapp] for more information on other scopes.
+
See [[#Global or scoped to a webapp]] for more information on other scopes.
  
 
Note that the Servlet Specification only allows the following types of object to be bound to an <code>env-entry</code>:
 
Note that the Servlet Specification only allows the following types of object to be bound to an <code>env-entry</code>:
Line 162: Line 162:
 
* java.lang.Boolean
 
* java.lang.Boolean
  
However, Jetty is a little more flexible and will also allow you to bind custom POJOs, [javax.naming.References|http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Reference.html] and [javax.naming.Referenceables|http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Referenceable.html]. Be aware if you take advantage of this feature that your web application will *not be portable*.
+
However, Jetty is a little more flexible and will also allow you to bind custom POJOs, [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Reference.html javax.naming.Reference's] and [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Referenceable.html javax.naming.Referenceable's]. Be aware if you take advantage of this feature that your web application will *not be portable*.
  
 
To use the <code>EnvEntry</code> configured above, use code in your servlet/filter/etc such as:
 
To use the <code>EnvEntry</code> configured above, use code in your servlet/filter/etc such as:
Line 177: Line 177:
 
Any type of resource that you want to refer to in a web.xml file as a <code><resource-ref></code> or <code><resource-env-ref></code> can be configured using the <code>org.mortbay.naming.plus.Resource</code> type of naming entry. You provide the scope, the name of the object (relative to <code>java:comp/env</code>) and a POJO instance or a  javax.naming.Reference instance or javax.naming.Referenceable instance.
 
Any type of resource that you want to refer to in a web.xml file as a <code><resource-ref></code> or <code><resource-env-ref></code> can be configured using the <code>org.mortbay.naming.plus.Resource</code> type of naming entry. You provide the scope, the name of the object (relative to <code>java:comp/env</code>) and a POJO instance or a  javax.naming.Reference instance or javax.naming.Referenceable instance.
  
The [J2EE Specification|http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html] recommends that DataSources are stored in <code>java:comp/env/jdbc</code>, JMS connection factories under <code>java:comp/env/jms</code>, JavaMail connection factories under <code>java:comp/env/mail</code> and URL connection factories under <code>java:comp/env/url</code>. For example:
+
The [http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html J2EE Specification] recommends that DataSources are stored in <code>java:comp/env/jdbc</code>, JMS connection factories under <code>java:comp/env/jms</code>, JavaMail connection factories under <code>java:comp/env/mail</code> and URL connection factories under <code>java:comp/env/url</code>. 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 |
+
|Resource Type || Name in jetty.xml || Environment Lookup
| javax.mail.Session | mail/myMailService | java:comp/env/mail/myMailService |
+
|-
 +
|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
 +
|}
  
h3. Configuring DataSources
+
=== 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|http://db.apache.org/derby] relational database, but you can use any implementation of a <code>javax.sql.DataSource</code>. In this example, we'll configure it as scoped to a webapp with the id of 'wac':
 
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|http://db.apache.org/derby] relational database, but you can use any implementation of a <code>javax.sql.DataSource</code>. In this example, we'll configure it as scoped to a webapp with the id of 'wac':
Line 223: Line 229:
 
There are [more examples|DataSource Examples] of DataSources for various databases [here|DataSource Examples].
 
There are [more examples|DataSource Examples] of DataSources for various databases [here|DataSource Examples].
  
h3. Configuring JMS Queues, Topics and ConnectionFactories
+
=== 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.
 
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.
Line 246: Line 252:
 
There is more information about [ActiveMQ|http://www.activemq.org] and Jetty [here|Integrating with ActiveMQ].
 
There is more information about [ActiveMQ|http://www.activemq.org] and Jetty [here|Integrating with ActiveMQ].
  
h3. Configuring Mail
+
=== Configuring Mail ===
  
 
Jetty also provides infrastructure for providing access to javax.mail.Sessions from within an application:
 
Jetty also provides infrastructure for providing access to javax.mail.Sessions from within an application:
Line 434: Line 440:
  
  
=== Demo Web Application ===
+
== Demo Web Application ==
  
 
There is a demonstration webapp which sets up examples of all of the JNDI resources we've discussed so far.
 
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|http://db.apache.org/derby] . At the time of writing, the webapp has been tested with both [JOTM|http://jotm.objectweb.org] and with [Atomikos|http://www.atomikos.com] transaction managers.
+
In order to run this demonstration, you will need to download the transaction manager of your choice and [http://db.apache.org/derby Derby] . At the time of writing, the webapp has been tested with both [http://jotm.objectweb.org JOTM] and with [http://www.atomikos.com Atomikos] transaction managers.
  
h3. Building the Demo
+
=== Building the Demo ===
  
 
As the demo webapp is not pre-built with the distribution, you first have to build it. It is located in <code>examples/test-jndi-webapp</code>. There is a <code>README.txt</code> file in there which explains how to build it, and how to add support for different transaction managers.
 
As the demo webapp is not pre-built with the distribution, you first have to build it. It is located in <code>examples/test-jndi-webapp</code>. There is a <code>README.txt</code> file in there which explains how to build it, and how to add support for different transaction managers.
Line 447: Line 453:
 
* then edit <code>contexts/test-jndi.xml</code> and uncomment one of the transaction manager setups
 
* then edit <code>contexts/test-jndi.xml</code> and uncomment one of the transaction manager setups
 
* then edit <code>contexts/test-jndi.d/WEB-INF/jetty-env.xml</code> and uncomment one of the transaction manager setups
 
* then edit <code>contexts/test-jndi.d/WEB-INF/jetty-env.xml</code> and uncomment one of the transaction manager setups
* copy a <code>derby.jar</code> to the jetty <code>lib/</code> 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]
+
* copy a <code>derby.jar</code> to the jetty <code>lib/</code> 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
  
 
You run the demo like so:
 
You run the demo like so:
Line 465: Line 471:
 
<code>http://localhost:8080/test-jndi</code>
 
<code>http://localhost:8080/test-jndi</code>
  
 
+
=== Adding Support for a Different Transaction Manager ===
h4. Adding Support for a Different Transaction Manager
+
  
 
# Edit the <code>src/etc/templates/filter.properties</code> file and add a new set of token and replacement strings following the pattern established for ATOMIKOS and JOTM.
 
# Edit the <code>src/etc/templates/filter.properties</code> file and add a new set of token and replacement strings following the pattern established for ATOMIKOS and JOTM.

Revision as of 17:23, 8 June 2010



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:

<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.Configuration</Item>    <!-- add -->
  <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
  <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
</Array>

Now, to apply this to a single webapp, we create a context xml file that describes the setup of that particular webapp 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.Configuration</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>

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:

<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.Configuration</Item>
              <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
              <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item>
          </Array>
      </Arg>
    </Call>
</Configure>
Idea.png
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
Idea.png
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:

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

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:

  1. jvm scope - the name is unique within the jvm
  2. server scope - the name is unique to the Server instance
  3. 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.

What can be bound and general overview

There are 4 types of objects that can be bound into Jetty's JNDI:

The binding for all of these object types generally 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>

The type of naming entry can be:

  • "org.mortbay.jetty.plus.naming.EnvEntry" for <env-entry>s
  • "org.mortbay.naming.plus.Resource" for all other type of resources
  • "org.mortbay.plus.naming.Transaction" for a JTA manager. We'll take a closer look at this in the #Configuring XA Transactions section.
  • "org.mortbay.plus.naming.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:

  1. jetty.xml
  2. WEB-INF/jetty-env.xml
  3. 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.mortbay.jetty.plus.naming.EnvEntry and even configure them to override an entry of the same name in web.xml.

<New class="org.mortbay.jetty.plus.naming.EnvEntry">
  <Arg></Arg>
  <Arg>mySpecialValue</Arg>
  <Arg type="java.lang.Integer">4000</Arg>
  <Arg type="boolean">true</Arg>
</New>

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.

See #Global or scoped to a webapp for more information on other scopes.

Note that the Servlet Specification only allows 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 will also allow you to bind custom POJOs, javax.naming.Reference's and javax.naming.Referenceable's. Be aware if you take advantage of this feature that your web application will *not be 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

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.mortbay.naming.plus.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:


{