Merge branch 'master' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project

This commit is contained in:
Joakim Erdfelt 2011-08-30 12:20:42 -07:00
commit 570222da94
44 changed files with 578 additions and 376 deletions

View File

@ -1,7 +1,11 @@
jetty-7.5.0-SNAPSHOT jetty-7.5.0-SNAPSHOT
+ 352188 TestClient correctly processes --host option in jetty-websocket
+ 353014 TimeoutExchangeTest run time reduced
+ 353623 Added new methods to HttpExchange + 353623 Added new methods to HttpExchange
+ 353624 HttpURI accepts java.net.URI object in constructor + 353624 HttpURI accepts java.net.URI object in constructor
+ 354080 ServletContextHandler allows to replace any subordinate handler when restarted + 354080 ServletContextHandler allows to replace any subordinate handler when restarted
+ 356128 Moved integration tests from jetty-monitor to test-integration module
+ 356137 Upgrade to jsp implementation version 2.1.3-b10
jetty-7.5.0.RC1 - 19 August 2011 jetty-7.5.0.RC1 - 19 August 2011
+ 276670 SLF4J loggers show correct location information + 276670 SLF4J loggers show correct location information

View File

@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Timeout; import org.eclipse.jetty.util.thread.Timeout;
class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector, Runnable class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector
{ {
private static final Logger LOG = Log.getLogger(SelectConnector.class); private static final Logger LOG = Log.getLogger(SelectConnector.class);
@ -65,7 +65,6 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
{ {
super.doStart(); super.doStart();
_selectorManager.start();
final boolean direct=_httpClient.getUseDirectBuffers(); final boolean direct=_httpClient.getUseDirectBuffers();
@ -76,7 +75,7 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
direct?Type.DIRECT:Type.INDIRECT,ssl_session.getApplicationBufferSize(), direct?Type.DIRECT:Type.INDIRECT,ssl_session.getApplicationBufferSize(),
direct?Type.DIRECT:Type.INDIRECT,1024); direct?Type.DIRECT:Type.INDIRECT,1024);
_httpClient._threadPool.dispatch(this); _selectorManager.start();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -117,25 +116,6 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
{ {
destination.onConnectionFailed(ex); destination.onConnectionFailed(ex);
} }
}
/* ------------------------------------------------------------ */
public void run()
{
while (_httpClient.isRunning())
{
try
{
_selectorManager.doSelect(0);
}
catch (Exception e)
{
LOG.warn(e.toString());
LOG.debug(e);
Thread.yield();
}
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
@ -322,7 +323,7 @@ public abstract class AbstractHttpExchangeCancelTest
{ {
try try
{ {
((StdErrLog)Log.getLog()).setHideStacks(!LOG.isDebugEnabled()); ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
TestHttpExchange exchange = new TestHttpExchange(); TestHttpExchange exchange = new TestHttpExchange();
exchange.setAddress(newAddress()); exchange.setAddress(newAddress());
exchange.setRequestURI("/?action=throw"); exchange.setRequestURI("/?action=throw");
@ -337,7 +338,7 @@ public abstract class AbstractHttpExchangeCancelTest
} }
finally finally
{ {
((StdErrLog)Log.getLog()).setHideStacks(false); ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
} }
} }

View File

@ -139,36 +139,37 @@ public class ProxyFakeTunnelTest extends ProxyTunnellingTest
} }
out.flush(); out.flush();
System.err.println(toserver); if (toserver!=null)
final InputStream from = toserver.getInputStream();
Thread copy = new Thread()
{ {
public void run() final InputStream from = toserver.getInputStream();
Thread copy = new Thread()
{ {
try public void run()
{
IO.copy(from,out);
out.close();
}
catch (IOException e)
{
}
finally
{ {
try try
{ {
IO.copy(from,out);
out.close(); out.close();
} }
catch (IOException e) catch (IOException e)
{ {
} }
finally
{
try
{
out.close();
}
catch (IOException e)
{
}
}
} }
} };
}; copy.setDaemon(true);
copy.setDaemon(true); copy.start();
copy.start(); }
} }
else else

View File

@ -16,11 +16,13 @@ package org.eclipse.jetty.client;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junit.framework.Assert; import junit.framework.Assert;
import org.eclipse.jetty.http.HttpMethods; import org.eclipse.jetty.http.HttpMethods;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.io.ByteArrayBuffer;
@ -31,29 +33,18 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
public class TimeoutExchangeTest public class TimeoutExchangeTest
{ {
private HttpClient _httpClient; private static HttpClient _httpClient;
private Server _server; private static Server _server;
private int _port; private static int _port;
@Before @BeforeClass
public void setUp() throws Exception public static void startServer() throws Exception
{
startServer();
}
@After
public void tearDown() throws Exception
{
stopClient();
stopServer();
}
private void startServer() throws Exception
{ {
_server = new Server(); _server = new Server();
_server.setGracefulShutdown(500); _server.setGracefulShutdown(500);
@ -61,7 +52,8 @@ public class TimeoutExchangeTest
_server.addConnector(_connector); _server.addConnector(_connector);
Handler handler = new AbstractHandler() Handler handler = new AbstractHandler()
{ {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException
{ {
try try
{ {
@ -84,13 +76,24 @@ public class TimeoutExchangeTest
_port = _connector.getLocalPort(); _port = _connector.getLocalPort();
} }
private void stopServer() throws Exception @AfterClass
public static void stopServer() throws Exception
{ {
_server.stop(); _server.stop();
_server.join(); _server.join();
_server = null; _server = null;
} }
@After
public void stopClient() throws Exception
{
if (_httpClient != null)
{
_httpClient.stop();
_httpClient = null;
}
}
private void startClient(long clientTimeout) throws Exception private void startClient(long clientTimeout) throws Exception
{ {
startClient(clientTimeout, 20000); startClient(clientTimeout, 20000);
@ -106,17 +109,11 @@ public class TimeoutExchangeTest
_httpClient.start(); _httpClient.start();
} }
private void stopClient() throws Exception
{
_httpClient.stop();
// Thread.sleep(500);
}
@Test @Test
public void testDefaultTimeoutNotExpiring() throws Exception public void testDefaultTimeoutNotExpiring() throws Exception
{ {
startClient(1000); startClient(300);
long serverSleep = 500; long serverSleep = 100;
CustomContentExchange httpExchange = new CustomContentExchange(); CustomContentExchange httpExchange = new CustomContentExchange();
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep); httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
@ -133,8 +130,8 @@ public class TimeoutExchangeTest
@Test @Test
public void testDefaultTimeoutExpiring() throws Exception public void testDefaultTimeoutExpiring() throws Exception
{ {
startClient(500); startClient(100);
long serverSleep = 1000; long serverSleep = 200;
CustomContentExchange httpExchange = new CustomContentExchange(); CustomContentExchange httpExchange = new CustomContentExchange();
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep); httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
@ -151,9 +148,9 @@ public class TimeoutExchangeTest
@Test @Test
public void testExchangeTimeoutNotExpiring() throws Exception public void testExchangeTimeoutNotExpiring() throws Exception
{ {
startClient(500); startClient(100);
long serverSleep = 1000; long serverSleep = 200;
long exchangeTimeout = 1500; long exchangeTimeout = 300;
CustomContentExchange httpExchange = new CustomContentExchange(); CustomContentExchange httpExchange = new CustomContentExchange();
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep); httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
@ -171,9 +168,10 @@ public class TimeoutExchangeTest
@Test @Test
public void testExchangeTimeoutExpiring() throws Exception public void testExchangeTimeoutExpiring() throws Exception
{ {
startClient(5000); startClient(1000);
long serverSleep = 1000;
long exchangeTimeout = 500; long serverSleep = 200;
long exchangeTimeout = 100;
CustomContentExchange httpExchange = new CustomContentExchange(); CustomContentExchange httpExchange = new CustomContentExchange();
httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep); httpExchange.setURL("http://localhost:" + _port + "/?sleep=" + serverSleep);
@ -191,8 +189,8 @@ public class TimeoutExchangeTest
@Test @Test
public void testDefaultTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception public void testDefaultTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception
{ {
startClient(3000, 1000); startClient(500,150);
long serverSleep = 2000; long serverSleep = 300;
// The idle timeout is shorter than the default timeout, but will be // The idle timeout is shorter than the default timeout, but will be
// temporarily increased on the endpoint in order for the exchange to complete. // temporarily increased on the endpoint in order for the exchange to complete.
@ -212,9 +210,9 @@ public class TimeoutExchangeTest
@Test @Test
public void testExchangeTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception public void testExchangeTimeoutWithSmallerIdleTimeoutNotExpiring() throws Exception
{ {
startClient(4000, 3000); startClient(500,150);
long serverSleep = 1000; long serverSleep = 150;
long exchangeTimeout = 2000; long exchangeTimeout = 300;
// The idle timeout is shorter than the default timeout, but will be // The idle timeout is shorter than the default timeout, but will be
// temporarily increased on the endpoint in order for the exchange to complete. // temporarily increased on the endpoint in order for the exchange to complete.

View File

@ -20,7 +20,8 @@
<orbit-javax-servlet-jsp-version>2.1.0.v201004190952</orbit-javax-servlet-jsp-version> <orbit-javax-servlet-jsp-version>2.1.0.v201004190952</orbit-javax-servlet-jsp-version>
<orbit-javax-servlet-jsp-jstl-version>1.2.0.v201004190952</orbit-javax-servlet-jsp-jstl-version> <orbit-javax-servlet-jsp-jstl-version>1.2.0.v201004190952</orbit-javax-servlet-jsp-jstl-version>
<orbit-com-sun-el-version>1.0.0.v201004190952</orbit-com-sun-el-version> <orbit-com-sun-el-version>1.0.0.v201004190952</orbit-com-sun-el-version>
<orbit-org-apache-jasper-version>2.1.0.v201007080150</orbit-org-apache-jasper-version> <!-- orbit-org-apache-jasper-version>2.1.0.v201007080150</orbit-org-apache-jasper-version -->
<central-jsp-version>2.1.3-b10</central-jsp-version>
<orbit-org-apache-taglibs-standard-version>1.2.0.v201004190952</orbit-org-apache-taglibs-standard-version> <orbit-org-apache-taglibs-standard-version>1.2.0.v201004190952</orbit-org-apache-taglibs-standard-version>
<orbit-org-objectweb-asm-version>3.1.0.v200803061910</orbit-org-objectweb-asm-version> <orbit-org-objectweb-asm-version>3.1.0.v200803061910</orbit-org-objectweb-asm-version>
<orbit-javax-transaction-version>1.1.1.v201004190952</orbit-javax-transaction-version> <orbit-javax-transaction-version>1.1.1.v201004190952</orbit-javax-transaction-version>
@ -76,7 +77,7 @@
<url url="${jetty-orbit-url}/javax.servlet.jsp_${orbit-javax-servlet-jsp-version}.jar" /> <url url="${jetty-orbit-url}/javax.servlet.jsp_${orbit-javax-servlet-jsp-version}.jar" />
<url url="${jetty-orbit-url}/javax.servlet.jsp.jstl_${orbit-javax-servlet-jsp-jstl-version}.jar" /> <url url="${jetty-orbit-url}/javax.servlet.jsp.jstl_${orbit-javax-servlet-jsp-jstl-version}.jar" />
<url url="${jetty-orbit-url}/com.sun.el_${orbit-com-sun-el-version}.jar" /> <url url="${jetty-orbit-url}/com.sun.el_${orbit-com-sun-el-version}.jar" />
<url url="${jetty-orbit-url}/org.apache.jasper.glassfish_${orbit-org-apache-jasper-version}.jar" /> <!-- url url="${jetty-orbit-url}/org.apache.jasper.glassfish_${orbit-org-apache-jasper-version}.jar" / -->
<url url="${jetty-orbit-url}/org.apache.taglibs.standard.glassfish_${orbit-org-apache-taglibs-standard-version}.jar" /> <url url="${jetty-orbit-url}/org.apache.taglibs.standard.glassfish_${orbit-org-apache-taglibs-standard-version}.jar" />
<url url="${jetty-orbit-url}/org.objectweb.asm_${orbit-org-objectweb-asm-version}.jar" /> <url url="${jetty-orbit-url}/org.objectweb.asm_${orbit-org-objectweb-asm-version}.jar" />
<url url="${jetty-orbit-url}/javax.transaction_${orbit-javax-transaction-version}.jar" /> <url url="${jetty-orbit-url}/javax.transaction_${orbit-javax-transaction-version}.jar" />
@ -544,6 +545,15 @@
<includes>**</includes> <includes>**</includes>
<outputDirectory>${assembly-directory}/lib/jsp</outputDirectory> <outputDirectory>${assembly-directory}/lib/jsp</outputDirectory>
</artifactItem> </artifactItem>
<artifactItem>
<groupId>org.glassfish.web</groupId>
<artifactId>jsp-impl</artifactId>
<version>${central-jsp-version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<includes>**</includes>
<outputDirectory>${assembly-directory}/lib/jsp</outputDirectory>
</artifactItem>
</artifactItems> </artifactItems>
</configuration> </configuration>
</execution> </execution>
@ -663,5 +673,10 @@
<artifactId>jetty-jsp-2.1</artifactId> <artifactId>jetty-jsp-2.1</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jsp-impl</artifactId>
<version>${central-jsp-version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -114,7 +114,7 @@ public abstract class AbstractGenerator implements Generator
_contentLength = HttpTokens.UNKNOWN_CONTENT; _contentLength = HttpTokens.UNKNOWN_CONTENT;
_date = null; _date = null;
// always return the buffer // always return the body buffer
if (_buffer!=null) if (_buffer!=null)
_buffers.returnBuffer(_buffer); _buffers.returnBuffer(_buffer);
_buffer=null; _buffer=null;
@ -132,6 +132,22 @@ public abstract class AbstractGenerator implements Generator
_method=null; _method=null;
} }
/* ------------------------------------------------------------------------------- */
public void returnBuffers()
{
if (_buffer!=null && _buffer.length()==0)
{
_buffers.returnBuffer(_buffer);
_buffer=null;
}
if (_header!=null && _header.length()==0)
{
_buffers.returnBuffer(_header);
_header=null;
}
}
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public void resetBuffer() public void resetBuffer()
{ {

View File

@ -73,6 +73,8 @@ public interface Generator
void reset(boolean returnBuffers); void reset(boolean returnBuffers);
void resetBuffer(); void resetBuffer();
void returnBuffers();
void sendError(int code, String reason, String content, boolean close) throws IOException; void sendError(int code, String reason, String content, boolean close) throws IOException;

View File

@ -250,7 +250,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
public void checkIdleTimestamp(long now) public void checkIdleTimestamp(long now)
{ {
long idleTimestamp=_idleTimestamp; long idleTimestamp=_idleTimestamp;
if (idleTimestamp!=0 && _maxIdleTime!=0 && now>(idleTimestamp+_maxIdleTime)) if (idleTimestamp!=0 && _maxIdleTime>0 && now>(idleTimestamp+_maxIdleTime))
idleExpired(); idleExpired();
} }

View File

@ -54,7 +54,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
*/ */
public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable
{ {
public static final Logger __log=Log.getLogger("org.eclipse.jetty.io.nio"); public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio");
// TODO Tune these by approx system speed. // TODO Tune these by approx system speed.
private static final int __JVMBUG_THRESHHOLD=Integer.getInteger("org.eclipse.jetty.io.nio.JVMBUG_THRESHHOLD",0).intValue(); private static final int __JVMBUG_THRESHHOLD=Integer.getInteger("org.eclipse.jetty.io.nio.JVMBUG_THRESHHOLD",0).intValue();
@ -71,6 +71,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
private int _selectSets=1; private int _selectSets=1;
private volatile int _set; private volatile int _set;
private boolean _deferringInterestedOps0=true; private boolean _deferringInterestedOps0=true;
private int _selectorPriorityDelta=0;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -178,6 +179,25 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
set.wakeup(); set.wakeup();
} }
/* ------------------------------------------------------------ */
/**
* @return delta The value to add to the selector thread priority.
*/
public int getSelectorPriorityDelta()
{
return _selectorPriorityDelta;
}
/* ------------------------------------------------------------ */
/** Set the selector thread priorty delta.
* @param delta The value to add to the selector thread priority.
*/
public void setSelectorPriorityDelta(int delta)
{
_selectorPriorityDelta=delta;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* @return the lowResourcesConnections * @return the lowResourcesConnections
@ -218,17 +238,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
_lowResourcesMaxIdleTime=(int)lowResourcesMaxIdleTime; _lowResourcesMaxIdleTime=(int)lowResourcesMaxIdleTime;
} }
/* ------------------------------------------------------------ */
/**
* @param acceptorID
* @throws IOException
*/
public void doSelect(int acceptorID) throws IOException
{
SelectSet[] sets= _selectSet;
if (sets!=null && sets.length>acceptorID && sets[acceptorID]!=null)
sets[acceptorID].doSelect();
}
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
public abstract boolean dispatch(Runnable task); public abstract boolean dispatch(Runnable task);
@ -245,6 +254,59 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
_selectSet[i]= new SelectSet(i); _selectSet[i]= new SelectSet(i);
super.doStart(); super.doStart();
// start a thread to Select
for (int i=0;i<getSelectSets();i++)
{
final int id=i;
dispatch(new Runnable()
{
public void run()
{
String name=Thread.currentThread().getName();
int priority=Thread.currentThread().getPriority();
try
{
SelectSet[] sets=_selectSet;
if (sets==null)
return;
SelectSet set=sets[id];
Thread.currentThread().setName(name+" Selector"+id);
if (getSelectorPriorityDelta()!=0)
Thread.currentThread().setPriority(Thread.currentThread().getPriority()+getSelectorPriorityDelta());
LOG.debug("Starting {} on {}",Thread.currentThread(),this);
while (isRunning())
{
try
{
set.doSelect();
}
catch(ThreadDeath e)
{
throw e;
}
catch(IOException e)
{
LOG.ignore(e);
}
catch(Exception e)
{
LOG.warn(e);
}
}
}
finally
{
LOG.debug("Stopped {} on {}",Thread.currentThread(),this);
Thread.currentThread().setName(name);
if (getSelectorPriorityDelta()!=0)
Thread.currentThread().setPriority(priority);
}
}
});
}
} }
@ -297,8 +359,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment) protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment)
{ {
__log.warn(ex+","+channel+","+attachment); LOG.warn(ex+","+channel+","+attachment);
__log.debug(ex); LOG.debug(ex);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -449,7 +511,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch (CancelledKeyException e) catch (CancelledKeyException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
catch (Throwable e) catch (Throwable e)
{ {
@ -457,9 +519,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
throw (ThreadDeath)e; throw (ThreadDeath)e;
if (isRunning()) if (isRunning())
__log.warn(e); LOG.warn(e);
else else
__log.debug(e); LOG.debug(e);
try try
{ {
@ -467,7 +529,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(IOException e2) catch(IOException e2)
{ {
__log.debug(e2); LOG.debug(e2);
} }
} }
} }
@ -491,7 +553,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(InterruptedException e) catch(InterruptedException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
now=System.currentTimeMillis(); now=System.currentTimeMillis();
} }
@ -585,14 +647,14 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch (CancelledKeyException e) catch (CancelledKeyException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
catch (Exception e) catch (Exception e)
{ {
if (isRunning()) if (isRunning())
__log.warn(e); LOG.warn(e);
else else
__log.ignore(e); LOG.ignore(e);
try try
{ {
@ -601,7 +663,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(IOException e2) catch(IOException e2)
{ {
__log.debug(e2); LOG.debug(e2);
} }
if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid()) if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid())
@ -646,13 +708,13 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
catch (ClosedSelectorException e) catch (ClosedSelectorException e)
{ {
if (isRunning()) if (isRunning())
__log.warn(e); LOG.warn(e);
else else
__log.ignore(e); LOG.ignore(e);
} }
catch (CancelledKeyException e) catch (CancelledKeyException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
finally finally
{ {
@ -687,16 +749,16 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
if (now>_log) if (now>_log)
{ {
if (_paused>0) if (_paused>0)
__log.debug(this+" Busy selector - injecting delay "+_paused+" times"); LOG.debug(this+" Busy selector - injecting delay "+_paused+" times");
if (_jvmFix2>0) if (_jvmFix2>0)
__log.debug(this+" JVM BUG(s) - injecting delay"+_jvmFix2+" times"); LOG.debug(this+" JVM BUG(s) - injecting delay"+_jvmFix2+" times");
if (_jvmFix1>0) if (_jvmFix1>0)
__log.debug(this+" JVM BUG(s) - recreating selector "+_jvmFix1+" times, cancelled keys "+_jvmFix0+" times"); LOG.debug(this+" JVM BUG(s) - recreating selector "+_jvmFix1+" times, cancelled keys "+_jvmFix0+" times");
else if(__log.isDebugEnabled() && _jvmFix0>0) else if(LOG.isDebugEnabled() && _jvmFix0>0)
__log.debug(this+" JVM BUG(s) - cancelled keys "+_jvmFix0+" times"); LOG.debug(this+" JVM BUG(s) - cancelled keys "+_jvmFix0+" times");
_paused=0; _paused=0;
_jvmFix2=0; _jvmFix2=0;
_jvmFix1=0; _jvmFix1=0;
@ -720,7 +782,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(InterruptedException e) catch(InterruptedException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
} }
else if (_jvmBug==__JVMBUG_THRESHHOLD) else if (_jvmBug==__JVMBUG_THRESHHOLD)
@ -754,7 +816,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
if (++_busyKeyCount>__BUSY_KEY && !(busy.channel() instanceof ServerSocketChannel)) if (++_busyKeyCount>__BUSY_KEY && !(busy.channel() instanceof ServerSocketChannel))
{ {
final SelectChannelEndPoint endpoint = (SelectChannelEndPoint)busy.attachment(); final SelectChannelEndPoint endpoint = (SelectChannelEndPoint)busy.attachment();
__log.warn("Busy Key "+busy.channel()+" "+endpoint); LOG.warn("Busy Key "+busy.channel()+" "+endpoint);
busy.cancel(); busy.cancel();
if (endpoint!=null) if (endpoint!=null)
{ {
@ -768,7 +830,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch (IOException e) catch (IOException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
} }
}); });
@ -907,7 +969,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(Exception e) catch(Exception e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
// close endpoints and selector // close endpoints and selector
@ -927,7 +989,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(IOException e) catch(IOException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
} }
} }
@ -941,7 +1003,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch (IOException e) catch (IOException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
_selector=null; _selector=null;
} }
@ -992,7 +1054,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
} }
catch(InterruptedException e) catch(InterruptedException e)
{ {
__log.ignore(e); LOG.ignore(e);
} }
AggregateLifeCycle.dump(out,indent,dump); AggregateLifeCycle.dump(out,indent,dump);
} }

View File

@ -27,9 +27,6 @@
<description>Performance monitoring artifact for jetty.</description> <description>Performance monitoring artifact for jetty.</description>
<properties> <properties>
<bundle-symbolic-name>${project.groupId}.jmx</bundle-symbolic-name> <bundle-symbolic-name>${project.groupId}.jmx</bundle-symbolic-name>
<test-wars-dir>${project.build.directory}/test-wars</test-wars-dir>
<test-libs-dir>${project.build.directory}/test-libs</test-libs-dir>
<test-dist-dir>${project.build.directory}/test-dist</test-dist-dir>
</properties> </properties>
<build> <build>
<plugins> <plugins>

View File

@ -82,6 +82,8 @@ public class PolicyMonitorTest
File permFile =new File(MavenTestingUtils.getTargetDir(), File permFile =new File(MavenTestingUtils.getTargetDir(),
"test-classes/monitor-test-2/global-all-permission.policy"); "test-classes/monitor-test-2/global-all-permission.policy");
// Wait so that time is definitely different
Thread.sleep(10);
permFile.setLastModified(System.currentTimeMillis()); permFile.setLastModified(System.currentTimeMillis());
monitor.waitForScan(); monitor.waitForScan();

View File

@ -119,6 +119,8 @@ public class AsyncHttpConnection extends HttpConnection
// Are we write blocked // Are we write blocked
if (_generator.isCommitted() && !_generator.isComplete()) if (_generator.isCommitted() && !_generator.isComplete())
((AsyncEndPoint)_endp).scheduleWrite(); ((AsyncEndPoint)_endp).scheduleWrite();
else
_generator.returnBuffers();
} }
return connection; return connection;
} }

View File

@ -153,23 +153,6 @@ public class ConnectHandler extends HandlerWrapper
((LifeCycle)_threadPool).start(); ((LifeCycle)_threadPool).start();
_selectorManager.start(); _selectorManager.start();
_threadPool.dispatch(new Runnable()
{
public void run()
{
while (isRunning())
{
try
{
_selectorManager.doSelect(0);
}
catch (IOException x)
{
_logger.warn("Unexpected exception", x);
}
}
}
});
} }
@Override @Override

View File

@ -36,6 +36,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.eclipse.jetty.util.thread.Timeout.Task; import org.eclipse.jetty.util.thread.Timeout.Task;
/* ------------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------- */
@ -241,46 +242,6 @@ public class SelectChannelConnector extends AbstractNIOConnector
_manager.start(); _manager.start();
super.doStart(); super.doStart();
// start a thread to Select
for (int i=0;i<getAcceptors();i++)
{
final int id=i;
_manager.dispatch(new Runnable()
{
public void run()
{
String name=Thread.currentThread().getName();
try
{
Thread.currentThread().setName(name+" Selector"+id+" "+SelectChannelConnector.this);
while (isRunning())
{
try
{
_manager.doSelect(id);
}
catch(ThreadDeath e)
{
throw e;
}
catch(IOException e)
{
LOG.ignore(e);
}
catch(Exception e)
{
LOG.warn(e);
}
}
}
finally
{
Thread.currentThread().setName(name);
}
}
});
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -372,7 +333,10 @@ public class SelectChannelConnector extends AbstractNIOConnector
@Override @Override
public boolean dispatch(Runnable task) public boolean dispatch(Runnable task)
{ {
return getThreadPool().dispatch(task); ThreadPool pool=getThreadPool();
if (pool==null)
pool=getServer().getThreadPool();
return pool.dispatch(task);
} }
@Override @Override

View File

@ -52,7 +52,7 @@ import org.eclipse.jetty.util.log.Logger;
*/ */
public class JDBCSessionIdManager extends AbstractSessionIdManager public class JDBCSessionIdManager extends AbstractSessionIdManager
{ {
final static Logger __log = SessionHandler.__log; final static Logger LOG = SessionHandler.__log;
protected final HashSet<String> _sessionIds = new HashSet<String>(); protected final HashSet<String> _sessionIds = new HashSet<String>();
protected Server _server; protected Server _server;
@ -106,7 +106,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
throws SQLException throws SQLException
{ {
_dbName = dbMeta.getDatabaseProductName().toLowerCase(); _dbName = dbMeta.getDatabaseProductName().toLowerCase();
__log.debug ("Using database "+_dbName); LOG.debug ("Using database "+_dbName);
_isLower = dbMeta.storesLowerCaseIdentifiers(); _isLower = dbMeta.storesLowerCaseIdentifiers();
_isUpper = dbMeta.storesUpperCaseIdentifiers(); _isUpper = dbMeta.storesUpperCaseIdentifiers();
} }
@ -230,7 +230,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
if ((System.currentTimeMillis()%2) == 0) if ((System.currentTimeMillis()%2) == 0)
_scavengeIntervalMs += tenPercent; _scavengeIntervalMs += tenPercent;
if (__log.isDebugEnabled()) __log.debug("Scavenging every "+_scavengeIntervalMs+" ms"); if (LOG.isDebugEnabled()) LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
if (_timer!=null && (period!=old_period || _task==null)) if (_timer!=null && (period!=old_period || _task==null))
{ {
synchronized (this) synchronized (this)
@ -271,7 +271,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
} }
catch (Exception e) catch (Exception e)
{ {
__log.warn("Problem storing session id="+id, e); LOG.warn("Problem storing session id="+id, e);
} }
} }
} }
@ -294,8 +294,8 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
synchronized (_sessionIds) synchronized (_sessionIds)
{ {
if (__log.isDebugEnabled()) if (LOG.isDebugEnabled())
__log.debug("Removing session id="+id); LOG.debug("Removing session id="+id);
try try
{ {
_sessionIds.remove(id); _sessionIds.remove(id);
@ -303,7 +303,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
} }
catch (Exception e) catch (Exception e)
{ {
__log.warn("Problem removing session id="+id, e); LOG.warn("Problem removing session id="+id, e);
} }
} }
@ -358,7 +358,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
} }
catch (Exception e) catch (Exception e)
{ {
__log.warn("Problem checking inUse for id="+clusterId, e); LOG.warn("Problem checking inUse for id="+clusterId, e);
return false; return false;
} }
} }
@ -409,13 +409,13 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
initializeDatabase(); initializeDatabase();
prepareTables(); prepareTables();
super.doStart(); super.doStart();
if (__log.isDebugEnabled()) __log.debug("Scavenging interval = "+getScavengeInterval()+" sec"); if (LOG.isDebugEnabled()) LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec");
_timer=new Timer("JDBCSessionScavenger", true); _timer=new Timer("JDBCSessionScavenger", true);
setScavengeInterval(getScavengeInterval()); setScavengeInterval(getScavengeInterval());
} }
catch (Exception e) catch (Exception e)
{ {
__log.warn("Problem initialising JettySessionIds table", e); LOG.warn("Problem initialising JettySessionIds table", e);
} }
} }
@ -652,7 +652,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
List<String> expiredSessionIds = new ArrayList<String>(); List<String> expiredSessionIds = new ArrayList<String>();
try try
{ {
if (__log.isDebugEnabled()) __log.debug("Scavenge sweep started at "+System.currentTimeMillis()); if (LOG.isDebugEnabled()) LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
if (_lastScavengeTime > 0) if (_lastScavengeTime > 0)
{ {
connection = getConnection(); connection = getConnection();
@ -661,7 +661,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
PreparedStatement statement = connection.prepareStatement(_selectExpiredSessions); PreparedStatement statement = connection.prepareStatement(_selectExpiredSessions);
long lowerBound = (_lastScavengeTime - _scavengeIntervalMs); long lowerBound = (_lastScavengeTime - _scavengeIntervalMs);
long upperBound = _lastScavengeTime; long upperBound = _lastScavengeTime;
if (__log.isDebugEnabled()) __log.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound); if (LOG.isDebugEnabled()) LOG.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound);
statement.setLong(1, lowerBound); statement.setLong(1, lowerBound);
statement.setLong(2, upperBound); statement.setLong(2, upperBound);
@ -670,7 +670,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
{ {
String sessionId = result.getString("sessionId"); String sessionId = result.getString("sessionId");
expiredSessionIds.add(sessionId); expiredSessionIds.add(sessionId);
if (__log.isDebugEnabled()) __log.debug (" Found expired sessionId="+sessionId); if (LOG.isDebugEnabled()) LOG.debug (" Found expired sessionId="+sessionId);
} }
//tell the SessionManagers to expire any sessions with a matching sessionId in memory //tell the SessionManagers to expire any sessions with a matching sessionId in memory
@ -693,7 +693,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs); upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs);
if (upperBound > 0) if (upperBound > 0)
{ {
if (__log.isDebugEnabled()) __log.debug("Deleting old expired sessions expired before "+upperBound); if (LOG.isDebugEnabled()) LOG.debug("Deleting old expired sessions expired before "+upperBound);
statement = connection.prepareStatement(_deleteOldExpiredSessions); statement = connection.prepareStatement(_deleteOldExpiredSessions);
statement.setLong(1, upperBound); statement.setLong(1, upperBound);
statement.executeUpdate(); statement.executeUpdate();
@ -702,12 +702,15 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
} }
catch (Exception e) catch (Exception e)
{ {
__log.warn("Problem selecting expired sessions", e); if (isRunning())
LOG.warn("Problem selecting expired sessions", e);
else
LOG.ignore(e);
} }
finally finally
{ {
_lastScavengeTime=System.currentTimeMillis(); _lastScavengeTime=System.currentTimeMillis();
if (__log.isDebugEnabled()) __log.debug("Scavenge sweep ended at "+_lastScavengeTime); if (LOG.isDebugEnabled()) LOG.debug("Scavenge sweep ended at "+_lastScavengeTime);
if (connection != null) if (connection != null)
{ {
try try
@ -716,7 +719,7 @@ public class JDBCSessionIdManager extends AbstractSessionIdManager
} }
catch (SQLException e) catch (SQLException e)
{ {
__log.warn(e); LOG.warn(e);
} }
} }
} }

View File

@ -155,7 +155,7 @@ public class HttpConnectionTest
{ {
try try
{ {
((StdErrLog)Log.getLog()).setHideStacks(true); ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
String response; String response;
@ -186,7 +186,7 @@ public class HttpConnectionTest
} }
finally finally
{ {
((StdErrLog)Log.getLog()).setHideStacks(false); ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
} }
} }
@ -336,11 +336,7 @@ public class HttpConnectionTest
Logger logger=null; Logger logger=null;
try try
{ {
if (!LOG.isDebugEnabled()) ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(true);
{
logger=Log.getLog();
Log.setLog(null);
}
response=connector.getResponses(requests); response=connector.getResponses(requests);
offset = checkContains(response,offset,"HTTP/1.1 500"); offset = checkContains(response,offset,"HTTP/1.1 500");
offset = checkContains(response,offset,"Connection: close"); offset = checkContains(response,offset,"Connection: close");
@ -348,8 +344,7 @@ public class HttpConnectionTest
} }
finally finally
{ {
if (logger!=null) ((StdErrLog)Log.getLogger(HttpConnection.class)).setHideStacks(false);
Log.setLog(logger);
} }
} }

View File

@ -385,7 +385,6 @@ public class RFC2616Test
String response; String response;
int offset=0; int offset=0;
// Expect 100 not sent // Expect 100 not sent
((StdErrLog)Log.getLog()).setHideStacks(true);
offset=0; offset=0;
response=connector.getResponses("GET /R1?error=401 HTTP/1.1\n"+ response=connector.getResponses("GET /R1?error=401 HTTP/1.1\n"+
@ -397,8 +396,6 @@ public class RFC2616Test
checkNotContained(response,offset,"HTTP/1.1 100","8.2.3 expect 100"); checkNotContained(response,offset,"HTTP/1.1 100","8.2.3 expect 100");
offset=checkContains(response,offset,"HTTP/1.1 401 ","8.2.3 expect 100")+1; offset=checkContains(response,offset,"HTTP/1.1 401 ","8.2.3 expect 100")+1;
offset=checkContains(response,offset,"Connection: close","8.2.3 expect 100")+1; offset=checkContains(response,offset,"Connection: close","8.2.3 expect 100")+1;
((StdErrLog)Log.getLog()).setHideStacks(false);
} }
@Test @Test

View File

@ -209,4 +209,9 @@ public abstract class AbstractLifeCycle implements LifeCycle
public void lifeCycleStopped(LifeCycle event) {} public void lifeCycleStopped(LifeCycle event) {}
public void lifeCycleStopping(LifeCycle event) {} public void lifeCycleStopping(LifeCycle event) {}
} }
public String toString()
{
return super.toString()+"#"+getState();
}
} }

View File

@ -3,10 +3,12 @@ package org.eclipse.jetty.util.component;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
@ -20,7 +22,7 @@ import org.eclipse.jetty.util.log.Logger;
public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
{ {
private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class); private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
private final Queue<Object> _dependentBeans=new ConcurrentLinkedQueue<Object>(); private final List<Object> _dependentBeans=new CopyOnWriteArrayList<Object>();
public void destroy() public void destroy()
{ {
@ -49,7 +51,9 @@ public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable
protected void doStop() throws Exception protected void doStop() throws Exception
{ {
super.doStop(); super.doStop();
for (Object o:_dependentBeans) List<Object> reverse = new ArrayList<Object>(_dependentBeans);
Collections.reverse(reverse);
for (Object o:reverse)
{ {
if (o instanceof LifeCycle) if (o instanceof LifeCycle)
((LifeCycle)o).stop(); ((LifeCycle)o).stop();

View File

@ -38,7 +38,7 @@ import org.eclipse.jetty.util.Loader;
public class Log public class Log
{ {
public final static String EXCEPTION= "EXCEPTION "; public final static String EXCEPTION= "EXCEPTION ";
public final static String IGNORED= "IGNORED"; public final static String IGNORED= "IGNORED ";
public static String __logClass; public static String __logClass;
public static boolean __ignored; public static boolean __ignored;
@ -233,10 +233,7 @@ public class Log
{ {
if (!initialized()) if (!initialized())
return; return;
if (__ignored) __log.ignore(thrown);
{
__log.warn(IGNORED, thrown);
}
} }
/** /**

View File

@ -309,7 +309,12 @@ public class StdErrLog implements Logger
private void format(StringBuilder builder, String msg, Object... args) private void format(StringBuilder builder, String msg, Object... args)
{ {
msg = String.valueOf(msg); // Avoids NPE if (msg==null)
{
msg="";
for (Object o : args)
msg+="{} ";
}
String braces = "{}"; String braces = "{}";
int start = 0; int start = 0;
for (Object arg : args) for (Object arg : args)
@ -412,5 +417,9 @@ public class StdErrLog implements Logger
{ {
warn(Log.IGNORED, ignored); warn(Log.IGNORED, ignored);
} }
else
{
debug("Ignored {}",ignored.toString());
}
} }
} }

View File

@ -139,14 +139,14 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
{ {
LOG.warn(size+" threads could not be stopped"); LOG.warn(size+" threads could not be stopped");
if (LOG.isDebugEnabled()) if (size==1 || LOG.isDebugEnabled())
{ {
for (Thread unstopped : _threads) for (Thread unstopped : _threads)
{ {
LOG.debug("Couldn't stop "+unstopped); LOG.info("Couldn't stop "+unstopped);
for (StackTraceElement element : unstopped.getStackTrace()) for (StackTraceElement element : unstopped.getStackTrace())
{ {
LOG.debug(" at "+element); LOG.info(" at "+element);
} }
} }
} }
@ -507,9 +507,10 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
@Override @Override
public String toString() public String toString()
{ {
return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}"; return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}#"+getState();
} }
/* ------------------------------------------------------------ */
private Runnable idleJobPoll() throws InterruptedException private Runnable idleJobPoll() throws InterruptedException
{ {
return _jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS); return _jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS);

View File

@ -32,11 +32,13 @@ public class LifeCycleListenerTest
TestLifeCycle lifecycle = new TestLifeCycle(); TestLifeCycle lifecycle = new TestLifeCycle();
TestListener listener = new TestListener(); TestListener listener = new TestListener();
lifecycle.addLifeCycleListener(listener); lifecycle.addLifeCycleListener(listener);
((StdErrLog)Log.getLog()).setHideStacks(true);
lifecycle.setCause(cause); lifecycle.setCause(cause);
try try
{ {
((StdErrLog)Log.getLogger(AbstractLifeCycle.class)).setHideStacks(true);
lifecycle.start(); lifecycle.start();
assertTrue(false); assertTrue(false);
} }
@ -45,10 +47,14 @@ public class LifeCycleListenerTest
assertEquals(cause,e); assertEquals(cause,e);
assertEquals(cause,listener.getCause()); assertEquals(cause,listener.getCause());
} }
finally
{
((StdErrLog)Log.getLogger(AbstractLifeCycle.class)).setHideStacks(false);
}
lifecycle.setCause(null); lifecycle.setCause(null);
((StdErrLog)Log.getLog()).setHideStacks(false); ((StdErrLog)Log.getLog()).setHideStacks(false);
lifecycle.start(); lifecycle.start();
// check that the starting event has been thrown // check that the starting event has been thrown
@ -62,6 +68,7 @@ public class LifeCycleListenerTest
// check that the lifecycle's state is started // check that the lifecycle's state is started
assertTrue("The lifecycle state is not started",lifecycle.isStarted()); assertTrue("The lifecycle state is not started",lifecycle.isStarted());
} }
@Test @Test
@ -77,12 +84,11 @@ public class LifeCycleListenerTest
// stop() will return without doing anything // stop() will return without doing anything
lifecycle.start(); lifecycle.start();
((StdErrLog)Log.getLog()).setHideStacks(true);
lifecycle.setCause(cause); lifecycle.setCause(cause);
try try
{ {
((StdErrLog)Log.getLogger(AbstractLifeCycle.class)).setHideStacks(true);
lifecycle.stop(); lifecycle.stop();
assertTrue(false); assertTrue(false);
} }
@ -91,10 +97,12 @@ public class LifeCycleListenerTest
assertEquals(cause,e); assertEquals(cause,e);
assertEquals(cause,listener.getCause()); assertEquals(cause,listener.getCause());
} }
finally
{
((StdErrLog)Log.getLogger(AbstractLifeCycle.class)).setHideStacks(false);
}
lifecycle.setCause(null); lifecycle.setCause(null);
((StdErrLog)Log.getLog()).setHideStacks(false);
lifecycle.stop(); lifecycle.stop();
@ -117,22 +125,15 @@ public class LifeCycleListenerTest
public void testRemoveLifecycleListener () public void testRemoveLifecycleListener ()
throws Exception throws Exception
{ {
TestLifeCycle lifecycle = new TestLifeCycle(); TestLifeCycle lifecycle = new TestLifeCycle();
TestListener listener = new TestListener(); TestListener listener = new TestListener();
lifecycle.addLifeCycleListener(listener); lifecycle.addLifeCycleListener(listener);
lifecycle.start(); lifecycle.start();
((StdErrLog)Log.getLog()).setHideStacks(true);
assertTrue("The starting event didn't occur",listener.starting); assertTrue("The starting event didn't occur",listener.starting);
lifecycle.removeLifeCycleListener(listener); lifecycle.removeLifeCycleListener(listener);
lifecycle.stop(); lifecycle.stop();
assertFalse("The stopping event occurred", listener.stopping); assertFalse("The stopping event occurred", listener.stopping);
} }
private class TestLifeCycle extends AbstractLifeCycle private class TestLifeCycle extends AbstractLifeCycle
{ {

View File

@ -27,29 +27,32 @@ public class StdErrLogTest extends TestCase
log.setHideStacks(true); log.setHideStacks(true);
try { try {
log.info("Testing info(msg,null,null) - {} {}","arg0","arg1");
log.info("Testing info(msg,null,null) - {} {}",null,null); log.info("Testing info(msg,null,null) - {} {}",null,null);
log.info("Testing info(msg,null,null) - {}",null,null); log.info("Testing info(msg,null,null) - {}",null,null);
log.info("Testing info(msg,null,null)",null,null); log.info("Testing info(msg,null,null)",null,null);
log.info(null,"- Testing","info(null,arg0,arg1)"); log.info(null,"Testing","info(null,arg0,arg1)");
log.info(null,null,null); log.info(null,null,null);
log.debug("Testing debug(msg,null,null) - {} {}","arg0","arg1");
log.debug("Testing debug(msg,null,null) - {} {}",null,null); log.debug("Testing debug(msg,null,null) - {} {}",null,null);
log.debug("Testing debug(msg,null,null) - {}",null,null); log.debug("Testing debug(msg,null,null) - {}",null,null);
log.debug("Testing debug(msg,null,null)",null,null); log.debug("Testing debug(msg,null,null)",null,null);
log.debug(null,"- Testing","debug(null,arg0,arg1)"); log.debug(null,"Testing","debug(null,arg0,arg1)");
log.debug(null,null,null); log.debug(null,null,null);
log.debug("Testing debug(msg,null)"); log.debug("Testing debug(msg,null)");
log.debug(null,new Throwable("IGNORE::Testing debug(null,thrw)").fillInStackTrace()); log.debug(null,new Throwable("Testing debug(null,thrw)").fillInStackTrace());
log.warn("Testing warn(msg,null,null) - {} {}","arg0","arg1");
log.warn("Testing warn(msg,null,null) - {} {}",null,null); log.warn("Testing warn(msg,null,null) - {} {}",null,null);
log.warn("Testing warn(msg,null,null) - {}",null,null); log.warn("Testing warn(msg,null,null) - {}",null,null);
log.warn("Testing warn(msg,null,null)",null,null); log.warn("Testing warn(msg,null,null)",null,null);
log.warn(null,"- Testing","warn(msg,arg0,arg1)"); log.warn(null,"Testing","warn(msg,arg0,arg1)");
log.warn(null,null,null); log.warn(null,null,null);
log.warn("Testing warn(msg,null)"); log.warn("Testing warn(msg,null)");
log.warn(null,new Throwable("IGNORE::Testing warn(msg,thrw)").fillInStackTrace()); log.warn(null,new Throwable("Testing warn(msg,thrw)").fillInStackTrace());
} }
catch (NullPointerException npe) catch (NullPointerException npe)
{ {
@ -58,4 +61,22 @@ public class StdErrLogTest extends TestCase
assertTrue("NullPointerException in StdErrLog.", false); assertTrue("NullPointerException in StdErrLog.", false);
} }
} }
public void testIgnores()
{
StdErrLog log = new StdErrLog(StdErrLogTest.class.getName());
log.setHideStacks(true);
Log.__ignored=false;
log.setDebugEnabled(false);
log.ignore(new Throwable("IGNORE ME"));
Log.__ignored=true;
log.setDebugEnabled(false);
log.ignore(new Throwable("Don't ignore me"));
Log.__ignored=false;
log.setDebugEnabled(true);
log.ignore(new Throwable("Debug me"));
}
} }

View File

@ -197,7 +197,7 @@ public class TestClient implements WebSocket.OnFrame
if ("-p".equals(a)||"--port".equals(a)) if ("-p".equals(a)||"--port".equals(a))
port=Integer.parseInt(args[++i]); port=Integer.parseInt(args[++i]);
else if ("-h".equals(a)||"--host".equals(a)) else if ("-h".equals(a)||"--host".equals(a))
port=Integer.parseInt(args[++i]); host=args[++i];
else if ("-c".equals(a)||"--count".equals(a)) else if ("-c".equals(a)||"--count".equals(a))
count=Integer.parseInt(args[++i]); count=Integer.parseInt(args[++i]);
else if ("-s".equals(a)||"--size".equals(a)) else if ("-s".equals(a)||"--size".equals(a))

View File

@ -3,12 +3,12 @@ package org.eclipse.jetty.websocket;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.SocketAddress;
import java.net.URI; import java.net.URI;
import java.nio.channels.ByteChannel; import java.nio.channels.ByteChannel;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -17,21 +17,25 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.io.ByteArrayBuffer;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** WebSocket Client /**
* <p>This WebSocket Client class can create multiple websocket connections to multiple destinations. * <p>{@link WebSocketClient} allows to create multiple connections to multiple destinations
* It uses the same {@link WebSocket} endpoint API as the server. * that can speak the websocket protocol.</p>
* Simple usage is as follows: <pre> * <p>When creating websocket connections, {@link WebSocketClient} accepts a {@link WebSocket}
* object (to receive events from the server), and returns a {@link WebSocket.Connection} to
* send data to the server.</p>
* <p>Example usage is as follows:</p>
* <pre>
* WebSocketClientFactory factory = new WebSocketClientFactory(); * WebSocketClientFactory factory = new WebSocketClientFactory();
* factory.start(); * factory.start();
* WebSocketClient client = factory.newClient();
* client.start();
* *
* WebSocket.Connection connection = client.open(new URI("ws://127.0.0.1:8080/"),new WebSocket.OnTextMessage() * WebSocketClient client = factory.newWebSocketClient();
* // Configure the client
*
* WebSocket.Connection connection = client.open(new URI("ws://127.0.0.1:8080/"), new WebSocket.OnTextMessage()
* { * {
* public void onOpen(Connection connection) * public void onOpen(Connection connection)
* { * {
@ -47,7 +51,7 @@ import org.eclipse.jetty.util.log.Logger;
* { * {
* // handle incoming message * // handle incoming message
* } * }
* }).get(5,TimeUnit.SECONDS); * }).get(5, TimeUnit.SECONDS);
* *
* connection.sendMessage("Hello World"); * connection.sendMessage("Hello World");
* </pre> * </pre>
@ -63,12 +67,17 @@ public class WebSocketClient
private String _protocol; private String _protocol;
private int _maxIdleTime=-1; private int _maxIdleTime=-1;
private MaskGen _maskGen; private MaskGen _maskGen;
private SocketAddress _bindAddress;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Create a WebSocket Client with private factory. /**
* <p>Creates a WebSocketClient from a private WebSocketClientFactory. This can be wasteful of resources if many clients are created. * <p>Creates a WebSocketClient from a private WebSocketClientFactory.</p>
* <p>This can be wasteful of resources if many clients are created.</p>
*
* @deprecated Use {@link WebSocketClientFactory#newWebSocketClient()}
* @throws Exception if the private WebSocketClientFactory fails to start
*/ */
@Deprecated
public WebSocketClient() throws Exception public WebSocketClient() throws Exception
{ {
_factory=new WebSocketClientFactory(); _factory=new WebSocketClientFactory();
@ -77,8 +86,10 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Create a WebSocket Client with shared factory. /**
* @param threadpool * <p>Creates a WebSocketClient with shared WebSocketClientFactory.</p>
*
* @param factory the shared {@link WebSocketClientFactory}
*/ */
public WebSocketClient(WebSocketClientFactory factory) public WebSocketClient(WebSocketClientFactory factory)
{ {
@ -87,8 +98,39 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the maxIdleTime for connections opened by this client. /**
* @return The maxIdleTime in ms, or -1 if the default from {@link #getSelectorManager()} is used. * @return The WebSocketClientFactory this client was created with.
*/
public WebSocketClientFactory getFactory()
{
return _factory;
}
/* ------------------------------------------------------------ */
/**
* @return the address to bind the socket channel to
* @see #setBindAddress(SocketAddress)
*/
public SocketAddress getBindAddress()
{
return _bindAddress;
}
/* ------------------------------------------------------------ */
/**
* @param bindAddress the address to bind the socket channel to
* @see #getBindAddress()
*/
public void setBindAddress(SocketAddress bindAddress)
{
this._bindAddress = bindAddress;
}
/* ------------------------------------------------------------ */
/**
* @return The maxIdleTime in ms for connections opened by this client,
* or -1 if the default from {@link WebSocketClientFactory#getSelectorManager()} is used.
* @see #setMaxIdleTime(int)
*/ */
public int getMaxIdleTime() public int getMaxIdleTime()
{ {
@ -96,8 +138,9 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Set the maxIdleTime for connections opened by this client. /**
* @param maxIdleTime max idle time in ms * @param maxIdleTime The max idle time in ms for connections opened by this client
* @see #getMaxIdleTime()
*/ */
public void setMaxIdleTime(int maxIdleTime) public void setMaxIdleTime(int maxIdleTime)
{ {
@ -105,8 +148,9 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the subprotocol string for connections opened by this client. /**
* @return The subprotocol * @return The subprotocol string for connections opened by this client.
* @see #setProtocol(String)
*/ */
public String getProtocol() public String getProtocol()
{ {
@ -114,8 +158,9 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Set the subprotocol string for connections opened by this client. /**
* @param protocol The subprotocol * @param protocol The subprotocol string for connections opened by this client.
* @see #getProtocol()
*/ */
public void setProtocol(String protocol) public void setProtocol(String protocol)
{ {
@ -123,8 +168,9 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the origin of the client /**
* @return The clients Origin * @return The origin URI of the client
* @see #setOrigin(String)
*/ */
public String getOrigin() public String getOrigin()
{ {
@ -132,8 +178,9 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Set the origin of the client /**
* @param origin the origin of the client (eg "http://example.com") * @param origin The origin URI of the client (eg "http://example.com")
* @see #getOrigin()
*/ */
public void setOrigin(String origin) public void setOrigin(String origin)
{ {
@ -141,40 +188,58 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* <p>Returns the map of the cookies that are sent during the initial HTTP handshake
* that upgrades to the websocket protocol.</p>
* @return The read-write cookie map
*/
public Map<String,String> getCookies() public Map<String,String> getCookies()
{ {
return _cookies; return _cookies;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* @return The list of websocket protocol extensions
*/
public List<String> getExtensions() public List<String> getExtensions()
{ {
return _extensions; return _extensions;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* @return the mask generator to use, or null if not mask generator should be used
* @see #setMaskGen(MaskGen)
*/
public MaskGen getMaskGen() public MaskGen getMaskGen()
{ {
return _maskGen; return _maskGen;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* @param maskGen the mask generator to use, or null if not mask generator should be used
* @see #getMaskGen()
*/
public void setMaskGen(MaskGen maskGen) public void setMaskGen(MaskGen maskGen)
{ {
_maskGen = maskGen; _maskGen = maskGen;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Open a WebSocket connection. /**
* Open a websocket connection to the URI and block until the connection is accepted or there is an error. * <p>Opens a websocket connection to the URI and blocks until the connection is accepted or there is an error.</p>
*
* @param uri The URI to connect to. * @param uri The URI to connect to.
* @param websocket The {@link WebSocket} instance to handle incoming events. * @param websocket The {@link WebSocket} instance to handle incoming events.
* @param maxConnectTime The interval to wait for a successful connection * @param maxConnectTime The interval to wait for a successful connection
* @param units the units of the maxConnectTime * @param units the units of the maxConnectTime
* @return A {@link WebSocket.Connection} * @return A {@link WebSocket.Connection}
* @throws IOException * @throws IOException if the connection fails
* @throws InterruptedException * @throws InterruptedException if the thread is interrupted
* @throws TimeoutException * @throws TimeoutException if the timeout elapses before the connection is completed
* @see #open(URI, WebSocket)
*/ */
public WebSocket.Connection open(URI uri, WebSocket websocket,long maxConnectTime,TimeUnit units) throws IOException, InterruptedException, TimeoutException public WebSocket.Connection open(URI uri, WebSocket websocket,long maxConnectTime,TimeUnit units) throws IOException, InterruptedException, TimeoutException
{ {
@ -196,14 +261,15 @@ public class WebSocketClient
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Asynchronously open a websocket connection. /**
* Open a websocket connection and return a {@link Future} to obtain the connection. * <p>Asynchronously opens a websocket connection and returns a {@link Future} to obtain the connection.</p>
* The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open. * <p>The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open.</p>
* *
* @param uri The URI to connect to. * @param uri The URI to connect to.
* @param websocket The {@link WebSocket} instance to handle incoming events. * @param websocket The {@link WebSocket} instance to handle incoming events.
* @return A {@link Future} to the {@link WebSocket.Connection} * @return A {@link Future} to the {@link WebSocket.Connection}
* @throws IOException * @throws IOException if the connection fails
* @see #open(URI, WebSocket, long, TimeUnit)
*/ */
public Future<WebSocket.Connection> open(URI uri, WebSocket websocket) throws IOException public Future<WebSocket.Connection> open(URI uri, WebSocket websocket) throws IOException
{ {
@ -216,12 +282,10 @@ public class WebSocketClient
throw new IOException("wss not supported"); throw new IOException("wss not supported");
SocketChannel channel = SocketChannel.open(); SocketChannel channel = SocketChannel.open();
if (_bindAddress != null)
channel.socket().bind(_bindAddress);
channel.socket().setTcpNoDelay(true); channel.socket().setTcpNoDelay(true);
int maxIdleTime = getMaxIdleTime(); int maxIdleTime = getMaxIdleTime();
if (maxIdleTime<0)
maxIdleTime=(int)_factory.getSelectorManager().getMaxIdleTime();
if (maxIdleTime>0)
channel.socket().setSoTimeout(maxIdleTime);
InetSocketAddress address=new InetSocketAddress(uri.getHost(),uri.getPort()); InetSocketAddress address=new InetSocketAddress(uri.getHost(),uri.getPort());
@ -234,13 +298,12 @@ public class WebSocketClient
return holder; return holder;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** The Future Websocket Connection. /** The Future Websocket Connection.
*/ */
static class WebSocketFuture implements Future<WebSocket.Connection> static class WebSocketFuture implements Future<WebSocket.Connection>
{ {
final WebSocket _websocket;; final WebSocket _websocket;
final URI _uri; final URI _uri;
final String _protocol; final String _protocol;
final String _origin; final String _origin;
@ -355,7 +418,7 @@ public class WebSocketClient
{ {
return _maskGen; return _maskGen;
} }
public String toString() public String toString()
{ {
return "[" + _uri + ","+_websocket+"]@"+hashCode(); return "[" + _uri + ","+_websocket+"]@"+hashCode();
@ -422,7 +485,7 @@ public class WebSocketClient
_done.await(timeout,unit); _done.await(timeout,unit);
ByteChannel channel=null; ByteChannel channel=null;
org.eclipse.jetty.websocket.WebSocket.Connection connection=null; org.eclipse.jetty.websocket.WebSocket.Connection connection=null;
Throwable exception=null; Throwable exception;
synchronized (this) synchronized (this)
{ {
exception=_exception; exception=_exception;
@ -465,6 +528,5 @@ public class WebSocketClient
__log.debug(e); __log.debug(e);
} }
} }
} }
} }

View File

@ -2,22 +2,10 @@ package org.eclipse.jetty.websocket;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ProtocolException; import java.net.ProtocolException;
import java.net.URI;
import java.nio.channels.ByteChannel;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpParser; import org.eclipse.jetty.http.HttpParser;
@ -33,15 +21,19 @@ import org.eclipse.jetty.io.nio.SelectorManager;
import org.eclipse.jetty.util.B64Code; import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.AggregateLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool; import org.eclipse.jetty.util.thread.ThreadPool;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** WebSocket Client Factory. /**
* The WebSocketClientFactory contains the common mechanisms for multiple WebSocketClient instances (eg threadpool, NIO selector). * <p>WebSocketClientFactory contains the common components needed by multiple {@link WebSocketClient} instances
* WebSocketClients with different configurations should share the same factory to avoid wasted resources. * (for example, a {@link ThreadPool}, a {@link SelectorManager NIO selector}, etc).</p>
* <p>WebSocketClients with different configurations should share the same factory to avoid to waste resources.</p>
* <p>If a ThreadPool or MaskGen is passed in the constructor, then it is not added with {@link AggregateLifeCycle#addBean(Object)},
* so it's lifecycle must be controlled externally.
* @see WebSocketClient * @see WebSocketClient
*/ */
public class WebSocketClientFactory extends AggregateLifeCycle public class WebSocketClientFactory extends AggregateLifeCycle
@ -52,37 +44,58 @@ public class WebSocketClientFactory extends AggregateLifeCycle
private final ThreadPool _threadPool; private final ThreadPool _threadPool;
private final WebSocketClientSelector _selector; private final WebSocketClientSelector _selector;
private final WebSocketBuffers _buffers; private MaskGen _maskGen;
private final MaskGen _maskGen; private WebSocketBuffers _buffers;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Create a WebSocket Client with default configuration. /**
* <p>Creates a WebSocketClientFactory with the default configuration.</p>
*/ */
public WebSocketClientFactory() public WebSocketClientFactory()
{ {
this(new QueuedThreadPool(),new RandomMaskGen(),16*1024); _threadPool=new QueuedThreadPool();
} addBean(_threadPool);
_buffers=new WebSocketBuffers(8*1024);
/* ------------------------------------------------------------ */ addBean(_buffers);
/** Create a WebSocket Client with ThreadPool . _maskGen=new RandomMaskGen();
*/ addBean(_maskGen);
public WebSocketClientFactory(ThreadPool threadPool) _selector=new WebSocketClientSelector();
{ addBean(_selector);
this(threadPool,new RandomMaskGen(),16*1024);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Create a WebSocket Client with shared threadpool. /**
* @param threadpool * <p>Creates a WebSocketClientFactory with the given ThreadPool and the default configuration.</p>
* @param threadPool the ThreadPool instance to use
*/ */
public WebSocketClientFactory(ThreadPool threadpool,MaskGen maskGen,int bufferSize) public WebSocketClientFactory(ThreadPool threadPool)
{ {
_threadPool=threadpool; _threadPool=threadPool;
addBean(threadPool);
_buffers=new WebSocketBuffers(8*1024);
addBean(_buffers);
_maskGen=new RandomMaskGen();
addBean(_maskGen);
_selector=new WebSocketClientSelector();
addBean(_selector);
}
/* ------------------------------------------------------------ */
/**
* <p>Creates a WebSocketClientFactory with the specified configuration.</p>
* @param threadPool the ThreadPool instance to use
* @param maskGen the mask generator to use
* @param bufferSize the read buffer size
*/
public WebSocketClientFactory(ThreadPool threadPool,MaskGen maskGen,int bufferSize)
{
_threadPool=threadPool;
addBean(threadPool);
_buffers=new WebSocketBuffers(bufferSize);
addBean(_buffers);
_maskGen=maskGen;
_selector=new WebSocketClientSelector(); _selector=new WebSocketClientSelector();
_buffers=new WebSocketBuffers(bufferSize);
_maskGen=maskGen;
addBean(_selector); addBean(_selector);
addBean(_threadPool);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -97,7 +110,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Get the ThreadPool. /** Get the ThreadPool.
* <p>Used to set/query the thread pool configuration. * Used to set/query the thread pool configuration.
* @return The {@link ThreadPool} * @return The {@link ThreadPool}
*/ */
public ThreadPool getThreadPool() public ThreadPool getThreadPool()
@ -106,47 +119,79 @@ public class WebSocketClientFactory extends AggregateLifeCycle
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* @return the shared mask generator, or null if no shared mask generator is used
* @see {@link WebSocketClient#getMaskGen()}
*/
public MaskGen getMaskGen() public MaskGen getMaskGen()
{ {
return _maskGen; return _maskGen;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/**
* @param maskGen the shared mask generator, or null if no shared mask generator is used
* @see {@link WebSocketClient#setMaskGen(MaskGen)}
*/
public void setMaskGen(MaskGen maskGen)
{
if (isRunning())
throw new IllegalStateException(getState());
if (removeBean(_maskGen))
addBean(maskGen);
_maskGen=maskGen;
}
/* ------------------------------------------------------------ */
/**
* @param bufferSize the read buffer size
* @see #getBufferSize()
*/
public void setBufferSize(int bufferSize)
{
if (isRunning())
throw new IllegalStateException(getState());
removeBean(_buffers);
_buffers=new WebSocketBuffers(bufferSize);
addBean(_buffers);
}
/* ------------------------------------------------------------ */
/**
* @return the read buffer size
*/
public int getBufferSize()
{
return _buffers.getBufferSize();
}
/* ------------------------------------------------------------ */
/**
* <p>Creates and returns a new instance of a {@link WebSocketClient}, configured with this
* WebSocketClientFactory instance.</p>
*
* @return a new {@link WebSocketClient} instance
*/
public WebSocketClient newWebSocketClient() public WebSocketClient newWebSocketClient()
{ {
return new WebSocketClient(this); return new WebSocketClient(this);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
protected void doStart() throws Exception protected void doStart() throws Exception
{ {
super.doStart(); super.doStart();
if (getThreadPool() instanceof LifeCycle && !((LifeCycle)getThreadPool()).isStarted())
// Start a selector threads ((LifeCycle)getThreadPool()).start();
for (int i=0;i<_selector.getSelectSets();i++)
{
final int id=i;
_threadPool.dispatch(new Runnable()
{
public void run()
{
while(isRunning())
{
try
{
_selector.doSelect(id);
}
catch (IOException e)
{
__log.warn(e);
}
}
}
});
}
} }
/* ------------------------------------------------------------ */
@Override
protected void doStop() throws Exception
{
super.doStop();
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** WebSocket Client Selector Manager /** WebSocket Client Selector Manager
@ -274,7 +319,7 @@ public class WebSocketClientFactory extends AggregateLifeCycle
path="/"; path="/";
String origin = future.getOrigin(); String origin = future.getOrigin();
String request= String request=
"GET "+path+" HTTP/1.1\r\n"+ "GET "+path+" HTTP/1.1\r\n"+
"Host: "+future.getURI().getHost()+":"+_holder.getURI().getPort()+"\r\n"+ "Host: "+future.getURI().getHost()+":"+_holder.getURI().getPort()+"\r\n"+
@ -373,8 +418,4 @@ public class WebSocketClientFactory extends AggregateLifeCycle
_holder.handshakeFailed(new EOFException()); _holder.handshakeFailed(new EOFException());
} }
} }
} }

View File

@ -58,7 +58,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
final static int CLOSE_SHUTDOWN=1001; final static int CLOSE_SHUTDOWN=1001;
final static int CLOSE_PROTOCOL=1002; final static int CLOSE_PROTOCOL=1002;
final static int CLOSE_BADDATA=1003; final static int CLOSE_BADDATA=1003;
final static int CLOSE_LARGE=1004;
final static int CLOSE_NOCODE=1005; final static int CLOSE_NOCODE=1005;
final static int CLOSE_NOCLOSE=1006; final static int CLOSE_NOCLOSE=1006;
final static int CLOSE_NOTUTF8=1007; final static int CLOSE_NOTUTF8=1007;
@ -135,7 +134,6 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
_context=Thread.currentThread().getContextClassLoader(); _context=Thread.currentThread().getContextClassLoader();
// TODO - can we use the endpoint idle mechanism?
if (endpoint instanceof AsyncEndPoint) if (endpoint instanceof AsyncEndPoint)
((AsyncEndPoint)endpoint).cancelIdle(); ((AsyncEndPoint)endpoint).cancelIdle();
@ -772,7 +770,7 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
int max = _connection.getMaxBinaryMessageSize(); int max = _connection.getMaxBinaryMessageSize();
if (max>0 && (bufferLen+length)>max) if (max>0 && (bufferLen+length)>max)
{ {
_connection.close(WebSocketConnectionD12.CLOSE_LARGE,"Message size > "+_connection.getMaxBinaryMessageSize()); _connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Message size > "+_connection.getMaxBinaryMessageSize());
_opcode=-1; _opcode=-1;
if (_aggregate!=null) if (_aggregate!=null)
_aggregate.clear(); _aggregate.clear();
@ -783,7 +781,7 @@ public class WebSocketConnectionD12 extends AbstractConnection implements WebSoc
private void textMessageTooLarge() private void textMessageTooLarge()
{ {
_connection.close(WebSocketConnectionD12.CLOSE_LARGE,"Text message size > "+_connection.getMaxTextMessageSize()+" chars"); _connection.close(WebSocketConnectionD12.CLOSE_BADDATA,"Text message size > "+_connection.getMaxTextMessageSize()+" chars");
_opcode=-1; _opcode=-1;
_utf8.reset(); _utf8.reset();

View File

@ -249,7 +249,7 @@ public class WebSocketParserD12 implements WebSocketParser
if (_length>_buffer.capacity() && !_fakeFragments) if (_length>_buffer.capacity() && !_fakeFragments)
{ {
events++; events++;
_handler.close(WebSocketConnectionD12.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _handler.close(WebSocketConnectionD12.CLOSE_BADDATA,"frame size "+_length+">"+_buffer.capacity());
_skip=true; _skip=true;
} }
@ -268,7 +268,7 @@ public class WebSocketParserD12 implements WebSocketParser
if (_length>=_buffer.capacity()) if (_length>=_buffer.capacity())
{ {
events++; events++;
_handler.close(WebSocketConnectionD12.CLOSE_LARGE,"frame size "+_length+">"+_buffer.capacity()); _handler.close(WebSocketConnectionD12.CLOSE_BADDATA,"frame size "+_length+">"+_buffer.capacity());
_skip=true; _skip=true;
} }

View File

@ -492,7 +492,7 @@ public class WebSocketMessageD12Test
assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read());
assertEquals(30,input.read()); assertEquals(30,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(WebSocketConnectionD12.CLOSE_BADDATA,code);
lookFor("Text message size > 15 chars",input); lookFor("Text message size > 15 chars",input);
} }
@ -543,7 +543,7 @@ public class WebSocketMessageD12Test
assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read());
assertEquals(30,input.read()); assertEquals(30,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(WebSocketConnectionD12.CLOSE_BADDATA,code);
lookFor("Text message size > 15 chars",input); lookFor("Text message size > 15 chars",input);
} }
@ -657,7 +657,7 @@ public class WebSocketMessageD12Test
assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read());
assertEquals(19,input.read()); assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(WebSocketConnectionD12.CLOSE_BADDATA,code);
lookFor("Message size > 15",input); lookFor("Message size > 15",input);
} }
@ -706,7 +706,7 @@ public class WebSocketMessageD12Test
assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read()); assertEquals(0x80|WebSocketConnectionD12.OP_CLOSE,input.read());
assertEquals(19,input.read()); assertEquals(19,input.read());
int code=(0xff&input.read())*0x100+(0xff&input.read()); int code=(0xff&input.read())*0x100+(0xff&input.read());
assertEquals(1004,code); assertEquals(WebSocketConnectionD12.CLOSE_BADDATA,code);
lookFor("Message size > 15",input); lookFor("Message size > 15",input);
} }

View File

@ -269,7 +269,7 @@ public class WebSocketParserD12Test
assertTrue(progress>0); assertTrue(progress>0);
assertEquals(WebSocketConnectionD12.CLOSE_LARGE,_handler._code); assertEquals(WebSocketConnectionD12.CLOSE_BADDATA,_handler._code);
for (int i=0;i<2048;i++) for (int i=0;i<2048;i++)
_in.put((byte)'a'); _in.put((byte)'a');
progress =_parser.parseNext(); progress =_parser.parseNext();

View File

@ -310,7 +310,10 @@ public class XmlConfiguration
// Check the class of the object // Check the class of the object
Class<?> oClass = (Class<?>)nodeClass(_config); Class<?> oClass = (Class<?>)nodeClass(_config);
if (oClass != null && !oClass.isInstance(obj)) if (oClass != null && !oClass.isInstance(obj))
throw new IllegalArgumentException("Object is not of type " + oClass); {
String loaders = (oClass.getClassLoader()==obj.getClass().getClassLoader())?"":"Object Class and type Class are from different loaders.";
throw new IllegalArgumentException("Object of class '"+obj.getClass().getCanonicalName()+"' is not of type '" + oClass.getCanonicalName()+"'. "+loaders);
}
configure(obj,_config,0); configure(obj,_config,0);
return obj; return obj;
} }

View File

@ -26,6 +26,11 @@
<artifactId>test-integration</artifactId> <artifactId>test-integration</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Jetty Tests :: Integrations</name> <name>Jetty Tests :: Integrations</name>
<properties>
<test-wars-dir>${project.build.directory}/test-wars</test-wars-dir>
<test-libs-dir>${project.build.directory}/test-libs</test-libs-dir>
<test-dist-dir>${project.build.directory}/test-dist</test-dist-dir>
</properties>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -50,6 +55,34 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-jetty-distro</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<version>${project.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
<outputDirectory>${test-dist-dir}</outputDirectory>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
@ -73,6 +106,11 @@
<artifactId>jetty-client</artifactId> <artifactId>jetty-client</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-monitor</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty.toolchain</groupId> <groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId> <artifactId>jetty-test-helper</artifactId>

View File

@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.monitor; package org.eclipse.jetty.test.monitor;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;

View File

@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.monitor; package org.eclipse.jetty.test.monitor;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;

View File

@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.monitor; package org.eclipse.jetty.test.monitor;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;

View File

@ -11,7 +11,7 @@
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.monitor; package org.eclipse.jetty.test.monitor;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;