Merge branch 'jetty-9.4.x' into distro-rework-589

This commit is contained in:
Jesse McConnell 2016-06-13 10:08:22 -05:00
commit 9ca6d617a8
14 changed files with 374 additions and 497 deletions

View File

@ -18,7 +18,6 @@
package org.eclipse.jetty.embedded;
import org.eclipse.jetty.http.HttpCompliance;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
@ -27,7 +26,6 @@ public class OneHandler
public static void main( String[] args ) throws Exception
{
Server server = new Server(8080);
server.getConnectors()[0].getConnectionFactory(HttpConnectionFactory.class).setHttpCompliance(HttpCompliance.LEGACY);
server.setHandler(new HelloHandler());
server.start();

View File

@ -265,6 +265,31 @@ public class HttpChannel implements Runnable, HttpOutput.Interceptor
{
handle();
}
// TODO Revert once #624 debugged
private static ThreadLocal<Throwable> __dispatchedFrom=new ThreadLocal<>();
public static Throwable getDispatchedFrom() { return __dispatchedFrom.get(); }
public Runnable getRunnable()
{
Throwable _dispatched = new Throwable();
return new Runnable()
{
@Override
public void run()
{
try
{
__dispatchedFrom.set(_dispatched);
handle();
}
finally
{
__dispatchedFrom.set(null);
}
}
};
}
AtomicReference<Action> caller = new AtomicReference<>();

View File

@ -615,7 +615,7 @@ public class HttpChannelState
cancelTimeout(event);
if (handle)
runInContext(event,_channel);
runInContext(event,_channel.getRunnable());
}
public void errorComplete()
@ -887,7 +887,7 @@ public class HttpChannelState
protected void scheduleDispatch()
{
_channel.execute(_channel);
_channel.execute(_channel.getRunnable());
}
protected void scheduleTimeout(AsyncContextEvent event)

View File

@ -122,7 +122,7 @@ public class HttpInput extends ServletInputStream implements Runnable
{
HttpChannel channel = _channelState.getHttpChannel();
Executor executor = channel.getConnector().getServer().getThreadPool();
executor.execute(channel);
executor.execute(channel.getRunnable());
}

View File

@ -860,7 +860,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
{
_writeListener = writeListener;
if (_channel.getState().onWritePossible())
_channel.execute(_channel);
_channel.execute(_channel.getRunnable());
}
else
throw new IllegalStateException();
@ -1005,7 +1005,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
if (!_state.compareAndSet(OutputState.UNREADY, OutputState.READY))
continue;
if (_channel.getState().onWritePossible())
_channel.execute(_channel);
_channel.execute(_channel.getRunnable());
break;
case CLOSED:
@ -1023,7 +1023,7 @@ public class HttpOutput extends ServletOutputStream implements Runnable
{
_onError=e==null?new IOException():e;
if (_channel.getState().onWritePossible())
_channel.execute(_channel);
_channel.execute(_channel.getRunnable());
}
}

View File

@ -18,12 +18,9 @@
package org.eclipse.jetty.server;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
@ -37,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.thread.Locker;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
@ -45,6 +43,10 @@ import org.junit.Test;
public class LocalAsyncContextTest
{
private final Locker _completeLock = new Locker();
private Throwable __completed;
private Throwable __dispatched;
private final AtomicReference<Throwable> __completed1 = new AtomicReference<>();
protected Server _server;
protected SuspendHandler _handler;
protected Connector _connector;
@ -54,7 +56,7 @@ public class LocalAsyncContextTest
{
_server = new Server();
_connector = initConnector();
_server.setConnectors(new Connector[]{ _connector });
_server.addConnector(_connector);
SessionHandler session = new SessionHandler();
_handler = new SuspendHandler();
@ -63,7 +65,10 @@ public class LocalAsyncContextTest
_server.setHandler(session);
_server.start();
__completed.set(null);
try (Locker.Lock lock = _completeLock.lock())
{
__completed = null;
}
__completed1.set(null);
}
@ -87,10 +92,17 @@ public class LocalAsyncContextTest
_handler.setSuspendFor(1000);
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(-1);
response=process(null);
check(response,"TIMEOUT");
spinAssertEquals(1,()->{return __completed.get()==null?0:1;});
spinAssertEquals(1,()->{return __completed1.get()==null?0:1;});
response = process(null);
check(response, "TIMEOUT");
spinAssertEquals(1, () ->
{
try (Locker.Lock lock = _completeLock.lock())
{
return __completed == null ? 0 : 1;
}
});
spinAssertEquals(1, () -> __completed1.get() == null ? 0 : 1);
}
@Test
@ -101,8 +113,8 @@ public class LocalAsyncContextTest
_handler.setSuspendFor(10000);
_handler.setResumeAfter(0);
_handler.setCompleteAfter(-1);
response=process(null);
check(response,"STARTASYNC","DISPATCHED");
response = process(null);
check(response, "STARTASYNC", "DISPATCHED");
}
@Test
@ -113,8 +125,8 @@ public class LocalAsyncContextTest
_handler.setSuspendFor(10000);
_handler.setResumeAfter(100);
_handler.setCompleteAfter(-1);
response=process(null);
check(response,"STARTASYNC","DISPATCHED");
response = process(null);
check(response, "STARTASYNC", "DISPATCHED");
}
@Test
@ -125,8 +137,8 @@ public class LocalAsyncContextTest
_handler.setSuspendFor(10000);
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(0);
response=process(null);
check(response,"STARTASYNC","COMPLETED");
response = process(null);
check(response, "STARTASYNC", "COMPLETED");
}
@Test
@ -137,9 +149,8 @@ public class LocalAsyncContextTest
_handler.setSuspendFor(10000);
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(200);
response=process(null);
check(response,"STARTASYNC","COMPLETED");
response = process(null);
check(response, "STARTASYNC", "COMPLETED");
}
@Test
@ -150,8 +161,8 @@ public class LocalAsyncContextTest
_handler.setRead(-1);
_handler.setResumeAfter(0);
_handler.setCompleteAfter(-1);
response=process("wibble");
check(response,"STARTASYNC","DISPATCHED");
response = process("wibble");
check(response, "STARTASYNC", "DISPATCHED");
}
@Test
@ -162,9 +173,8 @@ public class LocalAsyncContextTest
_handler.setRead(-1);
_handler.setResumeAfter(100);
_handler.setCompleteAfter(-1);
response=process("wibble");
check(response,"DISPATCHED");
response = process("wibble");
check(response, "DISPATCHED");
}
@Test
@ -175,35 +185,35 @@ public class LocalAsyncContextTest
_handler.setRead(-1);
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(0);
response=process("wibble");
check(response,"COMPLETED");
response = process("wibble");
check(response, "COMPLETED");
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(100);
response=process("wibble");
check(response,"COMPLETED");
response = process("wibble");
check(response, "COMPLETED");
_handler.setRead(6);
_handler.setResumeAfter(0);
_handler.setCompleteAfter(-1);
response=process("wibble");
check(response,"DISPATCHED");
response = process("wibble");
check(response, "DISPATCHED");
_handler.setResumeAfter(100);
_handler.setCompleteAfter(-1);
response=process("wibble");
check(response,"DISPATCHED");
response = process("wibble");
check(response, "DISPATCHED");
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(0);
response=process("wibble");
check(response,"COMPLETED");
response = process("wibble");
check(response, "COMPLETED");
_handler.setResumeAfter(-1);
_handler.setCompleteAfter(100);
response=process("wibble");
check(response,"COMPLETED");
response = process("wibble");
check(response, "COMPLETED");
}
@Test
@ -218,345 +228,289 @@ public class LocalAsyncContextTest
_handler.setSuspendFor2(1000);
_handler.setResumeAfter2(200);
_handler.setCompleteAfter2(-1);
response=process(null);
check(response,"STARTASYNC","DISPATCHED","startasync","STARTASYNC","DISPATCHED");
spinAssertEquals(1,()->{return __completed.get()==null?0:1;});
spinAssertEquals(0,()->{return __completed1.get()==null?0:1;});
response = process(null);
check(response, "STARTASYNC", "DISPATCHED", "startasync", "STARTASYNC2", "DISPATCHED");
spinAssertEquals(1, () ->
{
try (Locker.Lock lock = _completeLock.lock())
{
return __completed == null ? 0 : 1;
}
});
spinAssertEquals(0, () -> __completed1.get() == null ? 0 : 1);
}
protected void check(String response,String... content)
protected void check(String response, String... content)
{
Assert.assertThat(response,Matchers.startsWith("HTTP/1.1 200 OK"));
int i=0;
for (String m:content)
Assert.assertThat(response, Matchers.startsWith("HTTP/1.1 200 OK"));
int i = 0;
for (String m : content)
{
Assert.assertThat(response,Matchers.containsString(m));
i=response.indexOf(m,i);
i+=m.length();
Assert.assertThat(response, Matchers.containsString(m));
i = response.indexOf(m, i);
i += m.length();
}
}
private synchronized String process(String content) throws Exception
{
String request = "GET / HTTP/1.1\r\n" +
"Host: localhost\r\n"+
"Connection: close\r\n";
"Host: localhost\r\n" +
"Connection: close\r\n";
if (content==null)
request+="\r\n";
if (content == null)
request += "\r\n";
else
request+="Content-Length: "+content.length()+"\r\n" +"\r\n" + content;
request += "Content-Length: " + content.length() + "\r\n" + "\r\n" + content;
String response=getResponse(request);
return response;
return getResponse(request);
}
protected String getResponse(String request) throws Exception
{
LocalConnector connector=(LocalConnector)_connector;
LocalConnector connector = (LocalConnector)_connector;
LocalConnector.LocalEndPoint endp = connector.executeRequest(request);
endp.waitUntilClosed();
return endp.takeOutputString();
}
private static class SuspendHandler extends HandlerWrapper
private class SuspendHandler extends HandlerWrapper
{
private int _read;
private long _suspendFor=-1;
private long _resumeAfter=-1;
private long _completeAfter=-1;
private long _suspendFor2=-1;
private long _resumeAfter2=-1;
private long _completeAfter2=-1;
private long _suspendFor = -1;
private long _resumeAfter = -1;
private long _completeAfter = -1;
private long _suspendFor2 = -1;
private long _resumeAfter2 = -1;
private long _completeAfter2 = -1;
public SuspendHandler()
{
}
public int getRead()
{
return _read;
}
public void setRead(int read)
{
_read = read;
}
public long getSuspendFor()
{
return _suspendFor;
}
public void setSuspendFor(long suspendFor)
{
_suspendFor = suspendFor;
}
public long getResumeAfter()
{
return _resumeAfter;
}
public void setResumeAfter(long resumeAfter)
{
_resumeAfter = resumeAfter;
}
public long getCompleteAfter()
{
return _completeAfter;
}
public void setCompleteAfter(long completeAfter)
{
_completeAfter = completeAfter;
}
/* ------------------------------------------------------------ */
/** Get the suspendFor2.
* @return the suspendFor2
*/
public long getSuspendFor2()
{
return _suspendFor2;
}
/* ------------------------------------------------------------ */
/** Set the suspendFor2.
* @param suspendFor2 the suspendFor2 to set
*/
public void setSuspendFor2(long suspendFor2)
{
_suspendFor2 = suspendFor2;
}
/* ------------------------------------------------------------ */
/** Get the resumeAfter2.
* @return the resumeAfter2
*/
public long getResumeAfter2()
{
return _resumeAfter2;
}
/* ------------------------------------------------------------ */
/** Set the resumeAfter2.
* @param resumeAfter2 the resumeAfter2 to set
*/
public void setResumeAfter2(long resumeAfter2)
{
_resumeAfter2 = resumeAfter2;
}
/* ------------------------------------------------------------ */
/** Get the completeAfter2.
* @return the completeAfter2
*/
public long getCompleteAfter2()
{
return _completeAfter2;
}
/* ------------------------------------------------------------ */
/** Set the completeAfter2.
* @param completeAfter2 the completeAfter2 to set
*/
public void setCompleteAfter2(long completeAfter2)
{
_completeAfter2 = completeAfter2;
}
/* ------------------------------------------------------------ */
@Override
public void handle(String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
try
if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
{
if (DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
if (_read > 0)
{
if (_read>0)
{
byte[] buf=new byte[_read];
request.getInputStream().read(buf);
}
else if (_read<0)
{
InputStream in = request.getInputStream();
int b=in.read();
while(b!=-1)
b=in.read();
}
int read = _read;
byte[] buf = new byte[read];
while (read > 0)
read -= request.getInputStream().read(buf);
}
else if (_read < 0)
{
InputStream in = request.getInputStream();
int b = in.read();
while (b != -1)
b = in.read();
}
final AsyncContext asyncContext = baseRequest.startAsync();
response.getOutputStream().println("STARTASYNC");
asyncContext.addListener(__asyncListener);
asyncContext.addListener(__asyncListener1);
if (_suspendFor > 0)
asyncContext.setTimeout(_suspendFor);
if (_completeAfter > 0)
{
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(_completeAfter);
response.getOutputStream().println("COMPLETED");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_completeAfter == 0)
{
response.getOutputStream().println("COMPLETED");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
if (_resumeAfter > 0)
{
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(_resumeAfter);
if (((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId() != null)
asyncContext.dispatch();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_resumeAfter == 0)
{
asyncContext.dispatch();
}
}
else
{
if (request.getAttribute("TIMEOUT") != null)
response.getOutputStream().println("TIMEOUT");
else
response.getOutputStream().println("DISPATCHED");
if (_suspendFor2 >= 0)
{
final AsyncContext asyncContext = baseRequest.startAsync();
response.getOutputStream().println("STARTASYNC");
asyncContext.addListener(__asyncListener);
asyncContext.addListener(__asyncListener1);
if (_suspendFor>0)
asyncContext.setTimeout(_suspendFor);
response.getOutputStream().println("STARTASYNC2");
if (_suspendFor2 > 0)
asyncContext.setTimeout(_suspendFor2);
_suspendFor2 = -1;
if (_completeAfter>0)
if (_completeAfter2 > 0)
{
new Thread() {
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(_completeAfter);
response.getOutputStream().println("COMPLETED");
Thread.sleep(_completeAfter2);
response.getOutputStream().println("COMPLETED2");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
catch(Exception e)
catch (Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_completeAfter==0)
else if (_completeAfter2 == 0)
{
response.getOutputStream().println("COMPLETED");
response.getOutputStream().println("COMPLETED2");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
if (_resumeAfter>0)
if (_resumeAfter2 > 0)
{
new Thread() {
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(_resumeAfter);
if(((HttpServletRequest)asyncContext.getRequest()).getSession(true).getId()!=null)
asyncContext.dispatch();
Thread.sleep(_resumeAfter2);
asyncContext.dispatch();
}
catch(Exception e)
catch (Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_resumeAfter==0)
else if (_resumeAfter2 == 0)
{
asyncContext.dispatch();
}
}
else
{
if (request.getAttribute("TIMEOUT")!=null)
{
response.getOutputStream().println("TIMEOUT");
}
else
{
response.getOutputStream().println("DISPATCHED");
}
if (_suspendFor2>=0)
{
final AsyncContext asyncContext = baseRequest.startAsync();
response.getOutputStream().println("STARTASYNC2");
if (_suspendFor2>0)
asyncContext.setTimeout(_suspendFor2);
_suspendFor2=-1;
if (_completeAfter2>0)
{
new Thread() {
@Override
public void run()
{
try
{
Thread.sleep(_completeAfter2);
response.getOutputStream().println("COMPLETED2");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_completeAfter2==0)
{
response.getOutputStream().println("COMPLETED2");
response.setStatus(200);
baseRequest.setHandled(true);
asyncContext.complete();
}
if (_resumeAfter2>0)
{
new Thread() {
@Override
public void run()
{
try
{
Thread.sleep(_resumeAfter2);
asyncContext.dispatch();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}.start();
}
else if (_resumeAfter2==0)
{
asyncContext.dispatch();
}
}
else
{
response.setStatus(200);
baseRequest.setHandled(true);
}
response.setStatus(200);
baseRequest.setHandled(true);
}
}
finally
{
}
}
}
static AtomicReference<Throwable> __completed = new AtomicReference<>();
static AtomicReference<Throwable> __completed1 = new AtomicReference<>();
private static AsyncListener __asyncListener = new AsyncListener()
private AsyncListener __asyncListener = new AsyncListener()
{
@Override
public void onComplete(AsyncEvent event) throws IOException
{
Throwable complete = new Throwable();
if (!__completed.compareAndSet(null,complete))
Throwable dispatched = HttpChannel.getDispatchedFrom();
try (Locker.Lock lock = _completeLock.lock())
{
__completed.get().printStackTrace();
complete.printStackTrace();
__completed.set(null);
throw new IllegalStateException();
if (__completed == null)
{
__completed = complete;
__dispatched = dispatched;
}
else
{
System.err.println("First onCompleted dispatched from:");
if (__dispatched != null)
__dispatched.printStackTrace();
System.err.println("First onCompleted:");
__completed.printStackTrace();
System.err.println("Second onCompleted dispatched from:");
if (dispatched != null)
dispatched.printStackTrace();
complete.printStackTrace();
throw new IllegalStateException();
}
}
}
@ -564,12 +518,27 @@ public class LocalAsyncContextTest
public void onError(AsyncEvent event) throws IOException
{
Throwable complete = new Throwable();
if (!__completed.compareAndSet(null,complete))
Throwable dispatched = HttpChannel.getDispatchedFrom();
try (Locker.Lock lock = _completeLock.lock())
{
__completed.get().printStackTrace();
complete.printStackTrace();
__completed.set(null);
throw new IllegalStateException();
if (__completed == null)
{
__completed = complete;
__dispatched = dispatched;
}
else
{
System.err.println("First onCompleted dispatched from:");
if (__dispatched != null)
__dispatched.printStackTrace();
System.err.println("First onCompleted:");
__completed.printStackTrace();
System.err.println("Second onCompleted dispatched from:");
if (dispatched != null)
dispatched.printStackTrace();
complete.printStackTrace();
throw new IllegalStateException();
}
}
}
@ -583,18 +552,18 @@ public class LocalAsyncContextTest
@Override
public void onTimeout(AsyncEvent event) throws IOException
{
event.getSuppliedRequest().setAttribute("TIMEOUT",Boolean.TRUE);
event.getSuppliedRequest().setAttribute("TIMEOUT", Boolean.TRUE);
event.getAsyncContext().dispatch();
}
};
private static AsyncListener __asyncListener1 = new AsyncListener()
private AsyncListener __asyncListener1 = new AsyncListener()
{
@Override
public void onComplete(AsyncEvent event) throws IOException
{
Throwable complete = new Throwable();
if (!__completed1.compareAndSet(null,complete))
if (!__completed1.compareAndSet(null, complete))
{
__completed1.get().printStackTrace();
complete.printStackTrace();
@ -607,7 +576,7 @@ public class LocalAsyncContextTest
public void onError(AsyncEvent event) throws IOException
{
Throwable complete = new Throwable();
if (!__completed1.compareAndSet(null,complete))
if (!__completed1.compareAndSet(null, complete))
{
__completed1.get().printStackTrace();
complete.printStackTrace();
@ -615,7 +584,7 @@ public class LocalAsyncContextTest
throw new IllegalStateException();
}
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException
{
@ -625,24 +594,23 @@ public class LocalAsyncContextTest
public void onTimeout(AsyncEvent event) throws IOException
{
}
};
static <T> void spinAssertEquals(T expected, Supplier<T> actualSupplier)
{
spinAssertEquals(expected,actualSupplier,10,TimeUnit.SECONDS);
spinAssertEquals(expected, actualSupplier, 10, TimeUnit.SECONDS);
}
static <T> void spinAssertEquals(T expected, Supplier<T> actualSupplier, long waitFor, TimeUnit units)
{
long now = System.nanoTime();
long end = now+units.toNanos(waitFor);
T actual=null;
while(now < end)
long end = now + units.toNanos(waitFor);
T actual = null;
while (now < end)
{
actual=actualSupplier.get();
if (actual==null && expected==null ||
actual!=null && actual.equals(expected))
actual = actualSupplier.get();
if (actual == null && expected == null ||
actual != null && actual.equals(expected))
break;
try
{
@ -650,10 +618,11 @@ public class LocalAsyncContextTest
}
catch (InterruptedException e)
{
// Ignored
}
now = System.nanoTime();
}
assertEquals(expected,actual);
Assert.assertEquals(expected, actual);
}
}

View File

@ -181,7 +181,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
{
//Resource represents a packed jar
URI uri = target.getURI();
resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources");
resourcesDir = Resource.newResource(uriJarPrefix(uri,"!/META-INF/resources"));
}
if (!resourcesDir.exists() || !resourcesDir.isDirectory())
@ -252,7 +252,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
else
{
URI uri = jar.getURI();
webFrag = Resource.newResource("jar:"+uri+"!/META-INF/web-fragment.xml");
webFrag = Resource.newResource(uriJarPrefix(uri,"!/META-INF/web-fragment.xml"));
}
if (!webFrag.exists() || webFrag.isDirectory())
{
@ -401,8 +401,9 @@ public class MetaInfConfiguration extends AbstractConfiguration
public Collection<URL> getTlds (URI uri) throws IOException
{
HashSet<URL> tlds = new HashSet<URL>();
URL url = new URL("jar:"+uri+"!/");
String jarUri = uriJarPrefix(uri, "!/");
URL url = new URL(jarUri);
JarURLConnection jarConn = (JarURLConnection) url.openConnection();
jarConn.setUseCaches(Resource.getDefaultUseCaches());
JarFile jarFile = jarConn.getJarFile();
@ -413,11 +414,21 @@ public class MetaInfConfiguration extends AbstractConfiguration
String name = e.getName();
if (name.startsWith("META-INF") && name.endsWith(".tld"))
{
tlds.add(new URL("jar:"+uri+"!/"+name));
tlds.add(new URL(jarUri + name));
}
}
if (!Resource.getDefaultUseCaches())
jarFile.close();
return tlds;
}
private String uriJarPrefix(URI uri, String suffix)
{
String uriString = uri.toString();
if (uriString.startsWith("jar:")) {
return uriString + suffix;
} else {
return "jar:" + uriString + suffix;
}
}
}

View File

@ -14,17 +14,18 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<bundle-symbolic-name>${project.groupId}.jmx.webapp.it</bundle-symbolic-name>
<scripts-dir>${project.basedir}/src/test/scripts</scripts-dir>
<test-base-dir>${project.build.directory}/test-base</test-base-dir>
<test-home-dir>${project.build.directory}/test-home</test-home-dir>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-distribution</artifactId>
<artifactId>jetty-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>${project.version}</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
@ -61,22 +62,6 @@
<outputDirectory>${test-base-dir}/webapps</outputDirectory>
</configuration>
</execution>
<execution>
<id>unpack-jetty-distro</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>jetty-distribution</includeArtifactIds>
<includeScope>runtime</includeScope>
<includeTypes>zip</includeTypes>
<outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
<outputDirectory>${test-home-dir}</outputDirectory>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
@ -91,98 +76,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="jetty.jmx.home" location="${test-home-dir}/jetty-distribution-${project.version}" />
<property name="jetty.jmx.base" location="${test-base-dir}" />
<echo>Integration Test : Setup Jetty</echo>
<exec executable="${run.command}" dir="${scripts-dir}" spawn="false">
<arg value="${run.command.xtra}" />
<arg value="${setup.script}" />
<arg file="${java.home}" />
<arg file="${jetty.jmx.home}" />
<arg file="${jetty.jmx.base}" />
</exec>
<echo>Integration Test : Starting Jetty ...</echo>
<exec executable="${run.command}" dir="${scripts-dir}" spawn="true">
<arg value="${run.command.xtra}" />
<arg value="${start.script}" />
<arg file="${java.home}" />
<arg file="${jetty.jmx.home}" />
<arg file="${jetty.jmx.base}" />
</exec>
<waitfor maxwait="5" maxwaitunit="second" checkevery="500" checkeveryunit="millisecond">
<http url="http://localhost:58080/jmx-webapp/" />
</waitfor>
<echo>Integration Test : Jetty is now available</echo>
</target>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="jetty.jmx.home" location="${test-home-dir}/jetty-distribution-${project.version}" />
<property name="jetty.jmx.base" location="${test-base-dir}" />
<echo>Integration Test : Stop Jetty</echo>
<exec executable="${run.command}" dir="${scripts-dir}" spawn="false">
<arg value="${run.command.xtra}" />
<arg value="${stop.script}" />
<arg file="${java.home}" />
<arg file="${jetty.jmx.home}" />
<arg file="${jetty.jmx.base}" />
</exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>it-windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<properties>
<run.command>cmd</run.command>
<run.command.xtra>/c</run.command.xtra>
<start.script>start-jetty.bat</start.script>
<stop.script>stop-jetty.bat</stop.script>
</properties>
</profile>
<profile>
<id>it-unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<run.command>sh</run.command>
<run.command.xtra>--</run.command.xtra>
<setup.script>setup-jetty.sh</setup.script>
<start.script>start-jetty.sh</start.script>
<stop.script>stop-jetty.sh</stop.script>
</properties>
</profile>
</profiles>
</project>

View File

@ -24,7 +24,9 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.URI;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
@ -32,6 +34,14 @@ import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.SimpleRequest;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.jmx.ConnectorServer;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.NetworkConnector;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -41,26 +51,78 @@ import org.junit.Test;
*/
public class JmxIT
{
private static JMXConnector jmxc;
private static MBeanServerConnection mbsc;
private static JMXConnector __jmxc;
private static MBeanServerConnection __mbsc;
private static Server __server;
private static int __port;
@BeforeClass
public static void connectToMBeanServer() throws IOException
public static void connectToMBeanServer() throws Exception
{
startJetty();
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:1099/jndi/rmi://localhost:1099/jmxrmi");
jmxc = JMXConnectorFactory.connect(url,null);
mbsc = jmxc.getMBeanServerConnection();
__jmxc = JMXConnectorFactory.connect(url,null);
__mbsc = __jmxc.getMBeanServerConnection();
}
@AfterClass
public static void disconnectFromMBeanServer() throws IOException
public static void disconnectFromMBeanServer() throws Exception
{
jmxc.close();
stopJetty();
__jmxc.close();
}
public static void startJetty() throws Exception
{
File target = MavenTestingUtils.getTargetDir();
File jettyBase = new File (target, "test-base");
File webapps = new File (jettyBase, "webapps");
File war = new File (webapps, "jmx-webapp.war");
//create server instance
__server = new Server(0);
//set up the webapp
WebAppContext context = new WebAppContext();
context.setWar(war.getCanonicalPath());
context.setContextPath("/jmx-webapp");
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(__server);
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
context.setAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
__server.setHandler(context);
//set up jmx remote
MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
__server.addBean(mbContainer);
JMXServiceURL serviceUrl = new JMXServiceURL("rmi", "localhost", 1099, "/jndi/rmi://localhost:1099/jmxrmi");
ConnectorServer jmxConnServer = new ConnectorServer(serviceUrl, "org.eclipse.jetty.jmx:name=rmiconnectorserver");
__server.addBean(jmxConnServer);
//start server
__server.start();
//remember chosen port
__port = ((NetworkConnector)__server.getConnectors()[0]).getLocalPort();
}
public static void stopJetty () throws Exception
{
if (__server != null)
__server.stop();
}
private String getStringAttribute(ObjectName objName, String attrName) throws Exception
{
Object val = mbsc.getAttribute(objName,attrName);
Object val = __mbsc.getAttribute(objName,attrName);
assertThat(attrName,val,notNullValue());
assertThat(attrName,val,instanceOf(String.class));
return (String)val;
@ -68,18 +130,25 @@ public class JmxIT
private int getIntegerAttribute(ObjectName objName, String attrName) throws Exception
{
Object val = mbsc.getAttribute(objName,attrName);
Object val = __mbsc.getAttribute(objName,attrName);
assertThat(attrName,val,notNullValue());
assertThat(attrName,val,instanceOf(Integer.class));
return (Integer)val;
}
@Test
public void testBasic() throws Exception
{
URI serverURI = new URI("http://localhost:"+String.valueOf(__port)+"/jmx-webapp/");
SimpleRequest req = new SimpleRequest(serverURI);
assertThat(req.getString("ping"),startsWith("Servlet Pong at "));
}
@Test
public void testObtainRunningServerVersion() throws Exception
{
ObjectName serverName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
String version = getStringAttribute(serverName,"version");
System.err.println("Running version: " + version);
assertThat("Version",version,startsWith("9.4."));
}
@ -117,7 +186,7 @@ public class JmxIT
// Get initial count
int count = getIntegerAttribute(pingerName,"count");
// Operations
Object val = mbsc.invoke(pingerName,"ping",null,null);
Object val = __mbsc.invoke(pingerName,"ping",null,null);
assertThat("ping() return",val.toString(),startsWith("Pong"));
// Attributes
assertThat("count",getIntegerAttribute(pingerName,"count"),is(count+1));
@ -134,7 +203,7 @@ public class JmxIT
// Get initial count
int count = getIntegerAttribute(echoerName,"count");
// Operations
Object val = mbsc.invoke(echoerName,"echo",new Object[]{"Its Me"},new String[]{String.class.getName()});
Object val = __mbsc.invoke(echoerName,"echo",new Object[]{"Its Me"},new String[]{String.class.getName()});
assertThat("echo() return",val.toString(),is("Its Me"));
// Attributes
assertThat("count",getIntegerAttribute(echoerName,"count"),is(count+1));

View File

@ -1,41 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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 org.eclipse.jetty.test.jmx;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import java.net.URI;
import org.eclipse.jetty.toolchain.test.SimpleRequest;
import org.junit.Test;
/**
* Basic tests for a simple Servlet with no JMX involved (yet)
*/
public class PingIT
{
@Test
public void testBasic() throws Exception
{
URI serverURI = new URI("http://localhost:58080/jmx-webapp/");
SimpleRequest req = new SimpleRequest(serverURI);
assertThat(req.getString("ping"),startsWith("Servlet Pong at "));
}
}

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
JAVA_HOME=$1
JETTY_HOME=$2
JETTY_BASE=$3
echo \${java.home} : $JAVA_HOME
echo \${jetty.home} : $JETTY_HOME
echo \${jetty.base} : $JETTY_BASE
cd "$JETTY_BASE"
"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
--approve-all-licenses \
--add-to-start=deploy,http,annotations,jmx,jmx-remote,logging
"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
--version

View File

@ -1,17 +0,0 @@
#!/usr/bin/env bash
JAVA_HOME=$1
JETTY_HOME=$2
JETTY_BASE=$3
echo \${java.home} : $JAVA_HOME
echo \${jetty.home} : $JETTY_HOME
echo \${jetty.base} : $JETTY_BASE
cd "$JETTY_BASE"
"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
jetty.http.port=58080 \
STOP.PORT=58181 STOP.KEY=it

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
JAVA_HOME=$1
JETTY_HOME=$2
JETTY_BASE=$3
cd "$JETTY_BASE"
"$JAVA_HOME/bin/java" -jar "$JETTY_HOME/start.jar" \
--stop STOP.PORT=58181 STOP.KEY=it