| // ======================================================================== |
| // Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. |
| // ======================================================================== |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| |
| [[jndi-configuration]] |
| === Configuring JNDI |
| |
| [[configuring-jndi-env-entries]] |
| ==== Configuring JNDI _env-entries_ |
| |
| Sometimes it is useful to pass configuration information to a webapp at runtime that you either cannot or cannot conveniently code into a `web.xml` env-entry. |
| In such cases, you can use the `org.eclipse.jetty.plus.jndi.EnvEntry` class, and even override an entry of the same name in `web.xml`. |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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 xref:jndi-name-scope[scoped] to the 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, omit this argument, or set it to `false`. |
| |
| 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 |
| |
| That being said, Jetty is a little more flexible and allows you to also bind custom POJOs, http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Reference.html[`javax.naming.References`] and http://docs.oracle.com/javase/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 `env-entry` configured above, use code in your `servlet/filter/etc.`, such as: |
| |
| [source, java, subs="{sub-order}"] |
| ---- |
| import javax.naming.InitialContext; |
| |
| public class MyClass { |
| |
| public void myMethod() { |
| |
| InitialContext ic = new InitialContext(); |
| Integer mySpecialValue = (Integer)ic.lookup("java:comp/env/mySpecialValue"); |
| ... |
| } |
| } |
| ---- |
| |
| [[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 `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 http://jcp.org/aboutJava/communityprocess/pr/jsr244/index.html[J2EE Specification] recommends storing DataSources 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: |
| |
| .DataSource Declaration Conventions |
| [cols=",,",options="header",] |
| |======================================================================= |
| |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]] |
| ==== 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 http://db.apache.org/derby[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__: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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 do not have the appropriate `resource-ref` set up in your `web.xml`, it is available from application lookups as `java:comp/env/jdbc/myds`. |
| |
| Here's an example `web.xml` declaration for the datasource above: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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 look up your DataSource in your `servlet/filter/etc.`: |
| |
| [source, java, subs="{sub-order}"] |
| ---- |
| import javax.naming.InitialContext; |
| import javax.sql.DataSource; |
| |
| public class MyClass { |
| |
| public void myMethod() { |
| |
| InitialContext ic = new InitialContext(); |
| DataSource myDS = (DataSource)ic.lookup("java:comp/env/jdbc/myds"); |
| |
| ... |
| } |
| } |
| ---- |
| |
| ____ |
| [NOTE] |
| Careful! When configuring Resources, ensure that the type of object you configure matches the type of object you expect to look up in `java:comp/env`. |
| For database connection factories, this means that the object you register as a Resource _must_ implement the `javax.sql.DataSource` interface. |
| ____ |
| |
| For more examples of datasource configurations, see xref:jndi-datasource-examples[]. |
| |
| [[configuring-jms-queues-topics-connectionfactories]] |
| ==== 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 http://activemq.apache.org[ActiveMQ] in-JVM connection factory: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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> |
| ---- |
| |
| The entry in `web.xml` would be: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <resource-ref> |
| <res-ref-name>jms/connectionFactory</res-ref-name> |
| <res-type>javax.jms.ConnectionFactory</res-type> |
| <res-auth>Container</res-auth> |
| </resource-ref> |
| ---- |
| |
| TODO: put in an example of a QUEUE from progress demo |
| |
| [[configuring-mail-with-jndi]] |
| ==== Configuring Mail |
| |
| Jetty also provides infrastructure for access to `javax.mail.Sessions` from within an application: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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> |
| ---- |
| |
| This setup creates an instance of the `org.eclipse.jetty.jndi.factories.MailSessionReference` class, calls it's setter methods 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 link:#configuring-security-secure-passwords[Secure Password Obfuscation] (OBF:) mechanism to make the config file a little more secure from prying eyes. |
| Remember that you cannot use the other Jetty encryption mechanisms of MD5 and Crypt because they do not allow you to recover the original password, which the mail system requires. |
| ____ |
| |
| [[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, and that you can look up as `java:comp/UserTransaction` in your webapp. |
| 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 link:{JDURL}/org/eclipse/jetty/plus/jndi/Transaction.html[JNDI Transaction] object in a Jetty config file. |
| The following example configures the http://www.atomikos.com/[Atomikos] transaction manager: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <New id="tx" class="org.eclipse.jetty.plus.jndi.Transaction"> |
| <Arg> |
| <New class="com.atomikos.icatch.jta.J2eeUserTransaction"/> |
| </Arg> |
| </New> |
| ---- |
| |
| [[configuring-links]] |
| ==== Configuring Links |
| |
| Generally, the name you set for your `Resource` should be the same name you use for it in `web.xml`. |
| For example: |
| |
| In a context xml file: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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 `web.xml` file: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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> |
| ---- |
| |
| However, 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`. |
| For the example above, you can refer to the `jdbc/mydatasource` resource as `jdbc/mydatasource1` as follows: |
| |
| In a context xml file declare `jdbc/mydatasource`: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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> |
| ---- |
| |
| Then in a `WEB-INF/jetty-env.xml` file, link the name `jdbc/mydatasource` to the name you want to reference it as in |
| `web.xml`, which in this case is `jdbc/mydatasource1`: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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> |
| ---- |
| |
| Now you can refer to `jdbc/mydatasource1` in the `web.xml` like this: |
| |
| [source, xml, subs="{sub-order}"] |
| ---- |
| <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 a JNDI resource directly in the `web.xml` but need to link it to a specific resource in your deployment environment. |