diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/chapter.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/chapter.adoc index 2e6677c2088..5324c8b02cc 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/chapter.adoc @@ -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[] \ No newline at end of file +include::jndi-datasources.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-configuration.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-configuration.adoc index 12c92e49eea..ac11c7d7530 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-configuration.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-configuration.adoc @@ -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`. mySpecialValue 4000 true - + ---- -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__: ---- -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: jdbc/myds javax.sql.DataSource Container - + ---- 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: - + ---- -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: ---- -In `web.xml`: +In a `web.xml` file: [source, xml, subs="{sub-order}"] ---- @@ -324,12 +286,8 @@ In `web.xml`: ---- -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`: ---- -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: ---- -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. diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-datasources.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-datasources.adoc index a7d01aee1ea..e475882da44 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-datasources.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-datasources.adoc @@ -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}"] ---- - My DataSource Reference jdbc/DSTest javax.sql.DataSource Container - - ---- -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}"] ---- - jdbc/DSTest @@ -104,18 +92,13 @@ https://github.com/brettwooldridge/HikariCP[HikariCP documentation]. - - ---- [[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]. - - ---- [[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}"] ---- - jdbc/DSTest @@ -162,20 +140,15 @@ Jar]. - - ---- [[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}"] ---- - jdbc/DSTest @@ -189,8 +162,6 @@ Jar]. - - ---- [[atomikos-datasource]] @@ -200,7 +171,6 @@ Connection pooling + XA transactions. [source, xml, subs="{sub-order}"] ---- - jdbc/DSTest @@ -227,19 +197,15 @@ Connection pooling + XA transactions. - - ---- [[mysql-pooled-datasource]] ===== MySQL -Implements `javax.sql.DataSource, - javax.sql.ConnectionPoolDataSource.` +Implements `javax.sql.DataSource` and `javax.sql.ConnectionPoolDataSource`. [source, xml, subs="{sub-order}"] ---- - jdbc/DSTest @@ -251,14 +217,12 @@ Implements `javax.sql.DataSource, - - ---- [[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` dbname localhost 5432 - + - + ---- [[DB2-pooled-datasource]] ===== DB2 -Implements `javax.sql.ConnectionPoolDataSource` +Implements `javax.sql.ConnectionPoolDataSource`. [source, xml, subs="{sub-order}"] ---- - jdbc/DSTest @@ -302,16 +265,13 @@ Implements `javax.sql.ConnectionPoolDataSource` - - ---- [[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, ---- -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.` 5000 - + ---- [[DB2-datasource]] ===== DB2 -Implements `javax.sql.DataSource.` +Implements `javax.sql.DataSource`. [source, xml, subs="{sub-order}"] ---- @@ -443,5 +399,5 @@ Implements `javax.sql.DataSource.` 50000 - + ---- diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-embedded.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-embedded.adoc index 819e3b1fb22..bb0a60c9a9a 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-embedded.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/jndi-embedded.adoc @@ -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: - // - // woggle - // java.lang.Integer - // 4000 + //At runtime, the webapp accesses this as java:comp/env/woggle + //This is equivalent to putting an env-entry in web.xml: + // + // woggle + // java.lang.Integer + // 4000 // 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: // // wiggle // 100 @@ -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(); } diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/quick-jndi-setup.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/quick-jndi-setup.adoc index e10dffcdcea..0152e02f5eb 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/quick-jndi-setup.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/quick-jndi-setup.adoc @@ -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 - + ---- diff --git a/jetty-documentation/src/main/asciidoc/administration/jndi/using-jndi.adoc b/jetty-documentation/src/main/asciidoc/administration/jndi/using-jndi.adoc index 3c533dc0809..c453058eb8a 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jndi/using-jndi.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jndi/using-jndi.adoc @@ -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}"] ---- - - - ---- -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}"] ---- - - - ---- -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:: - - ---- 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}"] ---- - @@ -151,18 +120,14 @@ Server scope:: - - ---- 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}"] ---- - @@ -174,8 +139,6 @@ Webapp scope:: - - ---- [[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. diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java index 121c9ef34ef..f0ed55a56b6 100644 --- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java +++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java @@ -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 { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java index 4112384a2ec..ea5d1d63c1f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpOutput.java @@ -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 { diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java index c76d59b11f1..6d7b6d793b9 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncIOServletTest.java @@ -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 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)); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletTest.java index 16cffe6852a..f43f740ddfb 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncServletTest.java @@ -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); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java index be0130094e0..e095ae316e4 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java @@ -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