diff --git a/jetty-documentation/src/main/asciidoc/development/maven/jetty-maven-plugin.adoc b/jetty-documentation/src/main/asciidoc/development/maven/jetty-maven-plugin.adoc
index 24b7bba4ee1..ac5514b2b4f 100644
--- a/jetty-documentation/src/main/asciidoc/development/maven/jetty-maven-plugin.adoc
+++ b/jetty-documentation/src/main/asciidoc/development/maven/jetty-maven-plugin.adoc
@@ -597,6 +597,9 @@ The available configuration parameters - in addition to those for the `jetty:run
jvmArgs::
Optional.
A string representing arbitrary arguments to pass to the forked JVM.
+env::
+Optional.
+Map of key/value pairs to pass as environment to the forked JVM.
waitForChild::
Default is `true`.
This causes the parent process to wait for the forked process to exit.
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java
index fd652bb479a..fb15581c9c6 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java
@@ -25,7 +25,6 @@ import java.security.Principal;
import javax.security.auth.Subject;
import javax.servlet.ServletRequest;
-
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
@@ -203,7 +202,6 @@ public abstract class AbstractLoginService extends AbstractLifeCycle implements
if (user.getUserPrincipal() instanceof UserPrincipal)
{
- System.err.println("VALIDATING user "+fresh.getName());
return fresh.authenticate(((UserPrincipal)user.getUserPrincipal())._credential);
}
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
index 0c418ea65a6..ba795608f44 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java
@@ -18,17 +18,8 @@
package org.eclipse.jetty.security;
-import org.eclipse.jetty.util.PathWatcher;
-import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
-import org.eclipse.jetty.util.StringUtil;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.resource.JarResource;
-import org.eclipse.jetty.util.resource.PathResource;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.util.security.Credential;
-
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -41,6 +32,17 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.PathWatcher;
+import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.resource.JarFileResource;
+import org.eclipse.jetty.util.resource.PathResource;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.security.Credential;
+
/**
* PropertyUserStore
*
@@ -59,13 +61,10 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
{
private static final Logger LOG = Log.getLogger(PropertyUserStore.class);
- private static final String JAR_FILE = "jar:file:";
-
protected Path _configPath;
- protected Resource _configResource;
- protected PathWatcher pathWatcher;
- protected boolean hotReload = false; // default is not to reload
+ protected PathWatcher _pathWatcher;
+ protected boolean _hotReload = false; // default is not to reload
protected boolean _firstLoad = true; // true if first load, false from that point on
protected List _listeners;
@@ -73,9 +72,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
/**
* Get the config (as a string)
* @return the config path as a string
- * @deprecated use {@link #getConfigPath()} instead
*/
- @Deprecated
public String getConfig()
{
if (_configPath != null)
@@ -89,16 +86,28 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
*/
public void setConfig(String config)
{
+ if (config == null)
+ {
+ _configPath = null;
+ return;
+ }
+
try
{
Resource configResource = Resource.newResource(config);
- if (configResource.getFile() != null)
- setConfigPath(configResource.getFile());
+
+ if (configResource instanceof JarFileResource)
+ _configPath = extractPackedFile((JarFileResource)configResource);
+ else if (configResource instanceof PathResource)
+ _configPath = ((PathResource)configResource).getPath();
+ else if (configResource.getFile() != null)
+ setConfigFile(configResource.getFile());
else
- throw new IllegalArgumentException(config+" is not a file");
+ throw new IllegalArgumentException(config);
}
catch (Exception e)
{
+ _configPath = null;
throw new IllegalStateException(e);
}
@@ -117,44 +126,33 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
* Set the Config Path from a String reference to a file
* @param configFile the config file can a be a file path or a reference to a file within a jar file jar:file:
*/
+ @Deprecated
public void setConfigPath(String configFile)
{
- if (configFile == null)
- {
- _configPath = null;
- }
- else if (new File( configFile ).exists())
- {
- _configPath = new File(configFile).toPath();
- }
- if ( !new File( configFile ).exists() && configFile.startsWith( JAR_FILE ))
- {
- // format of the url is jar:file:/foo/bar/beer.jar!/mountain_goat/pale_ale.txt
- // ideally we'd like to extract this to Resource class?
- try
- {
- _configPath = extractPackedFile( configFile );
- }
- catch ( IOException e )
- {
- throw new RuntimeException( "cannot extract file from url:" + configFile, e );
- }
- }
+ setConfig(configFile);
}
- private Path extractPackedFile( String configFile )
+ private Path extractPackedFile( JarFileResource configResource )
throws IOException
{
- int fileIndex = configFile.indexOf( "!" );
- String entryPath = configFile.substring( fileIndex + 1, configFile.length() );
+ String uri = configResource.getURI().toASCIIString();
+ int colon = uri.lastIndexOf(":");
+ int bang_slash = uri.indexOf("!/");
+ if (colon<0 || bang_slash<0 || colon>bang_slash)
+ throw new IllegalArgumentException("Not resolved JarFile resource: "+uri);
+ String entry_path = uri.substring(colon+2).replace("!/","__").replace('/','_').replace('.','_');
Path tmpDirectory = Files.createTempDirectory( "users_store" );
- Path extractedPath = Paths.get(tmpDirectory.toString(), entryPath);
- // delete if exists as copyTo do not overwrite
+ tmpDirectory.toFile().deleteOnExit();
+ Path extractedPath = Paths.get(tmpDirectory.toString(), entry_path);
Files.deleteIfExists( extractedPath );
- // delete on shutdown
extractedPath.toFile().deleteOnExit();
- JarResource.newResource( configFile ).copyTo( tmpDirectory.toFile() );
+ IO.copy(configResource.getInputStream(),new FileOutputStream(extractedPath.toFile()));
+ if (isHotReload())
+ {
+ LOG.warn("Cannot hot reload from packed configuration: {}",configResource);
+ setHotReload(false);
+ }
return extractedPath;
}
@@ -162,7 +160,17 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
* Set the Config Path from a {@link File} reference
* @param configFile the config file
*/
+ @Deprecated
public void setConfigPath(File configFile)
+ {
+ setConfigFile(configFile);
+ }
+
+ /**
+ * Set the Config Path from a {@link File} reference
+ * @param configFile the config file
+ */
+ public void setConfigFile(File configFile)
{
if(configFile == null)
{
@@ -182,19 +190,15 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
_configPath = configPath;
}
- /* ------------------------------------------------------------ */
/**
* @return the resource associated with the configured properties file, creating it if necessary
* @throws IOException if unable to get the resource
*/
public Resource getConfigResource() throws IOException
{
- if (_configResource == null)
- {
- _configResource = new PathResource(_configPath);
- }
-
- return _configResource;
+ if (_configPath==null)
+ return null;
+ return new PathResource(_configPath);
}
/**
@@ -204,7 +208,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
*/
public boolean isHotReload()
{
- return hotReload;
+ return _hotReload;
}
/**
@@ -218,7 +222,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
{
throw new IllegalStateException("Cannot set hot reload while user store is running");
}
- this.hotReload = enable;
+ this._hotReload = enable;
}
@@ -247,8 +251,9 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
}
Properties properties = new Properties();
- if (getConfigResource().exists())
- properties.load(getConfigResource().getInputStream());
+ Resource config = getConfigResource();
+ if (config!=null && config.exists())
+ properties.load(config.getInputStream());
Set known = new HashSet<>();
@@ -297,7 +302,6 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
}
}
-
/*
* set initial load to false as there should be no more initial loads
*/
@@ -324,11 +328,11 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
loadUsers();
if ( isHotReload() && (_configPath != null) )
{
- this.pathWatcher = new PathWatcher();
- this.pathWatcher.watch(_configPath);
- this.pathWatcher.addListener(this);
- this.pathWatcher.setNotifyExistingOnStart(false);
- this.pathWatcher.start();
+ this._pathWatcher = new PathWatcher();
+ this._pathWatcher.watch(_configPath);
+ this._pathWatcher.addListener(this);
+ this._pathWatcher.setNotifyExistingOnStart(false);
+ this._pathWatcher.start();
}
}
@@ -357,9 +361,9 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
protected void doStop() throws Exception
{
super.doStop();
- if (this.pathWatcher != null)
- this.pathWatcher.stop();
- this.pathWatcher = null;
+ if (this._pathWatcher != null)
+ this._pathWatcher.stop();
+ this._pathWatcher = null;
}
/**
diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
index 2f24ebb6d56..84e8c764b75 100644
--- a/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
+++ b/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java
@@ -169,7 +169,7 @@ public class PropertyUserStoreTest
final File usersFile = initUsersText();
PropertyUserStore store = new PropertyUserStore();
- store.setConfigPath(usersFile);
+ store.setConfigFile(usersFile);
store.registerUserListener(userCount);
@@ -189,7 +189,7 @@ public class PropertyUserStoreTest
final String usersFile = initUsersPackedFileText();
PropertyUserStore store = new PropertyUserStore();
- store.setConfigPath(usersFile);
+ store.setConfig(usersFile);
store.registerUserListener(userCount);
@@ -215,7 +215,7 @@ public class PropertyUserStoreTest
PropertyUserStore store = new PropertyUserStore();
store.setHotReload(true);
- store.setConfigPath(usersFile);
+ store.setConfigFile(usersFile);
store.registerUserListener(userCount);
@@ -246,7 +246,7 @@ public class PropertyUserStoreTest
PropertyUserStore store = new PropertyUserStore();
store.setHotReload(true);
- store.setConfigPath(usersFile);
+ store.setConfigFile(usersFile);
store.registerUserListener(userCount);
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
index dc95ab451fc..c57cb35476d 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java
@@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
-class JarFileResource extends JarResource
+public class JarFileResource extends JarResource
{
private static final Logger LOG = Log.getLogger(JarFileResource.class);
private JarFile _jarFile;
diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java
index 481450f25a4..dff12b4b11f 100644
--- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java
+++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java
@@ -19,18 +19,14 @@
package org.eclipse.jetty.websocket.jsr356;
import java.lang.reflect.Method;
-import java.util.concurrent.Executor;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ShutdownThread;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
@@ -48,10 +44,8 @@ public class JettyClientContainerProvider extends ContainerProvider
private static final Logger LOG = Log.getLogger(JettyClientContainerProvider.class);
private static boolean useSingleton = false;
- private static WebSocketContainer INSTANCE;
private static boolean useServerContainer = false;
- private static Executor commonExecutor;
- private static ByteBufferPool commonBufferPool;
+ private static WebSocketContainer INSTANCE;
private static Object lock = new Object();
@@ -83,7 +77,7 @@ public class JettyClientContainerProvider extends ContainerProvider
/**
* Add ability of calls to {@link ContainerProvider#getWebSocketContainer()} to
- * find and return the {@link javax.websocket.server.ServerContainer} from the
+ * find and return the {@code javax.websocket.server.ServerContainer} from the
* active {@code javax.servlet.ServletContext}.
*
*
@@ -91,7 +85,7 @@ public class JettyClientContainerProvider extends ContainerProvider
* occurs within a thread being processed by the Servlet container.
*
*
- * @param flag true to to use return the {@link javax.websocket.server.ServerContainer}
+ * @param flag true to to use return the {@code javax.websocket.server.ServerContainer}
* from the active {@code javax.servlet.ServletContext} for all calls to
* {@link ContainerProvider#getWebSocketContainer()} from within a Servlet thread.
*/
@@ -103,13 +97,13 @@ public class JettyClientContainerProvider extends ContainerProvider
/**
* Test if {@link ContainerProvider#getWebSocketContainer()} has the ability to
- * find and return the {@link javax.websocket.server.ServerContainer} from the
+ * find and return the {@code javax.websocket.server.ServerContainer} from the
* active {@code javax.servlet.ServletContext}, before creating a new client based
* {@link WebSocketContainer}.
*
* @return true if {@link WebSocketContainer} returned from
* calls to {@link ContainerProvider#getWebSocketContainer()} could be the
- * {@link javax.websocket.server.ServerContainer}
+ * {@code javax.websocket.server.ServerContainer}
* from the active {@code javax.servlet.ServletContext}
*/
@SuppressWarnings("unused")
@@ -194,28 +188,14 @@ public class JettyClientContainerProvider extends ContainerProvider
// Still no instance?
if (webSocketContainer == null)
{
- if (commonExecutor == null)
- {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- String name = "Jsr356Client@" + hashCode();
- threadPool.setName(name);
- threadPool.setDaemon(true);
- commonExecutor = threadPool;
- }
-
- if (commonBufferPool == null)
- {
- commonBufferPool = new MappedByteBufferPool();
- }
-
- SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null);
+ SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy());
ClientContainer clientContainer = new ClientContainer(containerScope);
if (contextHandler != null && contextHandler instanceof ContainerLifeCycle)
{
// Add as bean to contextHandler
// Allow startup to follow Jetty lifecycle
- ((ContainerLifeCycle) contextHandler).addBean(clientContainer);
+ ((ContainerLifeCycle) contextHandler).addManaged(clientContainer);
}
else
{
diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
index 30464349810..11d4ef71a46 100644
--- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
+++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java
@@ -66,16 +66,16 @@ import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
public class WebSocketClient extends ContainerLifeCycle implements WebSocketContainerScope
{
private static final Logger LOG = Log.getLogger(WebSocketClient.class);
-
+
// From HttpClient
private final HttpClient httpClient;
-
+
// The container
private final WebSocketContainerScope containerScope;
private final WebSocketExtensionFactory extensionRegistry;
private SessionFactory sessionFactory;
private final List listeners = new CopyOnWriteArrayList<>();
-
+
private final int id = ThreadLocalRandom.current().nextInt();
/**
@@ -125,7 +125,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
{
this(new HttpClient());
this.httpClient.setExecutor(executor);
-
+
}
/**
@@ -237,7 +237,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
this.sessionFactory = new WebSocketSessionFactory(containerScope);
}
-
+
/**
* Create WebSocketClient based on pre-existing Container Scope, to allow sharing of
* internal features like Executor, ByteBufferPool, SSLContextFactory, etc.
@@ -388,10 +388,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
if (LOG.isDebugEnabled())
LOG.debug("Stopping {}",this);
- if (ShutdownThread.isRegistered(this))
- {
- ShutdownThread.deregister(this);
- }
+ ShutdownThread.deregister(this);
super.doStop();
@@ -434,7 +431,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
{
return httpClient.getCookieStore();
}
-
+
public Executor getExecutor()
{
return httpClient.getExecutor();
@@ -451,10 +448,10 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
threadPool.setDaemon(true);
return threadPool;
}
-
+
return executor;
}
-
+
public ExtensionFactory getExtensionFactory()
{
return extensionRegistry;
@@ -698,7 +695,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
getPolicy().setIdleTimeout(ms);
httpClient.setIdleTimeout(ms);
}
-
+
/**
* @deprecated see {@link WebSocketPolicy#setMaxTextMessageBufferSize(int)}
*/
diff --git a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java
index c63575f0e42..70232069a48 100644
--- a/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java
+++ b/jetty-websocket/websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/server/jsr356/DelayedStartClientOnServerTest.java
@@ -250,7 +250,7 @@ public class DelayedStartClientOnServerTest
List threadNames = getThreadNames(server, (ContainerLifeCycle)container);
assertNoHttpClientPoolThreads(threadNames);
- assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@")));
+ assertThat("Threads", threadNames, hasItem(containsString("WebSocketContainer@")));
}
finally
{
diff --git a/pom.xml b/pom.xml
index 8defcf427ff..067fc3c4a41 100644
--- a/pom.xml
+++ b/pom.xml
@@ -933,7 +933,7 @@
org.eclipse.jetty.toolchain
jetty-test-helper
- 4.1
+ 4.2
org.eclipse.jetty.toolchain