Merge remote-tracking branch 'origin/jetty-9.4.x' into issue-1640
This commit is contained in:
commit
ee4fd24cb1
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<bundle-symbolic-name>${project.groupId}.alpn.java.client</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.alpn.java.client</bundle-symbolic-name>
|
||||||
<conscrypt.version>1.0.0.RC10</conscrypt.version>
|
<conscrypt.version>1.0.0.RC11</conscrypt.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class ConscryptClientALPNProcessor implements ALPNProcessor.Client
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Method setAlpnProtocols = sslEngine.getClass().getDeclaredMethod("setAlpnProtocols", String[].class);
|
Method setAlpnProtocols = sslEngine.getClass().getDeclaredMethod("setApplicationProtocols", String[].class);
|
||||||
setAlpnProtocols.setAccessible(true);
|
setAlpnProtocols.setAccessible(true);
|
||||||
ALPNClientConnection alpn = (ALPNClientConnection)connection;
|
ALPNClientConnection alpn = (ALPNClientConnection)connection;
|
||||||
String[] protocols = alpn.getProtocols().toArray(new String[0]);
|
String[] protocols = alpn.getProtocols().toArray(new String[0]);
|
||||||
|
@ -92,9 +92,9 @@ public class ConscryptClientALPNProcessor implements ALPNProcessor.Client
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SSLEngine sslEngine = alpnConnection.getSSLEngine();
|
SSLEngine sslEngine = alpnConnection.getSSLEngine();
|
||||||
Method method = sslEngine.getClass().getDeclaredMethod("getAlpnSelectedProtocol");
|
Method method = sslEngine.getClass().getDeclaredMethod("getApplicationProtocol");
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
String protocol = new String((byte[])method.invoke(sslEngine), StandardCharsets.US_ASCII);
|
String protocol = (String)method.invoke(sslEngine);
|
||||||
alpnConnection.selected(protocol);
|
alpnConnection.selected(protocol);
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<bundle-symbolic-name>${project.groupId}.alpn.conscrypt.server</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.alpn.conscrypt.server</bundle-symbolic-name>
|
||||||
<conscrypt.version>1.0.0.RC10</conscrypt.version>
|
<conscrypt.version>1.0.0.RC11</conscrypt.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -116,6 +116,26 @@
|
||||||
<artifactId>jetty-alpn-java-server</artifactId>
|
<artifactId>jetty-alpn-java-server</artifactId>
|
||||||
<version>9.4.8-SNAPSHOT</version>
|
<version>9.4.8-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-openjdk8-client</artifactId>
|
||||||
|
<version>9.4.8-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-openjdk8-server</artifactId>
|
||||||
|
<version>9.4.8-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-conscrypt-client</artifactId>
|
||||||
|
<version>9.4.8-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-alpn-conscrypt-server</artifactId>
|
||||||
|
<version>9.4.8-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-alpn-server</artifactId>
|
<artifactId>jetty-alpn-server</artifactId>
|
||||||
|
|
|
@ -729,7 +729,7 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
*/
|
*/
|
||||||
public void setUserAgentField(HttpField agent)
|
public void setUserAgentField(HttpField agent)
|
||||||
{
|
{
|
||||||
if (agent.getHeader() != HttpHeader.USER_AGENT)
|
if (agent != null && agent.getHeader() != HttpHeader.USER_AGENT)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
this.agentField = agent;
|
this.agentField = agent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ The modules and XML files involved can be seen with the following commands:
|
||||||
....
|
....
|
||||||
$ java -jar $JETTY_HOME/start.jar --list-modules
|
$ java -jar $JETTY_HOME/start.jar --list-modules
|
||||||
...
|
...
|
||||||
1) protonego-boot <transitive>
|
1) alpn-impl <transitive>
|
||||||
...
|
...
|
||||||
2) http ${jetty.base}/start.d/http.ini
|
2) http ${jetty.base}/start.d/http.ini
|
||||||
2) ssl ${jetty.base}/start.d/ssl.ini
|
2) ssl ${jetty.base}/start.d/ssl.ini
|
||||||
|
@ -64,6 +64,7 @@ Currently there are very few HTTP/2 configuration properties and the default val
|
||||||
[cols=",",options="header",]
|
[cols=",",options="header",]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|Property |Description
|
|Property |Description
|
||||||
|jetty.http2.maxConcurrentStreams |The maximum number of concurrently open streams allowed on a single HTTP/2 connection (default 1024). Larger values increase parallelism but cost a memory commitment.
|
|jetty.http2.maxConcurrentStreams |The maximum number of concurrently open streams allowed on a single HTTP/2 connection (default 128). Larger values increase parallelism but cost a memory commitment.
|
||||||
|jetty.http2.initialStreamRecvWindow |The initial receive flow control window size for a new stream (default 65535). Larger values may allow greater throughput but also risk head of line blocking if TCP/IP flow control is triggered.
|
|jetty.http2.initialSessionRecvWindow |The initial receive flow control window size for a new session (default 1048576). Larger values may allow greater throughput but also risk head of line blocking if TCP/IP flow control is triggered.
|
||||||
|
|jetty.http2.initialStreamRecvWindow |The initial receive flow control window size for a new stream (default 524288). Larger values may allow greater throughput but also risk head of line blocking if TCP/IP flow control is triggered.
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
|
@ -136,7 +136,7 @@ Here's an example of an xml file that defines an in-memory type of LoginService
|
||||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||||
<Set name="name">Test Realm</Set>
|
<Set name="name">Test Realm</Set>
|
||||||
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
||||||
<Set name="refreshInterval">0</Set>
|
<Set name="hotReload">true</Set>
|
||||||
</New>
|
</New>
|
||||||
</Arg>
|
</Arg>
|
||||||
</Call>
|
</Call>
|
||||||
|
@ -264,8 +264,7 @@ You configure the `HashLoginService` with a name and a reference to the location
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
You can also configure it to check the properties file regularly for changes and reload when changes are detected.
|
You can also configure it to reload the configuration file when changes to it are detected.
|
||||||
The `reloadInterval` is in seconds:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
||||||
|
@ -273,7 +272,7 @@ The `reloadInterval` is in seconds:
|
||||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||||
<Set name="name">Test Realm</Set>
|
<Set name="name">Test Realm</Set>
|
||||||
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
||||||
<Set name="reloadInterval">5</Set>
|
<Set name="hotReload">true</Set>
|
||||||
<Call name="start"></Call>
|
<Call name="start"></Call>
|
||||||
</New>
|
</New>
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ include::{SRCDIR}/examples/embedded/src/main/java/org/eclipse/jetty/embedded/One
|
||||||
|
|
||||||
The typical way to configure an instance of the Jetty server is via `jetty.xml` and associated configuration files.
|
The typical way to configure an instance of the Jetty server is via `jetty.xml` and associated configuration files.
|
||||||
However the Jetty XML configuration format is just a simple rendering of what you can do in code; it is very simple to write embedded code that does precisely what the jetty.xml configuration does.
|
However the Jetty XML configuration format is just a simple rendering of what you can do in code; it is very simple to write embedded code that does precisely what the jetty.xml configuration does.
|
||||||
The link:{JDURL}/org/eclipse/jetty/embedded/LikeJettyXml.html[LikeJettyXml example] following renders in code the behavior obtained from the configuration files:
|
The link:{GITBROWSEURL}/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java[LikeJettyXml example] following renders in code the behavior obtained from the configuration files:
|
||||||
|
|
||||||
* link:{GITBROWSEURL}/jetty-server/src/main/config/etc/jetty.xml[jetty.xml]
|
* link:{GITBROWSEURL}/jetty-server/src/main/config/etc/jetty.xml[jetty.xml]
|
||||||
* link:{GITBROWSEURL}/jetty-jmx/src/main/config/etc/jetty-jmx.xml[jetty-jmx.xml]
|
* link:{GITBROWSEURL}/jetty-jmx/src/main/config/etc/jetty-jmx.xml[jetty-jmx.xml]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.eclipse.jetty.gcloud</groupId>
|
<groupId>org.eclipse.jetty.gcloud</groupId>
|
||||||
<artifactId>gcloud-parent</artifactId>
|
<artifactId>gcloud-parent</artifactId>
|
||||||
|
@ -22,12 +24,12 @@
|
||||||
<version>${gcloud.version}</version>
|
<version>${gcloud.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
|
|
||||||
|
@ -57,50 +59,51 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<bundle-symbolic-name>${project.groupId}.session</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.session</bundle-symbolic-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>manifest</goal>
|
<goal>manifest</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<instructions>
|
<instructions>
|
||||||
<Export-Package>org.eclipse.jetty.gcloud.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}";</Export-Package>
|
<Export-Package>
|
||||||
</instructions>
|
org.eclipse.jetty.gcloud.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}";
|
||||||
</configuration>
|
</Export-Package>
|
||||||
</execution>
|
</instructions>
|
||||||
</executions>
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<executions>
|
||||||
<executions>
|
<execution>
|
||||||
<execution>
|
<id>build-deps-file</id>
|
||||||
<id>build-deps-file</id>
|
<phase>generate-resources</phase>
|
||||||
<phase>generate-resources</phase>
|
<goals>
|
||||||
<goals>
|
<goal>list</goal>
|
||||||
<goal>list</goal>
|
</goals>
|
||||||
</goals>
|
<configuration>
|
||||||
<configuration>
|
<appendOutput>false</appendOutput>
|
||||||
<appendOutput>false</appendOutput>
|
<outputFile>${project.build.directory}/deps.txt</outputFile>
|
||||||
<outputFile>${project.build.directory}/deps.txt</outputFile>
|
<sort>true</sort>
|
||||||
<sort>true</sort>
|
<excludeGroupIds>org.eclipse.jetty</excludeGroupIds>
|
||||||
<excludeGroupIds>org.eclipse.jetty</excludeGroupIds>
|
<prependGroupId>true</prependGroupId>
|
||||||
<prependGroupId>true</prependGroupId>
|
<includeScope>runtime</includeScope>
|
||||||
<includeScope>runtime</includeScope>
|
</configuration>
|
||||||
</configuration>
|
</execution>
|
||||||
</execution>
|
</executions>
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -118,15 +121,15 @@
|
||||||
match=" *(.*):(.*):jar:(.*):[a-z]*"
|
match=" *(.*):(.*):jar:(.*):[a-z]*"
|
||||||
replace="maven://\1/\2/\3|lib/gcloud/\2-\3.jar"
|
replace="maven://\1/\2/\3|lib/gcloud/\2-\3.jar"
|
||||||
byline="true"
|
byline="true"
|
||||||
/>
|
/>
|
||||||
<replaceregexp file="${project.build.directory}/deps.txt"
|
<replaceregexp file="${project.build.directory}/deps.txt"
|
||||||
match="The following files have been resolved:"
|
match="The following files have been resolved:"
|
||||||
replace="[files]"
|
replace="[files]"
|
||||||
/>
|
/>
|
||||||
</tasks>
|
</tasks>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>process-mod</id>
|
<id>process-mod</id>
|
||||||
<phase>process-resources</phase>
|
<phase>process-resources</phase>
|
||||||
<goals>
|
<goals>
|
||||||
|
@ -141,8 +144,7 @@
|
||||||
</tasks>
|
</tasks>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
</executions>
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -161,7 +163,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -288,7 +288,9 @@ public class HTTP2CServerTest extends AbstractServerTest
|
||||||
{
|
{
|
||||||
AtomicLong fills = new AtomicLong();
|
AtomicLong fills = new AtomicLong();
|
||||||
// Remove "h2c", leaving only "http/1.1".
|
// Remove "h2c", leaving only "http/1.1".
|
||||||
connector.clearConnectionFactories();
|
connector.stop();
|
||||||
|
connector.removeConnectionFactory("h2c");
|
||||||
|
connector.start();
|
||||||
HttpConnectionFactory connectionFactory = new HttpConnectionFactory()
|
HttpConnectionFactory connectionFactory = new HttpConnectionFactory()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -306,8 +308,10 @@ public class HTTP2CServerTest extends AbstractServerTest
|
||||||
return configure(connection, connector, endPoint);
|
return configure(connection, connector, endPoint);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
connector.stop();
|
||||||
connector.addConnectionFactory(connectionFactory);
|
connector.addConnectionFactory(connectionFactory);
|
||||||
connector.setDefaultProtocol(connectionFactory.getProtocol());
|
connector.setDefaultProtocol(connectionFactory.getProtocol());
|
||||||
|
connector.start();
|
||||||
|
|
||||||
// Now send a HTTP/2 direct request, which
|
// Now send a HTTP/2 direct request, which
|
||||||
// will have the PRI * HTTP/2.0 preface.
|
// will have the PRI * HTTP/2.0 preface.
|
||||||
|
|
|
@ -61,11 +61,11 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
|
||||||
private long _selectorIndex;
|
private long _selectorIndex;
|
||||||
private int _reservedThreads = -1;
|
private int _reservedThreads = -1;
|
||||||
|
|
||||||
public static int defaultSchedulers(Executor executor)
|
private static int defaultSelectors(Executor executor)
|
||||||
{
|
{
|
||||||
if (executor instanceof ThreadPool)
|
if (executor instanceof ThreadPool.SizedThreadPool)
|
||||||
{
|
{
|
||||||
int threads = ((ThreadPool)executor).getThreads();
|
int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads();
|
||||||
int cpus = Runtime.getRuntime().availableProcessors();
|
int cpus = Runtime.getRuntime().availableProcessors();
|
||||||
return Math.max(1,Math.min(cpus/2,threads/16));
|
return Math.max(1,Math.min(cpus/2,threads/16));
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
|
||||||
protected SelectorManager(Executor executor, Scheduler scheduler, int selectors)
|
protected SelectorManager(Executor executor, Scheduler scheduler, int selectors)
|
||||||
{
|
{
|
||||||
if (selectors <= 0)
|
if (selectors <= 0)
|
||||||
selectors = defaultSchedulers(executor);
|
selectors = defaultSelectors(executor);
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
_selectors = new ManagedSelector[selectors];
|
_selectors = new ManagedSelector[selectors];
|
||||||
|
|
|
@ -289,7 +289,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
|
|
||||||
protected void interruptAcceptors()
|
protected void interruptAcceptors()
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lockIfNotHeld())
|
try (Locker.Lock lock = _locker.lock())
|
||||||
{
|
{
|
||||||
for (Thread thread : _acceptors)
|
for (Thread thread : _acceptors)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +363,6 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
_setAccepting.signalAll();
|
_setAccepting.signalAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConnectionFactory getConnectionFactory(String protocol)
|
public ConnectionFactory getConnectionFactory(String protocol)
|
||||||
|
@ -388,108 +387,105 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
|
|
||||||
public void addConnectionFactory(ConnectionFactory factory)
|
public void addConnectionFactory(ConnectionFactory factory)
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lockIfNotHeld())
|
if (isRunning())
|
||||||
|
throw new IllegalStateException(getState());
|
||||||
|
|
||||||
|
Set<ConnectionFactory> to_remove = new HashSet<>();
|
||||||
|
for (String key:factory.getProtocols())
|
||||||
{
|
{
|
||||||
Set<ConnectionFactory> to_remove = new HashSet<>();
|
key=StringUtil.asciiToLowerCase(key);
|
||||||
for (String key:factory.getProtocols())
|
ConnectionFactory old=_factories.remove(key);
|
||||||
|
if (old!=null)
|
||||||
{
|
{
|
||||||
key=StringUtil.asciiToLowerCase(key);
|
if (old.getProtocol().equals(_defaultProtocol))
|
||||||
ConnectionFactory old=_factories.remove(key);
|
_defaultProtocol=null;
|
||||||
if (old!=null)
|
to_remove.add(old);
|
||||||
{
|
|
||||||
if (old.getProtocol().equals(_defaultProtocol))
|
|
||||||
_defaultProtocol=null;
|
|
||||||
to_remove.add(old);
|
|
||||||
}
|
|
||||||
_factories.put(key, factory);
|
|
||||||
}
|
}
|
||||||
|
_factories.put(key, factory);
|
||||||
// keep factories still referenced
|
|
||||||
for (ConnectionFactory f : _factories.values())
|
|
||||||
to_remove.remove(f);
|
|
||||||
|
|
||||||
// remove old factories
|
|
||||||
for (ConnectionFactory old: to_remove)
|
|
||||||
{
|
|
||||||
removeBean(old);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("{} removed {}", this, old);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add new Bean
|
|
||||||
addBean(factory);
|
|
||||||
if (_defaultProtocol==null)
|
|
||||||
_defaultProtocol=factory.getProtocol();
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("{} added {}", this, factory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep factories still referenced
|
||||||
|
for (ConnectionFactory f : _factories.values())
|
||||||
|
to_remove.remove(f);
|
||||||
|
|
||||||
|
// remove old factories
|
||||||
|
for (ConnectionFactory old: to_remove)
|
||||||
|
{
|
||||||
|
removeBean(old);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} removed {}", this, old);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new Bean
|
||||||
|
addBean(factory);
|
||||||
|
if (_defaultProtocol==null)
|
||||||
|
_defaultProtocol=factory.getProtocol();
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} added {}", this, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFirstConnectionFactory(ConnectionFactory factory)
|
public void addFirstConnectionFactory(ConnectionFactory factory)
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lock())
|
if (isRunning())
|
||||||
{
|
throw new IllegalStateException(getState());
|
||||||
List<ConnectionFactory> existings = new ArrayList<>(_factories.values());
|
|
||||||
_factories.clear();
|
List<ConnectionFactory> existings = new ArrayList<>(_factories.values());
|
||||||
addConnectionFactory(factory);
|
_factories.clear();
|
||||||
for (ConnectionFactory existing : existings)
|
addConnectionFactory(factory);
|
||||||
addConnectionFactory(existing);
|
for (ConnectionFactory existing : existings)
|
||||||
_defaultProtocol = factory.getProtocol();
|
addConnectionFactory(existing);
|
||||||
}
|
_defaultProtocol = factory.getProtocol();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addIfAbsentConnectionFactory(ConnectionFactory factory)
|
public void addIfAbsentConnectionFactory(ConnectionFactory factory)
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lock())
|
if (isRunning())
|
||||||
|
throw new IllegalStateException(getState());
|
||||||
|
|
||||||
|
String key=StringUtil.asciiToLowerCase(factory.getProtocol());
|
||||||
|
if (_factories.containsKey(key))
|
||||||
{
|
{
|
||||||
String key=StringUtil.asciiToLowerCase(factory.getProtocol());
|
if (LOG.isDebugEnabled())
|
||||||
if (_factories.containsKey(key))
|
LOG.debug("{} addIfAbsent ignored {}", this, factory);
|
||||||
{
|
}
|
||||||
if (LOG.isDebugEnabled())
|
else
|
||||||
LOG.debug("{} addIfAbsent ignored {}", this, factory);
|
{
|
||||||
}
|
_factories.put(key, factory);
|
||||||
else
|
addBean(factory);
|
||||||
{
|
if (_defaultProtocol==null)
|
||||||
_factories.put(key, factory);
|
_defaultProtocol=factory.getProtocol();
|
||||||
addBean(factory);
|
if (LOG.isDebugEnabled())
|
||||||
if (_defaultProtocol==null)
|
LOG.debug("{} addIfAbsent added {}", this, factory);
|
||||||
_defaultProtocol=factory.getProtocol();
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("{} addIfAbsent added {}", this, factory);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnectionFactory removeConnectionFactory(String protocol)
|
public ConnectionFactory removeConnectionFactory(String protocol)
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lock())
|
if (isRunning())
|
||||||
{
|
throw new IllegalStateException(getState());
|
||||||
ConnectionFactory factory= _factories.remove(StringUtil.asciiToLowerCase(protocol));
|
|
||||||
removeBean(factory);
|
ConnectionFactory factory= _factories.remove(StringUtil.asciiToLowerCase(protocol));
|
||||||
return factory;
|
removeBean(factory);
|
||||||
}
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ConnectionFactory> getConnectionFactories()
|
public Collection<ConnectionFactory> getConnectionFactories()
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lock())
|
return _factories.values();
|
||||||
{
|
|
||||||
return _factories.values();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConnectionFactories(Collection<ConnectionFactory> factories)
|
public void setConnectionFactories(Collection<ConnectionFactory> factories)
|
||||||
{
|
{
|
||||||
try (Locker.Lock lock = _locker.lock())
|
if (isRunning())
|
||||||
{
|
throw new IllegalStateException(getState());
|
||||||
List<ConnectionFactory> existing = new ArrayList<>(_factories.values());
|
|
||||||
for (ConnectionFactory factory: existing)
|
List<ConnectionFactory> existing = new ArrayList<>(_factories.values());
|
||||||
removeConnectionFactory(factory.getProtocol());
|
for (ConnectionFactory factory: existing)
|
||||||
for (ConnectionFactory factory: factories)
|
removeConnectionFactory(factory.getProtocol());
|
||||||
if (factory!=null)
|
for (ConnectionFactory factory: factories)
|
||||||
addConnectionFactory(factory);
|
if (factory!=null)
|
||||||
}
|
addConnectionFactory(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedAttribute("The priority delta to apply to acceptor threads")
|
@ManagedAttribute("The priority delta to apply to acceptor threads")
|
||||||
|
@ -521,18 +517,15 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
@ManagedAttribute("Protocols supported by this connector")
|
@ManagedAttribute("Protocols supported by this connector")
|
||||||
public List<String> getProtocols()
|
public List<String> getProtocols()
|
||||||
{
|
{
|
||||||
synchronized (_factories)
|
return new ArrayList<>(_factories.keySet());
|
||||||
{
|
|
||||||
return new ArrayList<>(_factories.keySet());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearConnectionFactories()
|
public void clearConnectionFactories()
|
||||||
{
|
{
|
||||||
synchronized (_factories)
|
if (isRunning())
|
||||||
{
|
throw new IllegalStateException(getState());
|
||||||
_factories.clear();
|
|
||||||
}
|
_factories.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ManagedAttribute("This connector's default protocol")
|
@ManagedAttribute("This connector's default protocol")
|
||||||
|
@ -616,10 +609,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
if (_acceptorPriorityDelta!=0)
|
if (_acceptorPriorityDelta!=0)
|
||||||
thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta)));
|
thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta)));
|
||||||
|
|
||||||
synchronized (AbstractConnector.this)
|
_acceptors[_id] = thread;
|
||||||
{
|
|
||||||
_acceptors[_id] = thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -676,26 +666,6 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// protected void connectionOpened(Connection connection)
|
|
||||||
// {
|
|
||||||
// _stats.connectionOpened();
|
|
||||||
// connection.onOpen();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// protected void connectionClosed(Connection connection)
|
|
||||||
// {
|
|
||||||
// connection.onClose();
|
|
||||||
// long duration = System.currentTimeMillis() - connection.getEndPoint().getCreatedTimeStamp();
|
|
||||||
// _stats.connectionClosed(duration, connection.getMessagesIn(), connection.getMessagesOut());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void connectionUpgraded(Connection oldConnection, Connection newConnection)
|
|
||||||
// {
|
|
||||||
// oldConnection.onClose();
|
|
||||||
// _stats.connectionUpgraded(oldConnection.getMessagesIn(), oldConnection.getMessagesOut());
|
|
||||||
// newConnection.onOpen();
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<EndPoint> getConnectedEndPoints()
|
public Collection<EndPoint> getConnectedEndPoints()
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,7 +137,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
// True if:
|
// True if:
|
||||||
// 1. the session is still valid
|
// 1. the session is still valid
|
||||||
// BUT if passivated out to disk, do we really want this timer to keep going off?
|
// BUT if passivated out to disk, do we really want this timer to keep going off?
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return isValid() && isResident();
|
return isValid() && isResident();
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
public long getRequests()
|
public long getRequests()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _requests;
|
return _requests;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
protected void cookieSet()
|
protected void cookieSet()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
_sessionData.setCookieSet(_sessionData.getAccessed());
|
_sessionData.setCookieSet(_sessionData.getAccessed());
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected boolean access(long time)
|
protected boolean access(long time)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
return false;
|
return false;
|
||||||
|
@ -249,7 +249,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected void complete()
|
protected void complete()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
_requests--;
|
_requests--;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
protected boolean isExpiredAt(long time)
|
protected boolean isExpiredAt(long time)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _sessionData.isExpiredAt(time);
|
return _sessionData.isExpiredAt(time);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
protected boolean isIdleLongerThan (int sec)
|
protected boolean isIdleLongerThan (int sec)
|
||||||
{
|
{
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return ((_sessionData.getAccessed() + (sec*1000)) <= now);
|
return ((_sessionData.getAccessed() + (sec*1000)) <= now);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public boolean isValid()
|
public boolean isValid()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _state==State.VALID;
|
return _state==State.VALID;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
public long getCookieSetTime()
|
public long getCookieSetTime()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _sessionData.getCookieSet();
|
return _sessionData.getCookieSet();
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public long getCreationTime() throws IllegalStateException
|
public long getCreationTime() throws IllegalStateException
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForRead();
|
checkValidForRead();
|
||||||
return _sessionData.getCreated();
|
return _sessionData.getCreated();
|
||||||
|
@ -420,7 +420,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public String getId()
|
public String getId()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _sessionData.getId();
|
return _sessionData.getId();
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public long getLastAccessedTime()
|
public long getLastAccessedTime()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _sessionData.getLastAccessed();
|
return _sessionData.getLastAccessed();
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public void setMaxInactiveInterval(int secs)
|
public void setMaxInactiveInterval(int secs)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
_sessionData.setMaxInactiveMs((long)secs*1000L);
|
_sessionData.setMaxInactiveMs((long)secs*1000L);
|
||||||
_sessionData.calcAndSetExpiry();
|
_sessionData.calcAndSetExpiry();
|
||||||
|
@ -496,7 +496,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
public void updateInactivityTimer ()
|
public void updateInactivityTimer ()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())LOG.debug("updateInactivityTimer");
|
if (LOG.isDebugEnabled())LOG.debug("updateInactivityTimer");
|
||||||
|
|
||||||
|
@ -556,7 +556,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
public void stopInactivityTimer ()
|
public void stopInactivityTimer ()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
if (_sessionInactivityTimer != null)
|
if (_sessionInactivityTimer != null)
|
||||||
{
|
{
|
||||||
|
@ -573,7 +573,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public int getMaxInactiveInterval()
|
public int getMaxInactiveInterval()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return (int)(_sessionData.getMaxInactiveMs()/1000);
|
return (int)(_sessionData.getMaxInactiveMs()/1000);
|
||||||
}
|
}
|
||||||
|
@ -653,7 +653,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public Object getAttribute(String name)
|
public Object getAttribute(String name)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForRead();
|
checkValidForRead();
|
||||||
return _sessionData.getAttribute(name);
|
return _sessionData.getAttribute(name);
|
||||||
|
@ -667,7 +667,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Object getValue(String name)
|
public Object getValue(String name)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _sessionData.getAttribute(name);
|
return _sessionData.getAttribute(name);
|
||||||
}
|
}
|
||||||
|
@ -679,7 +679,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public Enumeration<String> getAttributeNames()
|
public Enumeration<String> getAttributeNames()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForRead();
|
checkValidForRead();
|
||||||
final Iterator<String> itor = _sessionData.getKeys().iterator();
|
final Iterator<String> itor = _sessionData.getKeys().iterator();
|
||||||
|
@ -730,7 +730,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public String[] getValueNames() throws IllegalStateException
|
public String[] getValueNames() throws IllegalStateException
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForRead();
|
checkValidForRead();
|
||||||
Iterator<String> itor = _sessionData.getKeys().iterator();
|
Iterator<String> itor = _sessionData.getKeys().iterator();
|
||||||
|
@ -751,7 +751,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
public void setAttribute(String name, Object value)
|
public void setAttribute(String name, Object value)
|
||||||
{
|
{
|
||||||
Object old=null;
|
Object old=null;
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
//if session is not valid, don't accept the set
|
//if session is not valid, don't accept the set
|
||||||
checkValidForWrite();
|
checkValidForWrite();
|
||||||
|
@ -812,7 +812,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
|
|
||||||
String id = null;
|
String id = null;
|
||||||
String extendedId = null;
|
String extendedId = null;
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForWrite(); //don't renew id on a session that is not valid
|
checkValidForWrite(); //don't renew id on a session that is not valid
|
||||||
id = _sessionData.getId(); //grab the values as they are now
|
id = _sessionData.getId(); //grab the values as they are now
|
||||||
|
@ -820,7 +820,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
}
|
}
|
||||||
|
|
||||||
String newId = _handler._sessionIdManager.renewSessionId(id, extendedId, request);
|
String newId = _handler._sessionIdManager.renewSessionId(id, extendedId, request);
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForWrite();
|
checkValidForWrite();
|
||||||
_sessionData.setId(newId);
|
_sessionData.setId(newId);
|
||||||
|
@ -877,7 +877,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
public Lock lockIfNotHeld ()
|
public Lock lockIfNotHeld ()
|
||||||
{
|
{
|
||||||
return _lock.lockIfNotHeld();
|
return _lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
@ -888,7 +888,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
{
|
{
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
switch (_state)
|
switch (_state)
|
||||||
{
|
{
|
||||||
|
@ -934,7 +934,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
*/
|
*/
|
||||||
protected void finishInvalidate() throws IllegalStateException
|
protected void finishInvalidate() throws IllegalStateException
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -970,7 +970,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
@Override
|
@Override
|
||||||
public boolean isNew() throws IllegalStateException
|
public boolean isNew() throws IllegalStateException
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
checkValidForRead();
|
checkValidForRead();
|
||||||
return _newSession;
|
return _newSession;
|
||||||
|
@ -982,7 +982,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
public void setIdChanged(boolean changed)
|
public void setIdChanged(boolean changed)
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
_idChanged=changed;
|
_idChanged=changed;
|
||||||
}
|
}
|
||||||
|
@ -992,7 +992,7 @@ public class Session implements SessionHandler.SessionIf
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
public boolean isIdChanged ()
|
public boolean isIdChanged ()
|
||||||
{
|
{
|
||||||
try (Lock lock = _lock.lockIfNotHeld())
|
try (Lock lock = _lock.lock())
|
||||||
{
|
{
|
||||||
return _idChanged;
|
return _idChanged;
|
||||||
}
|
}
|
||||||
|
|
|
@ -357,7 +357,7 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
|
||||||
StacklessLogging stackless = new StacklessLogging(HttpConnection.class))
|
StacklessLogging stackless = new StacklessLogging(HttpConnection.class))
|
||||||
{
|
{
|
||||||
Log.getLogger(HttpConnection.class).info("expect header is too large, then ISE extra data ...");
|
Log.getLogger(HttpConnection.class).info("expect header is too large ...");
|
||||||
OutputStream os = client.getOutputStream();
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
byte[] buffer = new byte[64 * 1024];
|
byte[] buffer = new byte[64 * 1024];
|
||||||
|
@ -379,9 +379,16 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
buffer[15]='H';
|
buffer[15]='H';
|
||||||
buffer[16]=':';
|
buffer[16]=':';
|
||||||
Arrays.fill(buffer,17,buffer.length-1,(byte)'A');
|
Arrays.fill(buffer,17,buffer.length-1,(byte)'A');
|
||||||
|
// write the request.
|
||||||
os.write(buffer);
|
try
|
||||||
os.flush();
|
{
|
||||||
|
os.write(buffer);
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
// Ignore exceptions during writing, so long as we can read response below
|
||||||
|
}
|
||||||
|
|
||||||
// Read the response.
|
// Read the response.
|
||||||
try
|
try
|
||||||
|
@ -391,7 +398,8 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
// TODO evaluate why we sometimes get an early close on this test
|
Log.getLogger(HttpServerTestBase.class).warn("TODO Early close???");
|
||||||
|
// TODO #1832 evaluate why we sometimes get an early close on this test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
@ -118,14 +119,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
||||||
@Override
|
@Override
|
||||||
public void testFullHeader() throws Exception
|
public void testFullHeader() throws Exception
|
||||||
{
|
{
|
||||||
try
|
super.testFullHeader();
|
||||||
{
|
|
||||||
super.testFullHeader();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
Log.getLogger(SslConnection.class).warn("Close overtook 400 response");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -167,7 +161,6 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,11 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
private ServletRegistration.Dynamic _registration;
|
private ServletRegistration.Dynamic _registration;
|
||||||
private JspContainer _jspContainer;
|
private JspContainer _jspContainer;
|
||||||
|
|
||||||
private transient Servlet _servlet;
|
private Servlet _servlet;
|
||||||
private transient Config _config;
|
private long _unavailable;
|
||||||
private transient long _unavailable;
|
private Config _config;
|
||||||
private transient boolean _enabled = true;
|
private boolean _enabled = true;
|
||||||
private transient UnavailableException _unavailableEx;
|
private UnavailableException _unavailableEx;
|
||||||
|
|
||||||
|
|
||||||
public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
|
public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
|
||||||
|
@ -400,9 +400,11 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
|
|
||||||
_config=new Config();
|
_config=new Config();
|
||||||
|
|
||||||
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
|
synchronized (this)
|
||||||
_servlet = new SingleThreadedWrapper();
|
{
|
||||||
|
if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
|
||||||
|
_servlet = new SingleThreadedWrapper();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,18 +487,38 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
public synchronized Servlet getServlet()
|
public synchronized Servlet getServlet()
|
||||||
throws ServletException
|
throws ServletException
|
||||||
{
|
{
|
||||||
// Handle previous unavailability
|
Servlet servlet=_servlet;
|
||||||
if (_unavailable!=0)
|
if (servlet!=null && _unavailable==0)
|
||||||
{
|
return servlet;
|
||||||
if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
|
|
||||||
throw _unavailableEx;
|
|
||||||
_unavailable=0;
|
|
||||||
_unavailableEx=null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_servlet==null)
|
synchronized(this)
|
||||||
initServlet();
|
{
|
||||||
return _servlet;
|
// Handle previous unavailability
|
||||||
|
if (_unavailable!=0)
|
||||||
|
{
|
||||||
|
if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
|
||||||
|
throw _unavailableEx;
|
||||||
|
_unavailable=0;
|
||||||
|
_unavailableEx=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
servlet=_servlet;
|
||||||
|
if (servlet!=null)
|
||||||
|
return servlet;
|
||||||
|
|
||||||
|
if (isRunning())
|
||||||
|
{
|
||||||
|
if (_class == null)
|
||||||
|
throw new UnavailableException("Servlet Not Initialized");
|
||||||
|
if (_unavailable != 0 || !_initOnStartup)
|
||||||
|
initServlet();
|
||||||
|
servlet=_servlet;
|
||||||
|
if (servlet == null)
|
||||||
|
throw new UnavailableException("Could not instantiate " + _class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return servlet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -505,7 +527,13 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
*/
|
*/
|
||||||
public Servlet getServletInstance()
|
public Servlet getServletInstance()
|
||||||
{
|
{
|
||||||
return _servlet;
|
Servlet servlet=_servlet;
|
||||||
|
if (servlet!=null)
|
||||||
|
return servlet;
|
||||||
|
synchronized(this)
|
||||||
|
{
|
||||||
|
return _servlet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -528,7 +556,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
*/
|
*/
|
||||||
public boolean isAvailable()
|
public boolean isAvailable()
|
||||||
{
|
{
|
||||||
if (isStarted()&& _unavailable==0)
|
if (isStarted() && _unavailable==0)
|
||||||
return true;
|
return true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -539,7 +567,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
LOG.ignore(e);
|
LOG.ignore(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isStarted()&& _unavailable==0;
|
return isStarted() && _unavailable==0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -604,7 +632,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private void initServlet()
|
private synchronized void initServlet()
|
||||||
throws ServletException
|
throws ServletException
|
||||||
{
|
{
|
||||||
Object old_run_as = null;
|
Object old_run_as = null;
|
||||||
|
@ -767,26 +795,17 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
|
protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
|
||||||
throws ServletException, UnavailableException
|
throws ServletException, UnavailableException
|
||||||
{
|
{
|
||||||
ensureInstance();
|
getServlet();
|
||||||
MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
|
MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
|
||||||
if (mpce != null)
|
if (mpce != null)
|
||||||
baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
|
baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Servlet ensureInstance()
|
@Deprecated
|
||||||
throws ServletException, UnavailableException
|
public Servlet ensureInstance()
|
||||||
|
throws ServletException, UnavailableException
|
||||||
{
|
{
|
||||||
if (_class==null)
|
return getServlet();
|
||||||
throw new UnavailableException("Servlet Not Initialized");
|
|
||||||
Servlet servlet=_servlet;
|
|
||||||
if (!isStarted())
|
|
||||||
throw new UnavailableException("Servlet not initialized", -1);
|
|
||||||
if (_unavailable!=0 || (!_initOnStartup && servlet==null))
|
|
||||||
servlet=getServlet();
|
|
||||||
if (servlet==null)
|
|
||||||
throw new UnavailableException("Could not instantiate "+_class);
|
|
||||||
|
|
||||||
return servlet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -810,7 +829,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
if (_class==null)
|
if (_class==null)
|
||||||
throw new UnavailableException("Servlet Not Initialized");
|
throw new UnavailableException("Servlet Not Initialized");
|
||||||
|
|
||||||
Servlet servlet = ensureInstance();
|
Servlet servlet = getServlet();
|
||||||
|
|
||||||
// Service the request
|
// Service the request
|
||||||
Object old_run_as = null;
|
Object old_run_as = null;
|
||||||
|
@ -855,26 +874,23 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private boolean isJspServlet ()
|
protected boolean isJspServlet ()
|
||||||
{
|
{
|
||||||
if (_servlet == null)
|
Servlet servlet = getServletInstance();
|
||||||
return false;
|
Class<?> c = servlet==null?_class:servlet.getClass();
|
||||||
|
|
||||||
Class<?> c = _servlet.getClass();
|
while (c != null)
|
||||||
|
|
||||||
boolean result = false;
|
|
||||||
while (c != null && !result)
|
|
||||||
{
|
{
|
||||||
result = isJspServlet(c.getName());
|
if (isJspServlet(c.getName()))
|
||||||
|
return true;
|
||||||
c = c.getSuperclass();
|
c = c.getSuperclass();
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private boolean isJspServlet (String classname)
|
protected boolean isJspServlet (String classname)
|
||||||
{
|
{
|
||||||
if (classname == null)
|
if (classname == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -447,8 +447,8 @@ public abstract class Resource implements ResourceFactory, Closeable
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* list of resource names contained in the given resource.
|
* list of resource names contained in the given resource.
|
||||||
*
|
* Ordering is unspecified, so callers may wish to sort the return value to ensure deterministic behavior.
|
||||||
* @return a list of resource names contained in the given resource.
|
* @return a list of resource names contained in the given resource, or null.
|
||||||
* Note: The resource names are not URL encoded.
|
* Note: The resource names are not URL encoded.
|
||||||
*/
|
*/
|
||||||
public abstract String[] list();
|
public abstract String[] list();
|
||||||
|
|
|
@ -22,10 +22,10 @@ import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience Lock Wrapper.
|
* <p>Convenience auto closeable {@link java.util.concurrent.locks.ReentrantLock} wrapper.</p>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* try(Locker.Lock lock = locker.lock())
|
* try (Locker.Lock lock = locker.lock())
|
||||||
* {
|
* {
|
||||||
* // something
|
* // something
|
||||||
* }
|
* }
|
||||||
|
@ -33,44 +33,49 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
*/
|
*/
|
||||||
public class Locker
|
public class Locker
|
||||||
{
|
{
|
||||||
private static final Lock LOCKED = new Lock();
|
|
||||||
private final ReentrantLock _lock = new ReentrantLock();
|
private final ReentrantLock _lock = new ReentrantLock();
|
||||||
private final Lock _unlock = new UnLock();
|
private final Lock _unlock = new Lock();
|
||||||
|
|
||||||
public Locker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Acquires the lock.</p>
|
||||||
|
*
|
||||||
|
* @return the lock to unlock
|
||||||
|
*/
|
||||||
public Lock lock()
|
public Lock lock()
|
||||||
{
|
{
|
||||||
if (_lock.isHeldByCurrentThread())
|
|
||||||
throw new IllegalStateException("Locker is not reentrant");
|
|
||||||
_lock.lock();
|
|
||||||
return _unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Lock lockIfNotHeld ()
|
|
||||||
{
|
|
||||||
if (_lock.isHeldByCurrentThread())
|
|
||||||
return LOCKED;
|
|
||||||
_lock.lock();
|
_lock.lock();
|
||||||
return _unlock;
|
return _unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link #lock()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public Lock lockIfNotHeld()
|
||||||
|
{
|
||||||
|
return lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether this lock has been acquired
|
||||||
|
*/
|
||||||
public boolean isLocked()
|
public boolean isLocked()
|
||||||
{
|
{
|
||||||
return _lock.isLocked();
|
return _lock.isLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Lock implements AutoCloseable
|
/**
|
||||||
|
* @return a {@link Condition} associated with this lock
|
||||||
|
*/
|
||||||
|
public Condition newCondition()
|
||||||
{
|
{
|
||||||
@Override
|
return _lock.newCondition();
|
||||||
public void close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UnLock extends Lock
|
/**
|
||||||
|
* <p>The unlocker object that unlocks when it is closed.</p>
|
||||||
|
*/
|
||||||
|
public class Lock implements AutoCloseable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
|
@ -78,9 +83,9 @@ public class Locker
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Condition newCondition()
|
@Deprecated
|
||||||
|
public class UnLock extends Lock
|
||||||
{
|
{
|
||||||
return _lock.newCondition();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.security.CodeSource;
|
||||||
import java.security.PermissionCollection;
|
import java.security.PermissionCollection;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -327,6 +328,10 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
if (lib.exists() && lib.isDirectory())
|
if (lib.exists() && lib.isDirectory())
|
||||||
{
|
{
|
||||||
String[] files=lib.list();
|
String[] files=lib.list();
|
||||||
|
if (files != null)
|
||||||
|
{
|
||||||
|
Arrays.sort(files);
|
||||||
|
}
|
||||||
for (int f=0;files!=null && f<files.length;f++)
|
for (int f=0;files!=null && f<files.length;f++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -702,7 +703,7 @@ public class WebInfConfiguration extends AbstractConfiguration
|
||||||
* Look for jars in <code>WEB-INF/lib</code>
|
* Look for jars in <code>WEB-INF/lib</code>
|
||||||
*
|
*
|
||||||
* @param context the context to find the lib jars in
|
* @param context the context to find the lib jars in
|
||||||
* @return the list of jars as {@link Resource}
|
* @return the list of jars as {@link Resource}, or null
|
||||||
* @throws Exception if unable to scan for lib jars
|
* @throws Exception if unable to scan for lib jars
|
||||||
*/
|
*/
|
||||||
protected List<Resource> findWebInfLibJars(WebAppContext context)
|
protected List<Resource> findWebInfLibJars(WebAppContext context)
|
||||||
|
@ -717,6 +718,10 @@ public class WebInfConfiguration extends AbstractConfiguration
|
||||||
if (web_inf_lib.exists() && web_inf_lib.isDirectory())
|
if (web_inf_lib.exists() && web_inf_lib.isDirectory())
|
||||||
{
|
{
|
||||||
String[] files=web_inf_lib.list();
|
String[] files=web_inf_lib.list();
|
||||||
|
if (files != null)
|
||||||
|
{
|
||||||
|
Arrays.sort(files);
|
||||||
|
}
|
||||||
for (int f=0;files!=null && f<files.length;f++)
|
for (int f=0;files!=null && f<files.length;f++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -22,10 +22,13 @@ import static org.eclipse.jetty.toolchain.test.ExtraMatchers.ordered;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assume.assumeThat;
|
import static org.junit.Assume.assumeThat;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.instrument.IllegalClassFormatException;
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -34,9 +37,11 @@ import java.nio.file.Path;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.resource.PathResource;
|
import org.eclipse.jetty.util.resource.PathResource;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -323,4 +328,26 @@ public class WebAppClassLoaderTest
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ordering() throws Exception
|
||||||
|
{
|
||||||
|
// The existence of a URLStreamHandler changes the behavior
|
||||||
|
assumeThat("URLStreamHandler changes behavior, skip test", URLStreamHandlerUtil.getFactory(), nullValue());
|
||||||
|
|
||||||
|
Enumeration<URL> resources = _loader.getResources("org/acme/clashing.txt");
|
||||||
|
assertTrue(resources.hasMoreElements());
|
||||||
|
URL resource = resources.nextElement();
|
||||||
|
try (InputStream data = resource.openStream())
|
||||||
|
{
|
||||||
|
assertEquals("correct contents of " + resource, "alpha", IO.toString(data));
|
||||||
|
}
|
||||||
|
assertTrue(resources.hasMoreElements());
|
||||||
|
resource = resources.nextElement();
|
||||||
|
try (InputStream data = resource.openStream())
|
||||||
|
{
|
||||||
|
assertEquals("correct contents of " + resource, "omega", IO.toString(data));
|
||||||
|
}
|
||||||
|
assertFalse(resources.hasMoreElements());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,11 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.servlet.GenericServlet;
|
import javax.servlet.GenericServlet;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -44,7 +46,9 @@ import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
import org.eclipse.jetty.server.handler.HotSwapHandler;
|
import org.eclipse.jetty.server.handler.HotSwapHandler;
|
||||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.resource.PathResource;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
@ -378,4 +382,18 @@ public class WebAppContextTest
|
||||||
|
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ordering() throws Exception
|
||||||
|
{
|
||||||
|
Path testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
|
||||||
|
Resource webapp = new PathResource(testWebappDir);
|
||||||
|
WebAppContext context = new WebAppContext();
|
||||||
|
context.setBaseResource(webapp);
|
||||||
|
context.setContextPath("/test");
|
||||||
|
new WebInfConfiguration().preConfigure(context);
|
||||||
|
assertEquals(Arrays.asList("acme.jar", "alpha.jar", "omega.jar"),
|
||||||
|
context.getMetaData().getWebInfJars().stream().map(r -> r.getURI().toString().replaceFirst(".+/", "")).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
10
pom.xml
10
pom.xml
|
@ -393,7 +393,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
<version>3.0.1</version>
|
<version>3.0.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -1138,12 +1138,8 @@
|
||||||
</profile>
|
</profile>
|
||||||
<!--
|
<!--
|
||||||
Usage:
|
Usage:
|
||||||
configure settings.xml for jetty.eclipse.website server entry
|
Javadoc aggregation for Jetty website
|
||||||
> mvn -Paggregate-site javadoc:aggregate
|
> mvn -Paggregate-site clean install javadoc:aggregate -Dtest=foo
|
||||||
then
|
|
||||||
> mvn -N site:deploy
|
|
||||||
or
|
|
||||||
> mvn -N site:sshdeploy (for ssh users w/passphrase and ssh-agent)
|
|
||||||
-->
|
-->
|
||||||
<profile>
|
<profile>
|
||||||
<id>aggregate-site</id>
|
<id>aggregate-site</id>
|
||||||
|
|
Loading…
Reference in New Issue