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 (Replace <Ref id=...> with <Ref refid=...>) |
|||
(47 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{Jetty Feature | {{Jetty Feature | ||
− | | introduction = | + | |introduction= |
− | + | ||
− | | | + | {{Jetty Redirect|http://www.eclipse.org/jetty/documentation/current/jndi.html}} |
− | + | 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://repo1.maven.org/maven2/org/mortbay/jetty/jetty-hightide 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. | |
− | === | + | |body= |
+ | ==Enabling JNDI== | ||
+ | |||
+ | {{Note|Note:|Skip this step if you are using the [http://repo1.maven.org/maven1/org/mortbay/jetty/jetty-hightide 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: | ||
+ | <source lang="bash"> | ||
+ | OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus | ||
+ | </source> | ||
+ | |||
+ | Step3: | ||
+ | Near the bottom of the file, in the section on Configuration files, add the following line after ''etc/jetty.xml'': | ||
+ | |||
+ | <source lang="bash"> | ||
+ | etc/jetty-plus.xml | ||
+ | </source> | ||
+ | |||
+ | 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 [http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/webapp/Configuration.html 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: | ||
− | |||
<source lang="xml"> | <source lang="xml"> | ||
<Array id="plusConfig" type="java.lang.String"> | <Array id="plusConfig" type="java.lang.String"> | ||
Line 16: | Line 48: | ||
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item> | <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item> | ||
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item> | <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item> | ||
− | <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <!-- add --> | + | <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <!-- add for jndi --> |
− | <Item>org.eclipse.jetty.plus.webapp. | + | <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item> <!-- add for jndi --> |
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> | <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> | ||
− | <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> | + | <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> <!-- not needed for jetty-8 --> |
</Array> | </Array> | ||
</source> | </source> | ||
− | Now, to apply | + | This augmented list of Configurations for JNDI is predefined for you in the <code>etc/jetty-plus.xml</code> file. |
+ | |||
+ | To have jetty use <code>etc/jetty-plus.xml</code> and therefore enable JNDI for all webapps, edit the <code>$JETTY_HOME/start.ini file</code>, and add the following line in the Configuration section near the bottom of the file: | ||
+ | |||
+ | <source lang="bash"> | ||
+ | etc/jetty-plus.xml | ||
+ | </source> | ||
+ | |||
+ | 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: | ||
+ | |||
<source lang="xml"> | <source lang="xml"> | ||
<Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> | ||
Line 33: | Line 81: | ||
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</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.EnvConfiguration</Item> <!-- add for JNDI --> | ||
− | <Item>org.eclipse.jetty.plus.webapp. | + | <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item> <!-- add for JNDI --> |
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> | <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item> | ||
<Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> | <Item>org.eclipse.jetty.webapp.TagLibConfiguration</Item> | ||
Line 39: | Line 87: | ||
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/my-cool-webapp</Set> | <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/my-cool-webapp</Set> | ||
− | <Set name="configurationClasses"><Ref | + | <Set name="configurationClasses"><Ref refid="plusConfig"/></Set> |
</Configure> | </Configure> | ||
</source> | </source> | ||
− | + | 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: | |
<source lang="bash"> | <source lang="bash"> | ||
Line 77: | Line 105: | ||
</source> | </source> | ||
− | + | Another, and more permanent, way of doing this is to edit the <code>$JETTY_HOME/start.ini</code> file and modify the OPTIONS section to include "plus": | |
− | You | + | |
+ | |||
+ | <source lang="bash"> | ||
+ | OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus | ||
+ | </source> | ||
+ | |||
+ | === Example Webapps === | ||
+ | |||
+ | The [http://repo1.maven.org/maven1/org/mortbay/jetty/jetty-hightide 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/ | ||
+ | |||
+ | The source for this webapp can be found on jetty @ codehaus: | ||
+ | |||
+ | jetty-7: http://git.codehaus.org/gitweb.cgi?p=jetty-project.git;a=tree;f=test-wars/test-jndi-webapp;h=52f283b8dbc3c9e86a4575e80c06a9cbea9816df;hb=refs/heads/master | ||
+ | |||
+ | jetty-8: http://git.codehaus.org/gitweb.cgi?p=jetty-project.git;a=tree;f=test-wars/test-jndi-webapp;h=be7ff6136bfdbc348f3072e3bb0af8ed79b05ac0;hb=refs/heads/jetty-8 | ||
+ | |||
+ | |||
+ | == Using JNDI == | ||
+ | You can now configure naming resources to reference in a <code>web.xml</code> file and access from within the <code>java:comp/env</code> naming environment of the web app during execution. Specifically, you can configure support for the following <code>web.xml</code> elements: | ||
<source lang="xml"> | <source lang="xml"> | ||
Line 86: | Line 132: | ||
</source> | </source> | ||
− | [[#Configuring env- | + | [[#Configuring env-entries|Configuring env-entries]] shows you how to set up overrides for <code><env-entry></code> elements in <code>web.xml</code>. [[#Configuring resource-refs and resource-env-refs|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 web apps can lookup <code>java:comp/UserTransaction</code> to obtain a distributed transaction manager. See [[#Configuring XA Transactions|Configuring XA Transactions]]. | |
− | You can define your naming resources with | + | You can define your naming resources with three scopes: |
− | # jvm | + | # jvm scope–the name is unique within the JVM. |
− | # server | + | # server scope–the name is unique to the Server instance. |
− | # webapp | + | # webapp scope–the name is unique to the WebAppContext instance. |
− | The section [[#Global or | + | The section [[#Setting JNDI Entries as Global or Scoped|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 [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Reference.html java.naming.Reference] instance. |
− | * | + | * An object instance that implements the [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Referenceable.html java.naming.Referenceable] interface. |
− | * | + | * A link between a name as referenced in <code>web.xml</code> and as referenced in the environment. |
− | The binding for all of these object types | + | The binding for all of these object types follows the same pattern: |
<source lang="xml"> | <source lang="xml"> | ||
Line 118: | Line 163: | ||
</New> | </New> | ||
</source> | </source> | ||
+ | |||
+ | ==== Defining Naming Entries ==== | ||
The <code>type of naming entry</code> can be: | The <code>type of naming entry</code> can be: | ||
− | * <code>"org. | + | * <code>"org.eclipse.jetty.plus.jndi.EnvEntry"</code> for <env-entry>s. |
− | * <code>"org. | + | * <code>"org.eclipse.jetty.plus.jndi.Resource"</code> for all other type of resources. |
− | * <code>"org. | + | * <code>"org.eclipse.jetty.plus.jndi.Transaction"</code> for a JTA manager. For detailed information, see the [[#Configuring XA Transactions|Configuring XA Transactions]] section. |
− | * <code>"org. | + | * <code>"org.eclipse.jetty.plus.jndi.Link"</code> for link between a <code>web.xml</code> resource name and a NamingEntry. For more information, see the [[#Configuring Links|Configuring Links]] section. |
− | + | You can define naming entries in three places: | |
# <code>jetty.xml</code> | # <code>jetty.xml</code> | ||
Line 132: | Line 179: | ||
# context xml file | # context xml file | ||
− | Naming entries defined in a <code>jetty.xml</code> 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 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 <code>jetty.xml</code> 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 <code>web.xml</code> <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 <code>web.xml</code>. | |
− | Sometimes it is useful | + | |
<source lang="xml"> | <source lang="xml"> | ||
− | <New class="org. | + | <New class="org.eclipse.jetty.plus.jndi.EnvEntry"> |
<Arg></Arg> | <Arg></Arg> | ||
<Arg>mySpecialValue</Arg> | <Arg>mySpecialValue</Arg> | ||
Line 146: | Line 194: | ||
</source> | </source> | ||
− | This example | + | 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 <code>web.xml</code>. If you don't want to override, then omit this argument, or set it to <code>false</code>. |
− | See [[#Global or | + | See [[#Setting JNDI Entries as Global or Scoped|Setting JNDI Entries as Global or Scoped]] for information on other scopes. |
− | + | The Servlet Specification allows binding only the following object types to an <code>env-entry</code>: | |
* java.lang.String | * java.lang.String | ||
Line 162: | Line 210: | ||
* java.lang.Boolean | * java.lang.Boolean | ||
− | However, Jetty is a little more flexible and | + | However, Jetty is a little more flexible and allows you to also bind custom POJOs, [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Reference.html javax.naming.References] and [http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/Referenceable.html javax.naming.Referenceables]. Be aware that if you take advantage of this feature, your web application is *not portable*. |
− | To use the <code> | + | To use the <code>env-entry</code> configured above, use code in your servlet/filter/etc., such as: |
<source lang="java"> | <source lang="java"> | ||
Line 173: | Line 221: | ||
</source> | </source> | ||
− | === Configuring resource-refs and resource-env-refs === | + | ==== Configuring resource-refs and resource-env-refs ==== |
− | + | You can configure any type of resource that you want to refer to in a <code>web.xml</code> file as a <code><resource-ref></code> or <code><resource-env-ref></code>, using the <code>org.eclipse.jetty.plus.jndi.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 <code>javax.naming.Reference</code> instance or <code>javax.naming.Referenceable</code> instance. | |
− | The [http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html J2EE Specification] recommends that DataSources | + | The [http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html J2EE Specification] recommends that DataSources be 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: |
<table> | <table> | ||
− | <tr><td>Resource Type</td><td> </td><td>Name in jetty.xml</td><td> </td><td>Environment Lookup</td></tr> | + | <tr><td>Resource Type</td><td> </td><td>Name in <code>jetty.xml</code></td><td> </td><td>Environment Lookup</td></tr> |
<tr><td>javax.sql.DataSource</td><td> </td><td>jdbc/myDB</td><td> </td><td>java:comp/env/jdbc/myDB</td></tr> | <tr><td>javax.sql.DataSource</td><td> </td><td>jdbc/myDB</td><td> </td><td>java:comp/env/jdbc/myDB</td></tr> | ||
<tr><td>javax.jms.QueueConnectionFactory</td><td> </td><td>jms/myQueue</td><td> </td><td>java:comp/env/jms/myQueue</td></tr> | <tr><td>javax.jms.QueueConnectionFactory</td><td> </td><td>jms/myQueue</td><td> </td><td>java:comp/env/jms/myQueue</td></tr> | ||
Line 186: | Line 234: | ||
</table> | </table> | ||
− | === 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 web app with the id of ''wac'': | |
<source lang="xml"> | <source lang="xml"> | ||
− | <Configure id='wac' class="org. | + | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> |
... | ... | ||
− | <New id="myds" class="org. | + | <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid="wac"/></Arg> |
<Arg>jdbc/myds</Arg> | <Arg>jdbc/myds</Arg> | ||
<Arg> | <Arg> | ||
Line 206: | Line 254: | ||
</source> | </source> | ||
− | The above | + | 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 <code><resource-ref></code> setup in your <code>web.xml</code>, then it is available from application lookups as <code>java:comp/env/jdbc/myds</code>. |
− | To lookup your DataSource in your servlet/filter/etc | + | Here's an example web.xml declaration for the datasource above: |
+ | |||
+ | <source lang="xml"> | ||
+ | <resource-ref> | ||
+ | <res-ref-name>jdbc/myds</res-ref-name> | ||
+ | <res-type>javax.sql.DataSource</res-type> | ||
+ | <res-auth>Container</res-auth> | ||
+ | </resource-ref> | ||
+ | </source> | ||
+ | |||
+ | To lookup your DataSource in your servlet/filter/etc.: | ||
<source lang="java"> | <source lang="java"> | ||
Line 218: | Line 276: | ||
</source> | </source> | ||
− | {{note|Careful!|When configuring Resources, | + | {{note|Careful!|When configuring Resources, ensure that the type of object you configure matches the type of object you expect to look up in <code>java:comp/env</code>. For database connection factories, this means that the object you register as a Resource *must* implement the <code>javax.sql.DataSource</code> interface.}} |
− | === Configuring JMS Queues, Topics and ConnectionFactories === | + | ==== Configuring JMS Queues, Topics and ConnectionFactories ==== |
− | Jetty | + | 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 [http://activemq.apache.org/ ActiveMQ] in JVM connection factory: |
− | + | ||
− | Here | + | |
<source lang="xml"> | <source lang="xml"> | ||
− | <Configure id='wac' class="org. | + | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> |
... | ... | ||
− | <New id="cf" class="org. | + | <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid='wac'/></Arg> |
<Arg>jms/connectionFactory</Arg> | <Arg>jms/connectionFactory</Arg> | ||
<Arg> | <Arg> | ||
Line 241: | Line 297: | ||
</source> | </source> | ||
− | + | For more information, see [http://activemq.apache.org/ ActiveMQ] and Jetty [[Integrating with ActiveMQ]]. | |
− | === Configuring Mail === | + | ==== Configuring Mail ==== |
− | Jetty also provides infrastructure for | + | Jetty also provides infrastructure for access to javax.mail.Sessions from within an application: |
<source lang="xml"> | <source lang="xml"> | ||
− | <Configure id='wac' class="org. | + | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> |
... | ... | ||
− | <New id="mail" class="org. | + | <New id="mail" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid="wac"/></Arg> |
<Arg>mail/Session</Arg> | <Arg>mail/Session</Arg> | ||
<Arg> | <Arg> | ||
− | <New class="org. | + | <New class="org.eclipse.jetty.jndi.factories.MailSessionReference"> |
<Set name="user">fred</Set> | <Set name="user">fred</Set> | ||
<Set name="password">OBF:1xmk1w261z0f1w1c1xmq</Set> | <Set name="password">OBF:1xmk1w261z0f1w1c1xmq</Set> | ||
Line 270: | Line 326: | ||
</source> | </source> | ||
− | The setup above creates an instance of the <code>org. | + | The setup above creates an instance of the <code>org.eclipse.jetty.jndi.factories.MailSessionReference</code> class, calls its setter methods <code>setUser("fred");</code>, <code>setPassword("OBF:1xmk1w261z0f1w1c1xmq");</code> 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 <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. | + | You can set the password to be plain text, or use Jetty's [[Jetty/Howto/Secure Passwords|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} | {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 <code>java:comp/UserTransaction</code> 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 <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: | |
− | + | ||
− | If you want | + | |
<source lang="xml"> | <source lang="xml"> | ||
− | <New id="tx" class="org. | + | <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"> |
<Arg> | <Arg> | ||
− | <New class="com.atomikos.icatch.jta. | + | <New class="com.atomikos.icatch.jta.UserTransactionImp"/> |
</Arg> | </Arg> | ||
</New> | </New> | ||
</source> | </source> | ||
− | + | Alternatively, you can use the [http:repo1.maven.org/maven1/org/mortbay/jetty/jetty-hightide/ Hightide] distribution of jetty instead, which comes with the [http://www.atomikos.com Atomikos] transaction system pre-configured. | |
− | |||
− | === Configuring Links === | + | ==== Configuring Links ==== |
− | + | The name you set for your NamingEntry should be the same name you use for it in <code>web.xml</code>. For example: | |
− | |||
In a context xml file: | In a context xml file: | ||
− | <Configure id='wac' class="org. | + | <source lang="xml"> |
+ | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> | ||
... | ... | ||
− | <New id="myds" class="org. | + | <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid="wac"/></Arg> |
<Arg>jdbc/mydatasource</Arg> | <Arg>jdbc/mydatasource</Arg> | ||
<Arg> | <Arg> | ||
Line 316: | Line 369: | ||
</source> | </source> | ||
− | and in web.xml: | + | and in <code>web.xml</code>: |
<source lang="xml"> | <source lang="xml"> | ||
Line 330: | Line 383: | ||
</source> | </source> | ||
− | + | You can refer to it in <code>web.xml</code> by a different name, and link it to the name in your <code>org.eclipse.jetty.plus.jndi.Resource</code> by using an <code>org.eclipse.jetty.plus.jndi.Link</code> type of NamingEntry. For the example above, you can refer to the <code>jdbc/mydatasource</code> resource as <code>jdbc/mydatasource1</code> as follows: | |
In a context xml file: | In a context xml file: | ||
<source lang="xml"> | <source lang="xml"> | ||
− | <Configure id='wac' class="org. | + | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> |
... | ... | ||
− | <New id="myds" class="org. | + | <New id="myds" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid="wac"/></Arg> |
<Arg>jdbc/mydatasource</Arg> | <Arg>jdbc/mydatasource</Arg> | ||
<Arg> | <Arg> | ||
Line 348: | Line 401: | ||
</New> | </New> | ||
</Configure> | </Configure> | ||
+ | </source> | ||
− | + | in a <code>jetty-env.xml</code> file: | |
− | in a jetty-env.xml file: | + | |
<source lang="xml"> | <source lang="xml"> | ||
− | <New id="map1" class="org. | + | <New id="map1" class="org.eclipse.jetty.plus.jndi.Link"> |
− | <Arg><Ref | + | <Arg><Ref refid='wac'/></Arg> |
<Arg>jdbc/mydatasource1</Arg> <!-- name in web.xml --> | <Arg>jdbc/mydatasource1</Arg> <!-- name in web.xml --> | ||
<Arg>jdbc/mydatasource</Arg> <!-- name in container environment --> | <Arg>jdbc/mydatasource</Arg> <!-- name in container environment --> | ||
Line 359: | Line 412: | ||
</source> | </source> | ||
− | and in web.xml: | + | and in <code>web.xml</code>: |
<source lang="xml"> | <source lang="xml"> | ||
<resource-ref> | <resource-ref> | ||
Line 372: | Line 425: | ||
</source> | </source> | ||
− | 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 <code>web.xml</code> but need to link it to a resource in your deployment environment. |
+ | |||
+ | ==== Using JNDI without a web.xml ==== | ||
+ | |||
+ | |||
+ | Usually, you define your naming entries in a WEB-INF/jetty-env.xml file or a $JETTY_HOME/etc file (or programmatically) and then link them into your webapp's java:comp/env namespace via entries in WEB-INF/web.xml. | ||
+ | |||
+ | However, as WEB-INF/web.xml files are not required for a valid webapp, you can use some xml (or code) to do the linking. Here's how. | ||
+ | |||
+ | =====With WEB-INF/jetty-env.xml file===== | ||
+ | |||
+ | If you have defined your naming entry in a WEB-INF/jetty-env.xml file, you can simply bind it into your webapp's java:comp/env namespace by adding a single line: | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <New id="jdbc/myds" class="org.eclipse.jetty.plus.jndi.Resource"> | ||
+ | <Arg></Arg> | ||
+ | <Arg>jdbc/myds</Arg> | ||
+ | <Arg> | ||
+ | <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> | ||
+ | <Set name="Url">jdbc:mysql://localhost:3306/chat</Set> | ||
+ | <Set name="User">root</Set> | ||
+ | <Set name="Password">sillyness</Set> | ||
+ | </New> | ||
+ | </Arg> | ||
+ | <Call name="bindToENC"> | ||
+ | <Arg>jdbc/myfoo</Arg> <!-- binds jdbc/myds to java:comp/env/jdbc/myfoo for this webapp --> | ||
+ | </Call> | ||
+ | </New> | ||
+ | </source> | ||
+ | |||
+ | |||
+ | =====With jetty xml file and WEB-INF/jetty-env.xml file===== | ||
+ | |||
+ | If you have defined your naming entries in xml files in jetty's etc/ directory, you can bind them into your webapp's namespace by using a WEB-INF/jetty-env.xml file to do the linking. | ||
+ | |||
+ | Assume the following naming entry is in $JETTY_HOME/etc/jetty-myjndi.xml: | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <New id="jdbc/myds" class="org.eclipse.jetty.plus.jndi.Resource"> | ||
+ | <Arg></Arg> | ||
+ | <Arg>jdbc/myds</Arg> | ||
+ | <Arg> | ||
+ | <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> | ||
+ | <Set name="Url">jdbc:mysql://localhost:3306/chat</Set> | ||
+ | <Set name="User">root</Set> | ||
+ | <Set name="Password">sillyness</Set> | ||
+ | </New> | ||
+ | </Arg> | ||
+ | </New> | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Then you can link jdbc/myds into your webapp's namespace as java:comp/env/jdbc/myfoo by using a WEB-INF/jetty-env.xml file: | ||
+ | |||
+ | <source lang="xml"> | ||
+ | <Call class="org.eclipse.jetty.plus.jndi.NamingEntryUtil" name="bindToENC"> | ||
+ | <Arg></Arg> <!-- scope of naming entry, ie same as first argument to your naming entry definition, in this case, null --> | ||
+ | <Arg>jdbc/myfoo</Arg> | ||
+ | <Arg>jdbc/myds</Arg> | ||
+ | </Call> | ||
+ | </source> | ||
+ | |||
+ | Note that you *must* use a WEB-INF/jetty-env.xml file to call the "bindToENC" method and *not* a context xml file, as the latter is not interpreted at the correct phase of the webapp's deployment to have the java:comp/env namespace created. | ||
+ | |||
+ | |||
+ | === 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 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. | |
− | As | + | |
− | The | + | The first parameter to the NamingEntry controls the scope. |
The jvm scope is represented by a null parameter: | The jvm scope is represented by a null parameter: | ||
<source lang="xml"> | <source lang="xml"> | ||
− | <New id="cf" class="org. | + | <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> |
<Arg></Arg> | <Arg></Arg> | ||
<Arg>jms/connectionFactory</Arg> | <Arg>jms/connectionFactory</Arg> | ||
Line 394: | Line 511: | ||
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. | + | <Configure id="Server" class="org.eclipse.jetty.Server"> |
... | ... | ||
− | <New id="cf" class="org. | + | <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid="Server"/></Arg> |
<Arg>jms/connectionFactory</Arg> | <Arg>jms/connectionFactory</Arg> | ||
<Arg> | <Arg> | ||
Line 410: | Line 527: | ||
The webapp scope is represented by referencing the related WebAppContext object: | The webapp scope is represented by referencing the related WebAppContext object: | ||
<source lang="xml"> | <source lang="xml"> | ||
− | <Configure id='wac' class="org. | + | <Configure id='wac' class="org.eclipse.jetty.webapp.WebAppContext"> |
... | ... | ||
− | <New id="cf" class="org. | + | <New id="cf" class="org.eclipse.jetty.plus.jndi.Resource"> |
− | <Arg><Ref | + | <Arg><Ref refid='wac'/></Arg> |
<Arg>jms/connectionFactory</Arg> | <Arg>jms/connectionFactory</Arg> | ||
<Arg> | <Arg> | ||
Line 424: | Line 541: | ||
</source> | </source> | ||
− | As you can see, the most natural | + | As you can see, the most natural configuration files in which to declare naming entries of each scope are: |
− | * <code>etc/jetty.xml</code> | + | * <code>etc/jetty.xml</code>–jvm or Server scope |
− | * <code>WEB-INF/jetty-env.xml</code> or a context xml | + | * <code>WEB-INF/jetty-env.xml</code> or a context xml file–webapp scope |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
}} | }} |
Latest revision as of 09:08, 27 October 2014
Contents
- 1 Introduction
- 2 Feature
- 3 Enabling JNDI
- 4 Using JNDI
- 4.1 Binding Objects into Jetty JNDI
- 4.1.1 Defining Naming Entries
- 4.1.2 Configuring env-entries
- 4.1.3 Configuring resource-refs and resource-env-refs
- 4.1.4 Configuring DataSources
- 4.1.5 Configuring JMS Queues, Topics and ConnectionFactories
- 4.1.6 Configuring Mail
- 4.1.7 Configuring XA Transactions
- 4.1.8 Configuring Links
- 4.1.9 Using JNDI without a web.xml
- 4.2 Setting JNDI Entries as Global or Scoped
- 4.1 Binding Objects into Jetty JNDI
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
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:
<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> <!-- not needed for jetty-8 --> </Array>
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:
<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 refid="plusConfig"/></Set> </Configure>
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/
The source for this webapp can be found on jetty @ codehaus:
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:
<env-entry/> <resource-ref/> <resource-env-ref/>
Configuring env-entries 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 link 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 aweb.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
.
<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 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
However, Jetty is a little more flexible and allows you to also bind custom POJOs, javax.naming.References and javax.naming.Referenceables. Be aware that if you take advantage of this feature, your web application is *not portable*.
To use the env-entry
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 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>
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
.
Here's an example web.xml declaration for the datasource above:
<resource-ref> <res-ref-name>jdbc/myds</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
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 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>
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 refid="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 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:
<New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"> <Arg> <New class="com.atomikos.icatch.jta.UserTransactionImp"/> </Arg> </New>
Alternatively, you can use the [http:repo1.maven.org/maven1/org/mortbay/jetty/jetty-hightide/ Hightide] distribution of jetty instead, which comes with the Atomikos transaction system pre-configured.
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 refid="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 refid="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:
<New id="map1" class="org.eclipse.jetty.plus.jndi.Link"> <Arg><Ref refid='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.
Using JNDI without a web.xml
Usually, you define your naming entries in a WEB-INF/jetty-env.xml file or a $JETTY_HOME/etc file (or programmatically) and then link them into your webapp's java:comp/env namespace via entries in WEB-INF/web.xml.
However, as WEB-INF/web.xml files are not required for a valid webapp, you can use some xml (or code) to do the linking. Here's how.
With WEB-INF/jetty-env.xml file
If you have defined your naming entry in a WEB-INF/jetty-env.xml file, you can simply bind it into your webapp's java:comp/env namespace by adding a single line:
<New id="jdbc/myds" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>jdbc/myds</Arg> <Arg> <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <Set name="Url">jdbc:mysql://localhost:3306/chat</Set> <Set name="User">root</Set> <Set name="Password">sillyness</Set> </New> </Arg> <Call name="bindToENC"> <Arg>jdbc/myfoo</Arg> <!-- binds jdbc/myds to java:comp/env/jdbc/myfoo for this webapp --> </Call> </New>
With jetty xml file and WEB-INF/jetty-env.xml file
If you have defined your naming entries in xml files in jetty's etc/ directory, you can bind them into your webapp's namespace by using a WEB-INF/jetty-env.xml file to do the linking.
Assume the following naming entry is in $JETTY_HOME/etc/jetty-myjndi.xml:
<New id="jdbc/myds" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>jdbc/myds</Arg> <Arg> <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <Set name="Url">jdbc:mysql://localhost:3306/chat</Set> <Set name="User">root</Set> <Set name="Password">sillyness</Set> </New> </Arg> </New>
Then you can link jdbc/myds into your webapp's namespace as java:comp/env/jdbc/myfoo by using a WEB-INF/jetty-env.xml file:
<Call class="org.eclipse.jetty.plus.jndi.NamingEntryUtil" name="bindToENC"> <Arg></Arg> <!-- scope of naming entry, ie same as first argument to your naming entry definition, in this case, null --> <Arg>jdbc/myfoo</Arg> <Arg>jdbc/myds</Arg> </Call>
Note that you *must* use a WEB-INF/jetty-env.xml file to call the "bindToENC" method and *not* a context xml file, as the latter is not interpreted at the correct phase of the webapp's deployment to have the java:comp/env namespace created.
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 refid="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 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>
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