Merged branch 'jetty-9.4.x' into 'master'.

This commit is contained in:
Simone Bordet 2016-07-19 10:34:59 +02:00
commit 491be7505b
11 changed files with 209 additions and 339 deletions

View File

@ -17,11 +17,11 @@
[[jndi]]
== Configuring JNDI
Jetty supports `java:comp/env` lookups in webapps. This is an optional
feature for which you need to do some setup.
Jetty supports `java:comp/env` lookups in webapps.
This is an optional feature for which some configuration is required.
include::quick-jndi-setup.adoc[]
include::using-jndi.adoc[]
include::jndi-configuration.adoc[]
include::jndi-embedded.adoc[]
include::jndi-datasources.adoc[]
include::jndi-datasources.adoc[]

View File

@ -18,12 +18,10 @@
=== Configuring JNDI
[[configuring-jndi-env-entries]]
==== 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 `org.eclipse.jetty.plus.jndi.EnvEntry`, and even override an entry of
the same name in ` web.xml`.
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}"]
----
@ -32,18 +30,15 @@ the same name in ` web.xml`.
<Arg>mySpecialValue</Arg>
<Arg type="java.lang.Integer">4000</Arg>
<Arg type="boolean">true</Arg>
</New>
</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`.
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`:
The Servlet Specification allows binding only the following object types to an `env-entry`:
* java.lang.String
* java.lang.Integer
@ -55,16 +50,10 @@ to an `env-entry`:
* 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__.
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:
To use the `env-entry` configured above, use code in your `servlet/filter/etc.`, such as:
[source, java, subs="{sub-order}"]
----
@ -78,25 +67,18 @@ public class MyClass {
Integer mySpecialValue = (Integer)ic.lookup("java:comp/env/mySpecialValue");
...
}
}
}
----
[[configuring-resource-refs-and-resource-env-refs]]
==== 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.
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:
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",]
@ -114,12 +96,10 @@ factories under `
[[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__:
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}"]
----
@ -137,13 +117,8 @@ app with the id of __wac__:
</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`.
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:
@ -153,7 +128,7 @@ Here's an example `web.xml` declaration for the datasource above:
<res-ref-name>jdbc/myds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</resource-ref>
----
To look up your DataSource in your `servlet/filter/etc.`:
@ -168,7 +143,7 @@ public class MyClass {
public void myMethod() {
InitialContext ic = new InitialContext();
DataSource myDS = (DataSource)ic.lookup("java:comp/env/jdbc/myds");
DataSource myDS = (DataSource)ic.lookup("java:comp/env/jdbc/myds");
...
}
@ -181,16 +156,14 @@ Careful! When configuring Resources, ensure that the type of object you configur
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[].
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:
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}"]
----
@ -223,8 +196,7 @@ 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:
Jetty also provides infrastructure for access to `javax.mail.Sessions` from within an application:
[source, xml, subs="{sub-order}"]
----
@ -246,17 +218,11 @@ from within an application:
</New>
</Arg>
</New>
</Configure>
</Configure>
----
This setup creates an instance of the `
org.eclipse.jetty.jndi.factories.MailSessionReference` class, calls
its 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.
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]
@ -267,14 +233,10 @@ ____
[[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:
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}"]
----
@ -288,8 +250,8 @@ configures the http://www.atomikos.com/[Atomikos] transaction manager:
[[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:
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:
@ -309,7 +271,7 @@ In a context xml file:
</Configure>
----
In `web.xml`:
In a `web.xml` file:
[source, xml, subs="{sub-order}"]
----
@ -324,12 +286,8 @@ In `web.xml`:
</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:
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`:
@ -349,8 +307,7 @@ In a context xml file declare `jdbc/mydatasource`:
</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
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}"]
@ -377,6 +334,4 @@ Now you can refer to `jdbc/mydatasource1` in the `web.xml` like this:
</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.
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.

View File

@ -17,8 +17,7 @@
[[jndi-datasource-examples]]
=== Datasource Examples
Here are examples of configuring a JNDI datasource for various
databases.
Here are examples of configuring a JNDI datasource for various databases.
____
[NOTE]
@ -29,22 +28,17 @@ All of these examples correspond to a `resource-ref` in `web.xml`.
[source, xml, subs="{sub-order}"]
----
<resource-ref>
<description>My DataSource Reference</description>
<res-ref-name>jdbc/DSTest</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
----
These examples assume that all of the datasources are declared at the
JVM scope, but you can use other scopes if desired. You can configure
all JNDI resources in a `jetty.xml` file or in a `
WEB-INF/jetty-env.xml` file, or a context XML file. See the section
xref:jndi-where-to-declare[] for more information.
These examples assume that all of the datasources are declared at the JVM scope, but you can use other scopes if desired.
You can configure all JNDI resources in a `jetty.xml` file, a `WEB-INF/jetty-env.xml` file, or a context XML file.
See the section xref:jndi-where-to-declare[] for more information.
____
[IMPORTANT]
@ -54,14 +48,11 @@ ____
[[pooling-datasources]]
==== Pooling DataSources
Pooling datasources enables connection pooling, which lets you reuse an
existing connection instead of creating a new connection to the
database. This is highly efficient in terms of memory allocation and
speed of the request to the database. We highly recommend this option
for production environments.
Pooling datasources enables connection pooling, which lets you reuse an existing connection instead of creating a new connection to the database.
This is highly efficient in terms of memory allocation and speed of the request to the database.
We highly recommend this option for production environments.
The following is a list of the pooled datasource examples we have worked
with in the past:
The following is a list of the pooled datasource examples we have worked with in the past:
* xref:hikaricp-datasource[]
* xref:bonecp-datasource[]
@ -75,14 +66,11 @@ with in the past:
[[hikaricp-datasource]]
===== HikariCP
Connection pooling, available at
http://search.maven.org/remotecontent?filepath=com/zaxxer/HikariCP/1.4.0/HikariCP-1.4.0.jar[HikariCP
Download]. All configuration options for HikariCP are described here:
https://github.com/brettwooldridge/HikariCP[HikariCP documentation].
Connection pooling, available at http://search.maven.org/remotecontent?filepath=com/zaxxer/HikariCP/1.4.0/HikariCP-1.4.0.jar[HikariCP Download].
All configuration options for HikariCP are described here: https://github.com/brettwooldridge/HikariCP[HikariCP documentation].
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -104,18 +92,13 @@ https://github.com/brettwooldridge/HikariCP[HikariCP documentation].
</New>
</Arg>
</New>
----
[[bonecp-datasource]]
===== BoneCP
Connection pooling, available at
http://jolbox.com/index.html?page=http://jolbox.com/download.html[BoneCP
Download]. All configuration options for BoneCP are described here:
http://jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPDataSource.html[BoneCP
API].
Connection pooling, available at http://jolbox.com/index.html?page=http://jolbox.com/download.html[BoneCP Download].
All configuration options for BoneCP are described here: http://jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPDataSource.html[BoneCP API].
[source, xml, subs="{sub-order}"]
----
@ -136,20 +119,15 @@ API].
</New>
</Arg>
</New>
----
[[c3p0-datasource]]
===== c3p0
Connection pooling, available at
http://central.maven.org/maven2/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar[c3p0
Jar].
Connection pooling, available at http://central.maven.org/maven2/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar[c3p0 Jar].
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -162,20 +140,15 @@ Jar].
</New>
</Arg>
</New>
----
[[dbcp-datasource]]
===== DBCP
Connection pooling, available at
http://central.maven.org/maven2/commons-dbcp/commons-dbcp/1.2/commons-dbcp-1.2.jar[dbcp
Jar].
Connection pooling, available at http://central.maven.org/maven2/commons-dbcp/commons-dbcp/1.2/commons-dbcp-1.2.jar[dbcp Jar].
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -189,8 +162,6 @@ Jar].
</New>
</Arg>
</New>
----
[[atomikos-datasource]]
@ -200,7 +171,6 @@ Connection pooling + XA transactions.
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -227,19 +197,15 @@ Connection pooling + XA transactions.
</New>
</Arg>
</New>
----
[[mysql-pooled-datasource]]
===== MySQL
Implements `javax.sql.DataSource,
javax.sql.ConnectionPoolDataSource.`
Implements `javax.sql.DataSource` and `javax.sql.ConnectionPoolDataSource`.
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -251,14 +217,12 @@ Implements `javax.sql.DataSource,
</New>
</Arg>
</New>
----
[[postgreSQL-pooled-datasource]]
===== PostgreSQL
Implements `javax.sql.ConnectionPoolDataSource`
Implements `javax.sql.ConnectionPoolDataSource`.
[source, xml, subs="{sub-order}"]
----
@ -273,22 +237,21 @@ Implements `javax.sql.ConnectionPoolDataSource`
<Set name="DatabaseName">dbname</Set>
<Set name="ServerName">localhost</Set>
<Set name="PortNumber">5432</Set>
</New>
</Arg>
</New>
----
[[DB2-pooled-datasource]]
===== DB2
Implements `javax.sql.ConnectionPoolDataSource`
Implements `javax.sql.ConnectionPoolDataSource`.
[source, xml, subs="{sub-order}"]
----
<New id="DSTest" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/DSTest</Arg>
@ -302,16 +265,13 @@ Implements `javax.sql.ConnectionPoolDataSource`
</New>
</Arg>
</New>
----
[[non-pooling-datasources]]
==== Non-pooling DataSources
If you are deploying in a production environment, we highly recommend
using a Pooling DataSource. Since that is not always an option we have a
handful of examples for non-pooling datasources listed here as well.
If you are deploying in a production environment, we highly recommend using a Pooling DataSource.
Since that is not always an option we have a handful of examples for non-pooling datasources listed here as well.
The following is a list of the non-pooled datasource examples:
@ -324,8 +284,7 @@ The following is a list of the non-pooled datasource examples:
[[sql-server-2000-datasource]]
===== SQL Server 2000
Implements `javax.sql.DataSource,
javax.sql.ConnectionPoolDataSource.`
Implements `javax.sql.DataSource` and `javax.sql.ConnectionPoolDataSource`.
[source, xml, subs="{sub-order}"]
----
@ -347,8 +306,7 @@ Implements `javax.sql.DataSource,
[[oracle-9i10g-datasource]]
===== Oracle 9i/10g
Implements `javax.sql.DataSource,
javax.sql.ConnectionPoolDataSource.`
Implements `javax.sql.DataSource` and `javax.sql.ConnectionPoolDataSource`.
[source, xml, subs="{sub-order}"]
----
@ -376,14 +334,12 @@ Implements `javax.sql.DataSource,
</New>
----
For more information, refer to:
http://docs.oracle.com/cd/B14117_01/java.101/b10979/conncache.htm[Oracle
Database JDBC documentation].
For more information, refer to: http://docs.oracle.com/cd/B14117_01/java.101/b10979/conncache.htm[Oracle Database JDBC documentation].
[[postgreSQL-datasource]]
===== PostgreSQL
Implements `javax.sql.DataSource.`
Implements `javax.sql.DataSource`.
[source, xml, subs="{sub-order}"]
----
@ -405,7 +361,7 @@ Implements `javax.sql.DataSource.`
[[sybase-datasource]]
===== Sybase
Implements `javax.sql.DataSource.`
Implements `javax.sql.DataSource`.
[source, xml, subs="{sub-order}"]
----
@ -421,13 +377,13 @@ Implements `javax.sql.DataSource.`
<Set name="PortNumber">5000</Set>
</New>
</Arg>
</New>
</New>
----
[[DB2-datasource]]
===== DB2
Implements `javax.sql.DataSource.`
Implements `javax.sql.DataSource`.
[source, xml, subs="{sub-order}"]
----
@ -443,5 +399,5 @@ Implements `javax.sql.DataSource.`
<Set name="PortNumber">50000</Set>
</New>
</Arg>
</New>
</New>
----

View File

@ -19,38 +19,24 @@
==== Setting up the Classpath
In addition to the jars that you require for your application, and the
jars needed for core Jetty, you will need to place the following jars
onto your classpath:
In addition to the jars that you require for your application, and the jars needed for core Jetty, you will need to place the following jars onto your classpath:
....
jetty-jndi.jar
jetty-plus.jar
....
If you are using transactions, you will also need the javax.transaction
api. You can
http://download.eclipse.org/jetty/orbit/javax.transaction_1.1.1.v201004190952.jar/dist/[obtain
this jar] from http://download.eclipse.org/jetty/orbit[the Jetty
dependencies site.]
If you are using transactions, you will also need the `javax.transaction` api.
You can http://download.eclipse.org/jetty/orbit/javax.transaction_1.1.1.v201004190952.jar/dist/[obtain this jar] from http://download.eclipse.org/jetty/orbit[the Jetty dependencies site.]
If you wish to use mail, you will also need the javax.mail api and
implementation. You can
http://download.eclipse.org/jetty/orbit/javax.mail.glassfish_1.4.1.v201005082020.jar/dist/[obtain
this jar] from
thehttp://download.eclipse.org/jetty/orbit/javax.mail.glassfish_1.4.1.v201005082020.jar/dist/[Jetty
dependencies site]. Note that this jar also requires the
javax.activation classes, which you can also
http://download.eclipse.org/jetty/orbit/javax.activation_1.1.0.v201105071233.jar/dist/[obtain]
from the http://download.eclipse.org/jetty/orbit/[Jetty dependencies
site].
If you wish to use mail, you will also need the `javax.mail` api and implementation.
You can http://download.eclipse.org/jetty/orbit/javax.mail.glassfish_1.4.1.v201005082020.jar/dist/[obtain this jar] from the http://download.eclipse.org/jetty/orbit/javax.mail.glassfish_1.4.1.v201005082020.jar/dist/[Jetty dependencies site].
Note that this jar also requires the `javax.activation` classes, which you can also http://download.eclipse.org/jetty/orbit/javax.activation_1.1.0.v201105071233.jar/dist/[obtain] from the http://download.eclipse.org/jetty/orbit/[Jetty dependencies site].
==== Example Code
Here is an example class that sets up some JNDI entries and deploys a
webapp that references these JNDI entries in code. We'll use some mocked
up classes for the transaction manager and the DataSource in this
example for simplicity:
Here is an example class that sets up some JNDI entries and deploys a webapp that references these JNDI entries in code.
We'll use some mocked up classes for the transaction manager and the DataSource in this example for simplicity:
[source, java, subs="{sub-order}"]
----
@ -70,7 +56,7 @@ public class ServerWithJNDI
//Create the server
Server server = new Server(8080);
//Enable parsing of jndi-related parts of web.xml and jetty-env.xml
org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
@ -86,19 +72,19 @@ public class ServerWithJNDI
org.eclipse.jetty.plus.jndi.Transaction transactionMgr = new org.eclipse.jetty.plus.jndi.Transaction(new com.acme.MockUserTransaction());
//Define an env entry with Server scope.
//At runtime, the webapp accesses this as java:comp/env/woggle
//This is equivalent to putting an env-entry in web.xml:
//<env-entry>
// <env-entry-name>woggle</env-entry-name>
// <env-entry-type>java.lang.Integer</env-entry-type>
// <env-entry-value>4000</env-entry-value>
//At runtime, the webapp accesses this as java:comp/env/woggle
//This is equivalent to putting an env-entry in web.xml:
//<env-entry>
// <env-entry-name>woggle</env-entry-name>
// <env-entry-type>java.lang.Integer</env-entry-type>
// <env-entry-value>4000</env-entry-value>
//</env-entry>
org.eclipse.jetty.plus.jndi.EnvEntry woggle = new org.eclipse.jetty.plus.jndi.EnvEntry(server, "woggle", new Integer(4000), false);
//Define an env entry with webapp scope.
//At runtime, the webapp accesses this as java:comp/env/wiggle
//This is equivalent to putting a web.xml entry in web.xml:
//This is equivalent to putting a web.xml entry in web.xml:
//<env-entry>
// <env-entry-name>wiggle</env-entry-name>
// <env-entry-value>100</env-entry-value>
@ -126,7 +112,7 @@ public class ServerWithJNDI
props.put("mail.debug", "false");
mailref.setProperties(props);
org.eclipse.jetty.plus.jndi.Resource xxxmail = new org.eclipse.jetty.plus.jndi.Resource(webapp, "mail/Session", mailref);
// Register a mock DataSource scoped to the webapp
//This must be linked to the webapp via an entry in web.xml:
@ -138,7 +124,7 @@ public class ServerWithJNDI
//At runtime the webapp accesses this as java:comp/env/jdbc/mydatasource
org.eclipse.jetty.plus.jndi.Resource mydatasource = new org.eclipse.jetty.plus.jndi.Resource(webapp, "jdbc/mydatasource",
new com.acme.MockDataSource());
server.start();
server.join();
}

View File

@ -17,40 +17,29 @@
[[jndi-quick-setup]]
=== Quick Setup
If you are using the standard distribution of Jetty, you must enable the
*jndi* link:#startup-modules[module] to obtain jetty's jndi
implementation, and the *plus* link:#startup-modules[module] which
provides classes for interacting with jndi. As the *plus* module depends
on the *jndi* module, you only need to enable the *plus* module to
enable both. Assuming you have jetty
link:#startup-base-and-home[installed] in /opt/jetty, and you have made
a link:#startup-base-and-home[jetty base] in /opt/jetty/my-base, do:
If you are using the standard distribution of Jetty, you must enable the _JNDI_ link:#startup-modules[module] to obtain Jetty's JNDI implementation, and the *plus* link:#startup-modules[module] which provides classes for interacting with JNDI.
As the _plus_ module depends on the _JNDI_ module, you only need to enable the _plus_ module to enable both.
Assuming you have Jetty installed in `/opt/jetty`, and you have made a link:#startup-base-and-home[jetty base] in `/opt/jetty/my-base`, do:
[source,bash]
----
cd /opt/jetty
cd my-base
java -jar $JETTY_HOME/start.jar --add-to-startd=plus
----
You can now start Jetty and use JNDI within your webapps. See
link:#using-jndi[Using JNDI] for information on how to add entries to
the JNDI environment that Jetty can look up within webapps.
You can now start Jetty and use JNDI within your webapps.
See link:#using-jndi[Using JNDI] for information on how to add entries to the JNDI environment that Jetty can look up within webapps.
If you have extra jars associated with your jndi resources, for example
a database driver jar, and you haven't made a custom
link:#startup-modules[module] for it, you can put the jars into your
link:#startup-base-and-home[jetty base] `ext/` directory. You will then
need to enable the *ext* module to ensure the jars in the `ext/`
directory are on the classpath. Assuming you have jetty
link:#startup-base-and-home[installed] in /opt/jetty, and you have made
a link:#startup-base-and-home[jetty base] in /opt/jetty/my-base, do:
If you have extra jars associated with your JNDI resources, for example a database driver jar, and you haven't made a custom link:#startup-modules[module] for it, you can put the jars into your `{$jetty base}ext/` directory.
You will then need to enable the _ext_ module to ensure the jars in the `ext/` directory are on the classpath.
Assuming you have Jetty installed in `/opt/jetty`, and you have made a link:#startup-base-and-home[jetty base] in `/opt/jetty/my-base`, do:
[source,bash]
----
cd /opt/jetty
cd my-base
java -jar $JETTY_HOME/start.jar --add-to-startd=ext
----

View File

@ -19,103 +19,76 @@
==== Defining the web.xml
You can configure naming resources to reference in a `web.xml` file and
access from within the `java:comp/env` naming environment of the webapp
during execution. Specifically, you can configure support for the
following `web.xml` elements:
You can configure naming resources to reference in a `web.xml` file and access from within the `java:comp/env` naming environment of the webapp during execution.
Specifically, you can configure support for the following `web.xml` elements:
[source, xml, subs="{sub-order}"]
----
<env-entry/>
<resource-ref/>
<resource-env-ref/>
----
link:#configuring-jndi-env-entries[Configuring env-entries] shows you
how to set up overrides for `
env-entry` elements in `web.xml`, while
link:#configuring-resource-refs-and-resource-env-refs[Configuring
`resource-refs` and `resource-env-refs`] discusses how to configure
support resources such as `javax.sql.DataSource`.
link:#configuring-jndi-env-entries[Configuring env-entries] shows you how to set up overrides for `env-entry` elements in `web.xml`, while link:#configuring-resource-refs-and-resource-env-refs[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 webapps can look up
`java:comp/UserTransaction` to obtain a distributed transaction manager:
see link:#configuring-xa-transactions[Configuring XA Transactions].
You can also plug a JTA `javax.transaction.UserTransaction` implementation into Jetty so that webapps can look up `java:comp/UserTransaction` to obtain a distributed transaction manager: see link:#configuring-xa-transactions[Configuring XA Transactions].
[[defining-jndi-naming-entries]]
==== Declaring Resources
You must declare the objects you want bound into the Jetty environment
so that you can then hook into your webapp via `env-entry,
resource-ref` and `resource-env-refs` in `web.xml`. You create
these bindings by using declarations of the following types:
You must declare the objects you want bound into the Jetty environment so that you can then hook into your webapp via `env-entry`, `resource-ref` and `resource-env-refs` in `web.xml`.
You create these bindings by using declarations of the following types:
`org.eclipse.jetty.plus.jndi.EnvEntry`::
for `env-entry` type of entries
For `env-entry` type of entries
`org.eclipse.jetty.plus.jndi.Resource`::
for all other type of resources
For all other type of resources
`org.eclipse.jetty.plus.jndi.Transaction`::
for a JTA manager
For a JTA manager
`org.eclipse.jetty.plus.jndi.Link`::
for link between a `web.xml` resource name and a naming entry
For the link between a `web.xml` resource name and a naming entry
Declarations of each of these types follow the same general pattern:
[source, xml, subs="{sub-order}"]
----
<New class="org.eclipse.jetty.plus.jndi.xxxx">
<Arg><!-- scope --></Arg>
<Arg><!-- name --></Arg>
<Arg><!-- value --></Arg>
</New>
----
You can place these declarations into three different files, depending
on your needs and the link:#jndi-name-scope[scope] of the resources
being declared.
You can place these declarations into three different files, depending on your needs and the link:#jndi-name-scope[scope] of the resources being declared.
[[jndi-where-to-declare]]
==== Deciding Where to Declare Resources
You can define naming resources in three places:
jetty.xml::
Naming resources defined in a `jetty.xml` file are
link:#jndi-name-scope[scoped] at either the JVM level or the Server
level. The classes for the resource must be visible at the Jetty
container level. If the classes for the resource only exist inside
your webapp, you must declare it in a `WEB-INF/jetty-env.xml` file.
_jetty.xml_::
Naming resources defined in a `jetty.xml` file are link:#jndi-name-scope[scoped] at either the JVM level or the Server level.
The classes for the resource must be visible at the Jetty container level.
If the classes for the resource only exist inside your webapp, you must declare it in a `WEB-INF/jetty-env.xml` file.
WEB-INF/jetty-env.xml::
Naming resources in a `WEB-INF/jetty-env.xml` file are
link:#jndi-name-scope[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. The resources defined here may use classes
from inside your webapp. This is a Jetty-specific mechanism.
context xml file::
Entries in a context xml file should be link:#jndi-name-scope[scoped]
at the level of the webapp to which they apply, although you can
supply a less strict scoping level of Server or JVM if you choose. As
with resources declared in a `jetty.xml` file, classes associated with
the resource must be visible on the container's classpath.
Naming resources in a `WEB-INF/jetty-env.xml` file are link:#jndi-name-scope[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.
The resources defined here may use classes from inside your webapp.
This is a Jetty-specific mechanism.
Context xml file::
Entries in a context xml file should be link:#jndi-name-scope[scoped] at the level of the webapp to which they apply, although you can supply a less strict scoping level of Server or JVM if you choose.
As with resources declared in a `jetty.xml` file, classes associated with the resource must be visible on the container's classpath.
[[jndi-name-scope]]
==== Scope of Resource Names
Naming resources within Jetty belong to one of three different scopes,
in increasing order of restrictiveness:
Naming resources within Jetty belong to one of three different scopes, in increasing order of restrictiveness:
JVM scope::
The name is unique across the JVM instance, and is visible to all
application code. You represent this scope by a `null` first parameter
to the resource declaration. For example:
+
The name is unique across the JVM instance, and is visible to all application code.
You represent this scope by a `null` first parameter to the resource declaration.
For example:
+
[source, xml, subs="{sub-order}"]
----
@ -128,18 +101,14 @@ JVM scope::
</New>
</Arg>
</New>
----
Server scope::
The name is unique to a Server instance, and is only visible to code
associated with that instance. You represent this scope by referencing
the Server instance as the first parameter to the resource
declaration. For example:
+
The name is unique to a Server instance, and is only visible to code associated with that instance.
You represent this scope by referencing the Server instance as the first parameter to the resource declaration.
For example:
+
[source, xml, subs="{sub-order}"]
----
<Configure id="Server" class="org.eclipse.jetty.Server">
<New id="cf" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg><Ref refid="Server"/></Arg> <!-- reference to Server instance -->
@ -151,18 +120,14 @@ Server scope::
</Arg>
</New>
</Configure>
----
Webapp scope::
The name is unique to the WebAppContext instance, and is only visible
to code associated with that instance. You represent this scope by
referencing the WebAppContext instance as the first parameter to the
resource declaration. For example:
+
The name is unique to the WebAppContext instance, and is only visible to code associated with that instance.
You represent this scope by referencing the `WebAppContext` instance as the first parameter to the resource declaration.
For example:
+
[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> <!-- reference to WebAppContext -->
@ -174,8 +139,6 @@ Webapp scope::
</Arg>
</New>
</Configure>
----
[[binding-objects-into-jetty-jndi]]
@ -184,12 +147,6 @@ Webapp scope::
You can bind four types of objects into a Jetty JNDI reference:
* An ordinary POJO instance.
* A
http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Reference.html[javax.naming.Reference]
instance.
* An object instance that implements the
http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Referenceable.html[javax.naming.Referenceable]
interface.
* A link between a name as referenced in `web.xml` and as referenced in
the Jetty environment.
* A http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Reference.html[javax.naming.Reference] instance.
* An object instance that implements the http://docs.oracle.com/javase/1.5.0/docs/api/javax/naming/Referenceable.html[javax.naming.Referenceable] interface.
* A link between a name as referenced in `web.xml` and as referenced in the Jetty environment.

View File

@ -108,11 +108,18 @@ public class BufferingFlowControlStrategy extends AbstractFlowControlStrategy
int maxLevel = (int)(maxSessionRecvWindow.get() * ratio);
if (level > maxLevel)
{
level = sessionLevel.getAndSet(0);
session.updateRecvWindow(level);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, updated session recv window by {}/{} for {}", length, level, maxLevel, session);
windowFrame = new WindowUpdateFrame(0, level);
if (sessionLevel.compareAndSet(level, 0))
{
session.updateRecvWindow(level);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, updated session recv window by {}/{} for {}", length, level, maxLevel, session);
windowFrame = new WindowUpdateFrame(0, level);
}
else
{
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, concurrent session recv window level {}/{} for {}", length, sessionLevel, maxLevel, session);
}
}
else
{

View File

@ -199,11 +199,14 @@ public class HttpOutput extends ServletOutputStream implements Runnable
}
case ASYNC:
if (!_state.compareAndSet(state, OutputState.READY))
continue;
break;
case UNREADY:
case PENDING:
{
if (!_state.compareAndSet(state,OutputState.CLOSED))
break;
continue;
IOException ex = new IOException("Closed while Pending/Unready");
LOG.warn(ex.toString());
LOG.debug(ex);
@ -212,7 +215,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
default:
{
if (!_state.compareAndSet(state,OutputState.CLOSED))
break;
continue;
try
{

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@ -46,6 +47,8 @@ import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@ -75,6 +78,7 @@ public class AsyncIOServletTest
{
private Server server;
private ServerConnector connector;
private LocalConnector local;
private ServletContextHandler context;
private String path = "/path";
private static final ThreadLocal<Throwable> scope = new ThreadLocal<>();
@ -83,6 +87,7 @@ public class AsyncIOServletTest
{
startServer(servlet,30000);
}
public void startServer(HttpServlet servlet, long idleTimeout) throws Exception
{
server = new Server();
@ -90,6 +95,8 @@ public class AsyncIOServletTest
connector.setIdleTimeout(idleTimeout);
connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setDelayDispatchUntilContent(false);
server.addConnector(connector);
local = new LocalConnector(server);
server.addConnector(local);
context = new ServletContextHandler(server, "/", false, false);
ServletHolder holder = new ServletHolder(servlet);
@ -952,11 +959,16 @@ public class AsyncIOServletTest
int read = input.read(buffer);
if (read < 0)
{
asyncContext.complete();
//if (output.isReady())
{
asyncContext.complete();
}
break;
}
if (output.isReady())
{
output.write(buffer, 0, read);
}
else
Assert.fail();
}
@ -978,7 +990,10 @@ public class AsyncIOServletTest
@Override
public void onWritePossible() throws IOException
{
writeLatch.countDown();
if (writeLatch.getCount()==0)
asyncContext.complete();
else
writeLatch.countDown();
}
@Override
@ -992,29 +1007,24 @@ public class AsyncIOServletTest
String content = "0123456789ABCDEF";
try (Socket client = new Socket("localhost", connector.getLocalPort()))
try (LocalEndPoint endp = local.connect())
{
OutputStream output = client.getOutputStream();
String request = "POST " + path + " HTTP/1.1\r\n" +
"Host: localhost:" + connector.getLocalPort() + "\r\n" +
"Transfer-Encoding: chunked\r\n" +
"\r\n" +
"10\r\n" +
Integer.toHexString(content.length())+"\r\n" +
content + "\r\n";
output.write(request.getBytes("UTF-8"));
output.flush();
endp.addInput(ByteBuffer.wrap(request.getBytes("UTF-8")));
assertTrue(writeLatch.await(5, TimeUnit.SECONDS));
request = "" +
"0\r\n" +
"\r\n";
output.write(request.getBytes("UTF-8"));
output.flush();
endp.addInput(ByteBuffer.wrap(request.getBytes("UTF-8")));
HttpTester.Input input = HttpTester.from(client.getInputStream());
HttpTester.Response response = HttpTester.parseResponse(input);
HttpTester.Response response = HttpTester.parseResponse(endp.getResponse());
assertThat(response.getStatus(), Matchers.equalTo(HttpStatus.OK_200));
assertThat(response.getContent(), Matchers.equalTo(content));

View File

@ -200,7 +200,7 @@ public class AsyncServletTest
@Test
public void testAsyncNotSupportedAsync() throws Exception
{
try (StacklessLogging stackless = new StacklessLogging(ServletHandler.class))
try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
{
_expectedCode="500 ";
String response=process("noasync","start=200",null);

View File

@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.QuietServletException;
import org.eclipse.jetty.server.Server;
@ -84,7 +85,7 @@ public class ErrorPageTest
@Test
public void testErrorCode() throws Exception
{
String response = _connector.getResponses("GET /fail/code?code=599 HTTP/1.0\r\n\r\n");
String response = _connector.getResponse("GET /fail/code?code=599 HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 599 599"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /599"));
assertThat(response,Matchers.containsString("ERROR_CODE: 599"));
@ -97,20 +98,23 @@ public class ErrorPageTest
@Test
public void testErrorException() throws Exception
{
String response = _connector.getResponses("GET /fail/exception HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 500 Server Error"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /TestException"));
assertThat(response,Matchers.containsString("ERROR_CODE: 500"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION: javax.servlet.ServletException: java.lang.IllegalStateException"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION_TYPE: class javax.servlet.ServletException"));
assertThat(response,Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$FailServlet-"));
assertThat(response,Matchers.containsString("ERROR_REQUEST_URI: /fail/exception"));
try(StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
{
String response = _connector.getResponse("GET /fail/exception HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 500 Server Error"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /TestException"));
assertThat(response,Matchers.containsString("ERROR_CODE: 500"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION: javax.servlet.ServletException: java.lang.IllegalStateException"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION_TYPE: class javax.servlet.ServletException"));
assertThat(response,Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$FailServlet-"));
assertThat(response,Matchers.containsString("ERROR_REQUEST_URI: /fail/exception"));
}
}
@Test
public void testGlobalErrorCode() throws Exception
{
String response = _connector.getResponses("GET /fail/global?code=598 HTTP/1.0\r\n\r\n");
String response = _connector.getResponse("GET /fail/global?code=598 HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 598 598"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /GlobalErrorPage"));
assertThat(response,Matchers.containsString("ERROR_CODE: 598"));
@ -123,14 +127,17 @@ public class ErrorPageTest
@Test
public void testGlobalErrorException() throws Exception
{
String response = _connector.getResponses("GET /fail/global?code=NAN HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 500 Server Error"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /GlobalErrorPage"));
assertThat(response,Matchers.containsString("ERROR_CODE: 500"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION: java.lang.NumberFormatException: For input string: \"NAN\""));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION_TYPE: class java.lang.NumberFormatException"));
assertThat(response,Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$FailServlet-"));
assertThat(response,Matchers.containsString("ERROR_REQUEST_URI: /fail/global"));
try(StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
{
String response = _connector.getResponse("GET /fail/global?code=NAN HTTP/1.0\r\n\r\n");
assertThat(response,Matchers.containsString("HTTP/1.1 500 Server Error"));
assertThat(response,Matchers.containsString("ERROR_PAGE: /GlobalErrorPage"));
assertThat(response,Matchers.containsString("ERROR_CODE: 500"));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION: java.lang.NumberFormatException: For input string: \"NAN\""));
assertThat(response,Matchers.containsString("ERROR_EXCEPTION_TYPE: class java.lang.NumberFormatException"));
assertThat(response,Matchers.containsString("ERROR_SERVLET: org.eclipse.jetty.servlet.ErrorPageTest$FailServlet-"));
assertThat(response,Matchers.containsString("ERROR_REQUEST_URI: /fail/global"));
}
}
public static class FailServlet extends HttpServlet implements Servlet