Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2013-03-01 22:32:57 +0000
committerGreg Wilkins2013-03-01 22:32:57 +0000
commit64783068123ad4bc262cf1f594462c833a6d3e50 (patch)
tree281e6017d8726c17bd034e7b76a54be1264ca8c9
parent41952ebf1db6f5b7809c30dfc5be40c4892146d4 (diff)
parent79630de1f194e9edb0d1807b7d1841fbc5acd7ee (diff)
downloadorg.eclipse.jetty.project-64783068123ad4bc262cf1f594462c833a6d3e50.tar.gz
org.eclipse.jetty.project-64783068123ad4bc262cf1f594462c833a6d3e50.tar.xz
org.eclipse.jetty.project-64783068123ad4bc262cf1f594462c833a6d3e50.zip
Merge branch 'master' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project
Conflicts: jetty-server/src/main/config/etc/jetty.xml
-rw-r--r--examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java39
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java6
-rw-r--r--jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializerListener.java27
-rw-r--r--jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java43
-rw-r--r--jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java53
-rw-r--r--jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java5
-rw-r--r--jetty-server/src/main/config/etc/jetty.xml14
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java18
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java76
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java1
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java2
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java5
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/LogicalConnection.java14
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java11
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/mux/MuxChannel.java14
-rw-r--r--jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java12
-rw-r--r--jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketConnection.java14
-rw-r--r--jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java9
-rw-r--r--jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java10
-rw-r--r--jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleServlet.java35
-rw-r--r--jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleSocket.java34
-rw-r--r--tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/FooInitializer.java63
-rw-r--r--tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java8
23 files changed, 388 insertions, 125 deletions
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index 181e6c5c93..ec27c98fed 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -25,7 +25,6 @@ import org.eclipse.jetty.deploy.PropertiesConfigurationManager;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService;
-import org.eclipse.jetty.server.ForwardedRequestCustomizer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -42,7 +41,7 @@ import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.util.thread.TimerScheduler;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
public class LikeJettyXml
{
@@ -51,7 +50,7 @@ public class LikeJettyXml
String jetty_home = System.getProperty("jetty.home","../../jetty-distribution/target/distribution");
System.setProperty("jetty.home",jetty_home);
-
+
// === jetty.xml ===
// Setup Threadpool
QueuedThreadPool threadPool = new QueuedThreadPool();
@@ -61,7 +60,7 @@ public class LikeJettyXml
Server server = new Server(threadPool);
// Scheduler
- server.addBean(new TimerScheduler());
+ server.addBean(new ScheduledExecutorScheduler());
// HTTP Configuration
HttpConfiguration http_config = new HttpConfiguration();
@@ -73,7 +72,7 @@ public class LikeJettyXml
http_config.setSendServerVersion(true);
http_config.setSendDateHeader(false);
// httpConfig.addCustomizer(new ForwardedRequestCustomizer());
-
+
// Handler Structure
HandlerCollection handlers = new HandlerCollection();
ContextHandlerCollection contexts = new ContextHandlerCollection();
@@ -84,21 +83,21 @@ public class LikeJettyXml
server.setDumpAfterStart(false);
server.setDumpBeforeStop(false);
server.setStopAtShutdown(true);
-
- // === jetty-jmx.xml ===
+
+ // === jetty-jmx.xml ===
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
-
- // === jetty-http.xml ===
+
+ // === jetty-http.xml ===
ServerConnector http = new ServerConnector(server,new HttpConnectionFactory(http_config));
http.setPort(8080);
http.setIdleTimeout(30000);
server.addConnector(http);
-
- // === jetty-https.xml ===
+
+ // === jetty-https.xml ===
// SSL Context Factory
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(jetty_home + "/etc/keystore");
@@ -114,11 +113,11 @@ public class LikeJettyXml
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
-
+
// SSL HTTP Configuration
HttpConfiguration https_config = new HttpConfiguration(http_config);
https_config.addCustomizer(new SecureRequestCustomizer());
-
+
// SSL Connector
ServerConnector sslConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,"http/1.1"),
@@ -141,15 +140,15 @@ public class LikeJettyXml
deployer.addAppProvider(webapp_provider);
server.addBean(deployer);
-
- // === jetty-stats.xml ===
+
+ // === jetty-stats.xml ===
StatisticsHandler stats = new StatisticsHandler();
stats.setHandler(server.getHandler());
server.setHandler(stats);
- // === jetty-requestlog.xml ===
+ // === jetty-requestlog.xml ===
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(jetty_home + "/logs/jetty-yyyy_mm_dd.log");
requestLog.setFilenameDateFormat("yyyy_MM_dd");
@@ -163,7 +162,7 @@ public class LikeJettyXml
handlers.addHandler(requestLogHandler);
- // === jetty-lowresources.xml ===
+ // === jetty-lowresources.xml ===
LowResourceMonitor lowResourcesMonitor=new LowResourceMonitor(server);
lowResourcesMonitor.setPeriod(1000);
lowResourcesMonitor.setLowResourcesIdleTimeout(200);
@@ -173,8 +172,8 @@ public class LikeJettyXml
lowResourcesMonitor.setMaxLowResourcesTime(5000);
server.addBean(lowResourcesMonitor);
-
- // === test-realm.xml ===
+
+ // === test-realm.xml ===
HashLoginService login = new HashLoginService();
login.setName("Test Realm");
login.setConfig(jetty_home + "/etc/realm.properties");
@@ -182,7 +181,7 @@ public class LikeJettyXml
server.addBean(login);
- // Start the server
+ // Start the server
server.start();
server.join();
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
index a726705f55..2f79754951 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.annotations;
import java.net.URI;
import java.util.ArrayList;
+import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
@@ -29,6 +30,7 @@ import javax.servlet.annotation.HandlesTypes;
import org.eclipse.jetty.annotations.AnnotationParser.DiscoverableAnnotationHandler;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
+import org.eclipse.jetty.util.ArrayUtil;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@@ -221,10 +223,10 @@ public class AnnotationConfiguration extends AbstractConfiguration
- //add a listener which will call the servletcontainerinitializers when appropriate
+ //add a bean which will call the servletcontainerinitializers when appropriate
ServletContainerInitializerListener listener = new ServletContainerInitializerListener();
listener.setWebAppContext(context);
- context.addEventListener(listener);
+ context.addBean(listener, true);
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializerListener.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializerListener.java
index e36bc272d1..b5ced5b558 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializerListener.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/ServletContainerInitializerListener.java
@@ -22,11 +22,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.util.MultiMap;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;
@@ -36,7 +35,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
*
*
*/
-public class ServletContainerInitializerListener implements ServletContextListener
+public class ServletContainerInitializerListener extends AbstractLifeCycle
{
private static final Logger LOG = Log.getLogger(ServletContainerInitializerListener.class);
protected WebAppContext _context = null;
@@ -47,10 +46,12 @@ public class ServletContainerInitializerListener implements ServletContextListen
_context = context;
}
- /**
- * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+
+ /**
+ * Call the doStart method of the ServletContainerInitializers
+ * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
- public void contextInitialized(ServletContextEvent sce)
+ public void doStart()
{
List<ContainerInitializer> initializers = (List<ContainerInitializer>)_context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
MultiMap classMap = (MultiMap)_context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
@@ -129,12 +130,14 @@ public class ServletContainerInitializerListener implements ServletContextListen
addInheritedTypes (classMap, initializer, implementsOrExtends);
}
}
-
-
- /**
- * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+
+
+
+ /**
+ * Nothing to do for ServletContainerInitializers on stop
+ * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
- public void contextDestroyed(ServletContextEvent sce)
+ public void doStop()
{
}
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
index c43a41c4f1..8b3def6744 100644
--- a/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
+++ b/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java
@@ -45,6 +45,7 @@ abstract public class WriteFlusher
{
private static final Logger LOG = Log.getLogger(WriteFlusher.class);
private static final boolean DEBUG = LOG.isDebugEnabled(); // Easy for the compiler to remove the code if DEBUG==false
+ private static final ByteBuffer[] EMPTY_BUFFERS = new ByteBuffer[0];
private static final EnumMap<StateType, Set<StateType>> __stateTransitions = new EnumMap<>(StateType.class);
private static final State __IDLE = new IdleState();
private static final State __WRITING = new WritingState();
@@ -243,7 +244,7 @@ abstract public class WriteFlusher
private PendingState(ByteBuffer[] buffers, Callback callback)
{
super(StateType.PENDING);
- _buffers = buffers;
+ _buffers = compact(buffers);
_callback = callback;
}
@@ -263,6 +264,44 @@ abstract public class WriteFlusher
if (_callback!=null)
_callback.succeeded();
}
+
+ /**
+ * Compacting the buffers is needed because the semantic of WriteFlusher is
+ * to write the buffers and if the caller sees that the buffer is consumed,
+ * then it can recycle it.
+ * If we do not compact, then it is possible that we store a consumed buffer,
+ * which is then recycled and refilled; when the WriteFlusher is invoked to
+ * complete the write, it will write the refilled bytes, garbling the content.
+ *
+ * @param buffers the buffers to compact
+ * @return the compacted buffers
+ */
+ private ByteBuffer[] compact(ByteBuffer[] buffers)
+ {
+ int length = buffers.length;
+
+ // Just one element, no need to compact
+ if (length < 2)
+ return buffers;
+
+ // How many still have content ?
+ int consumed = 0;
+ while (consumed < length && BufferUtil.isEmpty(buffers[consumed]))
+ ++consumed;
+
+ // All of them still have content, no need to compact
+ if (consumed == 0)
+ return buffers;
+
+ // None has content, return empty
+ if (consumed == length)
+ return EMPTY_BUFFERS;
+
+ int newLength = length - consumed;
+ ByteBuffer[] result = new ByteBuffer[newLength];
+ System.arraycopy(buffers, consumed, result, 0, newLength);
+ return result;
+ }
}
/**
@@ -306,7 +345,7 @@ abstract public class WriteFlusher
if (updateState(__WRITING,pending))
onIncompleteFlushed();
else
- fail(new PendingState(buffers, callback));
+ fail(pending);
return;
}
}
diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java
index b1eeadc478..85fe4f5057 100644
--- a/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java
+++ b/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java
@@ -18,19 +18,11 @@
package org.eclipse.jetty.io;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.WritePendingException;
import java.security.SecureRandom;
+import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -54,16 +46,23 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
@RunWith(MockitoJUnitRunner.class)
public class WriteFlusherTest
{
+ private final AtomicBoolean _flushIncomplete = new AtomicBoolean(false);
+ private final ExecutorService executor = Executors.newFixedThreadPool(16);
@Mock
private EndPoint _endPointMock;
-
private WriteFlusher _flusher;
-
- private final AtomicBoolean _flushIncomplete = new AtomicBoolean(false);
- private final ExecutorService executor = Executors.newFixedThreadPool(16);
private ByteArrayEndPoint _endp;
@Before
@@ -400,6 +399,34 @@ public class WriteFlusherTest
assertThat("callback completed", callback.isDone(), is(true));
}
+ @Test
+ public void testPendingWriteDoesNotStoreConsumedBuffers() throws Exception
+ {
+ int toWrite = _endp.getOutput().capacity();
+ byte[] chunk1 = new byte[toWrite / 2];
+ Arrays.fill(chunk1, (byte)1);
+ ByteBuffer buffer1 = ByteBuffer.wrap(chunk1);
+ byte[] chunk2 = new byte[toWrite];
+ Arrays.fill(chunk1, (byte)2);
+ ByteBuffer buffer2 = ByteBuffer.wrap(chunk2);
+
+ _flusher.write(new Callback.Adapter(), buffer1, buffer2);
+ assertTrue(_flushIncomplete.get());
+ assertFalse(buffer1.hasRemaining());
+
+ // Reuse buffer1
+ buffer1.clear();
+ Arrays.fill(chunk1, (byte)3);
+ int remaining1 = buffer1.remaining();
+
+ // Complete the write
+ _endp.takeOutput();
+ _flusher.completeWrite();
+
+ // Make sure buffer1 is unchanged
+ assertEquals(remaining1, buffer1.remaining());
+ }
+
private class ExposingStateCallback extends FutureCallback
{
private boolean failed = false;
diff --git a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
index 1d32c66442..2e0760f4bd 100644
--- a/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
+++ b/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java
@@ -28,7 +28,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
-
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -52,8 +51,8 @@ import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
/**
* <p>Implementation of a {@link Handler} that supports HTTP CONNECT.</p>
@@ -163,7 +162,7 @@ public class ConnectHandler extends HandlerWrapper
}
if (scheduler == null)
{
- setScheduler(new TimerScheduler());
+ setScheduler(new ScheduledExecutorScheduler());
addBean(getScheduler());
}
if (bufferPool == null)
diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml
index 954ba71173..dd78c54004 100644
--- a/jetty-server/src/main/config/etc/jetty.xml
+++ b/jetty-server/src/main/config/etc/jetty.xml
@@ -14,7 +14,7 @@
<!-- java -jar start.jar -? -->
<!-- =============================================================== -->
-<!-- =============================================================== -->
+<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
@@ -49,13 +49,13 @@
<Set name="detailedDump">false</Set>
</New>
</Arg>
-
+
<!-- =========================================================== -->
<!-- Add shared Scheduler instance -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
- <New class="org.eclipse.jetty.util.thread.TimerScheduler"/>
+ <New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler"/>
</Arg>
</Call>
@@ -83,14 +83,14 @@
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">false</Set>
<Set name="headerCacheSize">512</Set>
-
- <!-- Uncomment to enable handling of X-Forwarded- style headers
+
+ <!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->
</New>
-
+
<!-- =========================================================== -->
<!-- Set the default handler structure for the Server -->
@@ -100,7 +100,7 @@
<!-- DefaultHandler, which handles any requests not handled by -->
<!-- the context handlers. -->
<!-- Other handlers may be added to the "Handlers" collection, -->
- <!-- for example the jetty-requestlog.xml file adds the -->
+ <!-- for example the jetty-requestlog.xml file adds the -->
<!-- RequestLogHandler after the default handler -->
<!-- =========================================================== -->
<Set name="handler">
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
index ca40a390df..bcc13aa3cd 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java
@@ -48,8 +48,8 @@ import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
/**
* <p>An abstract implementation of {@link Connector} that provides a {@link ConnectionFactory} mechanism
@@ -63,7 +63,7 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* </li>
* <li>The {@link Scheduler} service is used to monitor the idle timeouts of all connections and is also made available
* to the connections to time such things as asynchronous request timeouts. The default is to use a new
- * {@link TimerScheduler} instance.
+ * {@link ScheduledExecutorScheduler} instance.
* </li>
* <li>The {@link ByteBufferPool} service is made available to all connections to be used to acquire and release
* {@link ByteBuffer} instances from a pool. The default is to use a new {@link ArrayByteBufferPool} instance.
@@ -151,12 +151,12 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private long _idleTimeout = 30000;
private String _defaultProtocol;
private ConnectionFactory _defaultConnectionFactory;
-
+
/**
* @param server The server this connector will be added to. Must not be null.
* @param executor An executor for this connector or null to use the servers executor
- * @param scheduler A scheduler for this connector or null to either a {@link Scheduler} set as a server bean or if none set, then a new {@link TimerScheduler} instance.
+ * @param scheduler A scheduler for this connector or null to either a {@link Scheduler} set as a server bean or if none set, then a new {@link ScheduledExecutorScheduler} instance.
* @param pool A buffer pool for this connector or null to either a {@link ByteBufferPool} set as a server bean or none set, the new {@link ArrayByteBufferPool} instance.
* @param acceptors the number of acceptor threads to use, or 0 for a default value.
* @param factories The Connection Factories to use.
@@ -173,7 +173,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
_executor=executor!=null?executor:_server.getThreadPool();
if (scheduler==null)
scheduler=_server.getBean(Scheduler.class);
- _scheduler=scheduler!=null?scheduler:new TimerScheduler();
+ _scheduler=scheduler!=null?scheduler:new ScheduledExecutorScheduler();
if (pool==null)
pool=_server.getBean(ByteBufferPool.class);
_byteBufferPool = pool!=null?pool:new ArrayByteBufferPool();
@@ -479,9 +479,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
}
-
-
-
+
+
+
// protected void connectionOpened(Connection connection)
// {
// _stats.connectionOpened();
@@ -512,7 +512,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{
_endpoints.add(endp);
}
-
+
protected void onEndPointClosed(EndPoint endp)
{
_endpoints.remove(endp);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
index d4a1dbb029..3749e04057 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
@@ -32,9 +32,9 @@ import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.ThreadPool;
-import org.eclipse.jetty.util.thread.TimerScheduler;
/* ------------------------------------------------------------ */
@@ -42,7 +42,7 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* <p>An instance of this class will monitor all the connectors of a server (or a set of connectors
* configured with {@link #setMonitoredConnectors(Collection)}) for a low resources state.
* Low resources can be detected by:<ul>
- * <li>{@link ThreadPool#isLowOnThreads()} if {@link Connector#getExecutor()} is
+ * <li>{@link ThreadPool#isLowOnThreads()} if {@link Connector#getExecutor()} is
* an instance of {@link ThreadPool} and {@link #setMonitorThreads(boolean)} is true.<li>
* <li>If {@link #setMaxMemory(long)} is non zero then low resources is detected if the JVMs
* {@link Runtime} instance has {@link Runtime#totalMemory()} minus {@link Runtime#freeMemory()}
@@ -51,11 +51,11 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* of connections exceeds {@link #getMaxConnections()}</li>
* </ul>
* </p>
- * <p>Once low resources state is detected, the cause is logged and all existing connections returned
- * by {@link Connector#getConnectedEndPoints()} have {@link EndPoint#setIdleTimeout(long)} set
- * to {@link #getLowResourcesIdleTimeout()}. New connections are not affected, however if the low
- * resources state persists for more than {@link #getMaxLowResourcesTime()}, then the
- * {@link #getLowResourcesIdleTimeout()} to all connections again. Once the low resources state is
+ * <p>Once low resources state is detected, the cause is logged and all existing connections returned
+ * by {@link Connector#getConnectedEndPoints()} have {@link EndPoint#setIdleTimeout(long)} set
+ * to {@link #getLowResourcesIdleTimeout()}. New connections are not affected, however if the low
+ * resources state persists for more than {@link #getMaxLowResourcesTime()}, then the
+ * {@link #getLowResourcesIdleTimeout()} to all connections again. Once the low resources state is
* cleared, the idle timeout is reset to the connector default given by {@link Connector#getIdleTimeout()}.
* </p>
*/
@@ -76,44 +76,44 @@ public class LowResourceMonitor extends AbstractLifeCycle
private String _cause;
private String _reasons;
private long _lowStarted;
-
-
+
+
private final Runnable _monitor = new Runnable()
{
@Override
public void run()
- {
+ {
if (isRunning())
{
monitor();
_scheduler.schedule(_monitor,_period,TimeUnit.MILLISECONDS);
}
- }
+ }
};
-
+
public LowResourceMonitor(@Name("server") Server server)
{
_server=server;
}
-
+
@ManagedAttribute("Are the monitored connectors low on resources?")
public boolean isLowOnResources()
{
return _low.get();
}
-
+
@ManagedAttribute("The reason(s) the monitored connectors are low on resources")
public String getLowResourcesReasons()
{
return _reasons;
}
-
+
@ManagedAttribute("Get the timestamp in ms since epoch that low resources state started")
public long getLowResourcesStarted()
{
return _lowStarted;
}
-
+
@ManagedAttribute("The monitored connectors. If null then all server connectors are monitored")
public Collection<Connector> getMonitoredConnectors()
{
@@ -140,7 +140,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
/**
- * @param periodMS The period in ms to monitor for low resources
+ * @param periodMS The period in ms to monitor for low resources
*/
public void setPeriod(int periodMS)
{
@@ -154,8 +154,8 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
/**
- * @param monitorThreads If true, check connectors executors to see if they are
- * {@link ThreadPool} instances that are low on threads.
+ * @param monitorThreads If true, check connectors executors to see if they are
+ * {@link ThreadPool} instances that are low on threads.
*/
public void setMonitorThreads(boolean monitorThreads)
{
@@ -222,14 +222,14 @@ public class LowResourceMonitor extends AbstractLifeCycle
protected void doStart() throws Exception
{
_scheduler = _server.getBean(Scheduler.class);
-
+
if (_scheduler==null)
{
_scheduler=new LRMScheduler();
_scheduler.start();
}
super.doStart();
-
+
_scheduler.schedule(_monitor,_period,TimeUnit.MILLISECONDS);
}
@@ -240,24 +240,24 @@ public class LowResourceMonitor extends AbstractLifeCycle
_scheduler.stop();
super.doStop();
}
-
+
protected Connector[] getMonitoredOrServerConnectors()
{
if (_monitoredConnectors!=null && _monitoredConnectors.length>0)
return _monitoredConnectors;
return _server.getConnectors();
}
-
+
protected void monitor()
{
String reasons=null;
String cause="";
int connections=0;
-
+
for(Connector connector : getMonitoredOrServerConnectors())
{
connections+=connector.getConnectedEndPoints().size();
-
+
Executor executor = connector.getExecutor();
if (executor instanceof ThreadPool)
{
@@ -269,21 +269,21 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
}
}
-
+
if (_maxConnections>0 && connections>_maxConnections)
{
reasons=low(reasons,"Max Connections exceeded: "+connections+">"+_maxConnections);
cause+="C";
}
-
+
long memory=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
if (_maxMemory>0 && memory>_maxMemory)
{
reasons=low(reasons,"Max memory exceeded: "+memory+">"+_maxMemory);
cause+="M";
}
-
-
+
+
if (reasons!=null)
{
// Log the reasons if there is any change in the cause
@@ -292,7 +292,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
LOG.warn("Low Resources: {}",reasons);
_cause=cause;
}
-
+
// Enter low resources state?
if (_low.compareAndSet(false,true))
{
@@ -300,12 +300,12 @@ public class LowResourceMonitor extends AbstractLifeCycle
_lowStarted=System.currentTimeMillis();
setLowResources();
}
-
+
// Too long in low resources state?
if (_maxLowResourcesTime>0 && (System.currentTimeMillis()-_lowStarted)>_maxLowResourcesTime)
setLowResources();
}
- else
+ else
{
if (_low.compareAndSet(true,false))
{
@@ -316,7 +316,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
}
}
-
+
protected void setLowResources()
{
for(Connector connector : getMonitoredOrServerConnectors())
@@ -325,7 +325,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
endPoint.setIdleTimeout(_lowResourcesIdleTimeout);
}
}
-
+
protected void clearLowResources()
{
for(Connector connector : getMonitoredOrServerConnectors())
@@ -334,16 +334,16 @@ public class LowResourceMonitor extends AbstractLifeCycle
endPoint.setIdleTimeout(connector.getIdleTimeout());
}
}
-
+
private String low(String reasons, String newReason)
{
if (reasons==null)
return newReason;
return reasons+", "+newReason;
}
-
-
- private static class LRMScheduler extends TimerScheduler
+
+
+ private static class LRMScheduler extends ScheduledExecutorScheduler
{
}
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index abd240ddcf..cb2d54fe2b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -2097,6 +2097,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
if (!_enabled)
throw new UnsupportedOperationException();
ContextHandler.this.addEventListener(t);
+ ContextHandler.this.addProgrammaticListener(t);
}
@Override
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
index 4bb4113cb5..a73a07b9bf 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java
@@ -995,7 +995,7 @@ public class DoSFilter implements Filter
* @see #addWhitelistAddress(List, String)
*/
@ManagedOperation("removes an IP address that will not be rate limited")
- public boolean removeWhitelistAddress(String address)
+ public boolean removeWhitelistAddress(@Name("address") String address)
{
return _whitelist.remove(address);
}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
index 8970dcafab..2a23c5f2c1 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
@@ -30,7 +30,6 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
-
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.ByteBufferPool;
@@ -50,8 +49,8 @@ import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
public class SPDYClient
{
@@ -202,7 +201,7 @@ public class SPDYClient
addBean(executor);
if (scheduler == null)
- scheduler = new TimerScheduler();
+ scheduler = new ScheduledExecutorScheduler();
this.scheduler = scheduler;
addBean(scheduler);
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/LogicalConnection.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/LogicalConnection.java
index 1bc7366ee5..dd6431d0c9 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/LogicalConnection.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/LogicalConnection.java
@@ -74,6 +74,12 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
InetSocketAddress getLocalAddress();
/**
+ * Set the maximum number of milliseconds of idleness before the connection is closed/disconnected, (ie no frames are either sent or received)
+ * @return the idle timeout in milliseconds
+ */
+ long getMaxIdleTimeout();
+
+ /**
* The policy that the connection is running under.
* @return the policy for the connection
*/
@@ -110,6 +116,14 @@ public interface LogicalConnection extends OutgoingFrames, SuspendToken
boolean isReading();
/**
+ * Set the maximum number of milliseconds of idleness before the connection is closed/disconnected, (ie no frames are either sent or received)
+ *
+ * @param ms
+ * the number of milliseconds of idle timeout
+ */
+ void setMaxIdleTimeout(long ms);
+
+ /**
* Set where the connection should send the incoming frames to.
* <p>
* Often this is from the Parser to the start of the extension stack, and eventually on to the session.
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
index 0d648c6ada..cb80189b5f 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java
@@ -59,7 +59,6 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
private ExtensionFactory extensionFactory;
private long maximumMessageSize;
private String protocolVersion;
- private long timeout;
private Map<String, String[]> parameterMap = new HashMap<>();
private WebSocketRemoteEndpoint remote;
private IncomingFrames incomingHandler;
@@ -165,12 +164,12 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
}
/**
- * The idle timeout in seconds
+ * The idle timeout in milliseconds
*/
@Override
public long getIdleTimeout()
{
- return timeout;
+ return connection.getMaxIdleTimeout();
}
@ManagedAttribute(readonly = true)
@@ -320,12 +319,12 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Inc
}
/**
- * Set the timeout in seconds
+ * Set the timeout in milliseconds
*/
@Override
- public void setIdleTimeout(long seconds)
+ public void setIdleTimeout(long ms)
{
- this.timeout = seconds;
+ connection.setMaxIdleTimeout(ms);
}
@Override
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/mux/MuxChannel.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/mux/MuxChannel.java
index 3e56bbd56f..b8bd82508f 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/mux/MuxChannel.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/mux/MuxChannel.java
@@ -112,6 +112,13 @@ public class MuxChannel implements LogicalConnection, IncomingFrames, SuspendTok
}
@Override
+ public long getMaxIdleTimeout()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
public WebSocketPolicy getPolicy()
{
return policy;
@@ -206,6 +213,13 @@ public class MuxChannel implements LogicalConnection, IncomingFrames, SuspendTok
}
@Override
+ public void setMaxIdleTimeout(long ms)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
public void setNextIncomingFrames(IncomingFrames incoming)
{
this.incoming = incoming;
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
index 289be61b17..12091c194c 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java
@@ -347,6 +347,12 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
return ioState;
}
+ @Override
+ public long getMaxIdleTimeout()
+ {
+ return getEndPoint().getIdleTimeout();
+ }
+
public Parser getParser()
{
return parser;
@@ -569,6 +575,12 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
}
@Override
+ public void setMaxIdleTimeout(long ms)
+ {
+ getEndPoint().setIdleTimeout(ms);
+ }
+
+ @Override
public void setSession(WebSocketSession session)
{
this.session = session;
diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketConnection.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketConnection.java
index 7099af3ac4..5387af30d0 100644
--- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketConnection.java
+++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/io/LocalWebSocketConnection.java
@@ -92,6 +92,13 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
}
@Override
+ public long getMaxIdleTimeout()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
public WebSocketPolicy getPolicy()
{
return policy;
@@ -149,6 +156,13 @@ public class LocalWebSocketConnection implements LogicalConnection, IncomingFram
}
@Override
+ public void setMaxIdleTimeout(long ms)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
public void setNextIncomingFrames(IncomingFrames incoming)
{
this.incoming = incoming;
diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
index e5f75af903..edffd2f172 100644
--- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
+++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java
@@ -27,7 +27,6 @@ import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
-
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -39,8 +38,8 @@ import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.UpgradeResponse;
import org.eclipse.jetty.websocket.api.WebSocketException;
@@ -83,7 +82,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
/**
* Have the factory maintain 1 and only 1 scheduler. All connections share this scheduler.
*/
- private final Scheduler scheduler = new TimerScheduler();
+ private final Scheduler scheduler = new ScheduledExecutorScheduler();
private final String supportedVersions;
private final WebSocketPolicy basePolicy;
private final EventDriverFactory eventDriverFactory;
@@ -308,7 +307,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
/*
* (non-Javadoc)
- *
+ *
* @see org.eclipse.jetty.websocket.server.WebSocketServletFactory#register(java.lang.Class)
*/
@Override
@@ -349,7 +348,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
* <p>
* This method will not normally return, but will instead throw a UpgradeConnectionException, to exit HTTP handling and initiate WebSocket handling of the
* connection.
- *
+ *
* @param request
* The request to upgrade
* @param response
diff --git a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java
index 355accfbae..609a812625 100644
--- a/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java
+++ b/jetty-websocket/websocket-servlet/src/main/java/org/eclipse/jetty/websocket/servlet/WebSocketServlet.java
@@ -42,15 +42,17 @@ import org.eclipse.jetty.websocket.api.annotations.WebSocket;
* <pre>
* package my.example;
*
- * import javax.servlet.http.HttpServletRequest;
- * import org.eclipse.jetty.websocket.WebSocket;
- * import org.eclipse.jetty.websocket.server.WebSocketServlet;
+ * import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
+ * import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
*
* public class MyEchoServlet extends WebSocketServlet
* {
* &#064;Override
- * public void registerWebSockets(WebSocketServerFactory factory)
+ * public void configure(WebSocketServletFactory factory)
* {
+ * // set a 10 second idle timeout
+ * factory.getPolicy().setIdleTimeout(10000);
+ * // register my socket
* factory.register(MyEchoSocket.class);
* }
* }
diff --git a/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleServlet.java b/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleServlet.java
new file mode 100644
index 0000000000..b81559a754
--- /dev/null
+++ b/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleServlet.java
@@ -0,0 +1,35 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package examples;
+
+import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
+import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
+
+@SuppressWarnings("serial")
+public class MyExampleServlet extends WebSocketServlet
+{
+ @Override
+ public void configure(WebSocketServletFactory factory)
+ {
+ // set a 10 second timeout
+ factory.getPolicy().setIdleTimeout(10000);
+ // register my socket
+ factory.register(MyExampleSocket.class);
+ }
+}
diff --git a/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleSocket.java b/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleSocket.java
new file mode 100644
index 0000000000..cffefaa6c8
--- /dev/null
+++ b/jetty-websocket/websocket-servlet/src/test/java/examples/MyExampleSocket.java
@@ -0,0 +1,34 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package examples;
+
+import org.eclipse.jetty.websocket.api.WebSocketAdapter;
+
+/**
+ * Example WebSocket, simple echo
+ */
+public class MyExampleSocket extends WebSocketAdapter
+{
+ @Override
+ public void onWebSocketText(String message)
+ {
+ // Echo message back, asynchronously
+ getSession().getRemote().sendStringByFuture(message);
+ }
+}
diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/FooInitializer.java b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/FooInitializer.java
index 1f1a46699a..c07863ed46 100644
--- a/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/FooInitializer.java
+++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/src/main/java/com/acme/FooInitializer.java
@@ -23,17 +23,80 @@ import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
@HandlesTypes ({javax.servlet.Servlet.class, Foo.class})
public class FooInitializer implements ServletContainerInitializer
{
+ public static class BarListener implements ServletContextListener
+ {
+
+ /**
+ * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+ */
+ @Override
+ public void contextInitialized(ServletContextEvent sce)
+ {
+ throw new IllegalStateException("BAR LISTENER CALLED!");
+ }
+
+ /**
+ * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+ */
+ @Override
+ public void contextDestroyed(ServletContextEvent sce)
+ {
+
+ }
+
+ }
+ public static class FooListener implements ServletContextListener
+ {
+
+ /**
+ * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+ */
+ @Override
+ public void contextInitialized(ServletContextEvent sce)
+ {
+ //Can add a ServletContextListener from a ServletContainerInitializer
+ sce.getServletContext().setAttribute("com.acme.AnnotationTest.listenerTest", Boolean.TRUE);
+
+ //Can't add a ServletContextListener from a ServletContextListener
+ try
+ {
+ sce.getServletContext().addListener(new BarListener());
+ sce.getServletContext().setAttribute("com.acme.AnnotationTest.listenerRegoTest", Boolean.FALSE);
+ }
+ catch (UnsupportedOperationException e)
+ {
+ sce.getServletContext().setAttribute("com.acme.AnnotationTest.listenerRegoTest", Boolean.TRUE);
+ }
+ catch (Exception e)
+ {
+ sce.getServletContext().setAttribute("com.acme.AnnotationTest.listenerRegoTest", Boolean.FALSE);
+ }
+ }
+
+ /**
+ * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+ */
+ @Override
+ public void contextDestroyed(ServletContextEvent sce)
+ {
+
+ }
+
+ }
public void onStartup(Set<Class<?>> classes, ServletContext context)
{
context.setAttribute("com.acme.Foo", new ArrayList<Class>(classes));
ServletRegistration.Dynamic reg = context.addServlet("AnnotationTest", "com.acme.AnnotationTest");
context.setAttribute("com.acme.AnnotationTest.complete", (reg == null));
+ context.addListener(new FooListener());
}
}
diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java
index f6b319a983..b3eecea853 100644
--- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java
+++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/AnnotationTest.java
@@ -245,6 +245,14 @@ public class AnnotationTest extends HttpServlet
Boolean complete = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.complete");
out.println("<br/><b>Result: "+(complete.booleanValue()?"PASS":"FAIL")+"</b>");
+ out.println("<h2>ServletContextListener Programmatic Registration from ServletContainerInitializer</h2>");
+ Boolean programmaticListener = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.listenerTest");
+ out.println("<br/><b>Result: "+(programmaticListener.booleanValue()?"PASS":"FAIL")+"</b>");
+
+ out.println("<h2>ServletContextListener Programmatic Registration Prevented from ServletContextListener</h2>");
+ Boolean programmaticListenerPrevention = (Boolean)config.getServletContext().getAttribute("com.acme.AnnotationTest.listenerRegoTest");
+ out.println("<br/><b>Result: "+(programmaticListenerPrevention.booleanValue()?"PASS":"FAIL")+"</b>");
+
out.println("<h2>@PostConstruct Callback</h2>");
out.println("<pre>");
out.println("@PostConstruct");

Back to the top