diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java index 8db704b15d5..ca182eadde6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @@ -37,6 +37,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo { public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio"); + private final boolean WORK_AROUND_JVM_BUG_6346658 = System.getProperty("os.name").toLowerCase().contains("win"); private final SelectorManager.SelectSet _selectSet; private final SelectorManager _manager; private SelectionKey _key; @@ -681,15 +682,23 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo @Override public void close() throws IOException { - try + // On unix systems there is a JVM issue that if you cancel before closing, it can + // cause the selector to block waiting for a channel to close and that channel can + // block waiting for the remote end. But on windows, if you don't cancel before a + // close, then the selector can block anyway! + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=357318 + if (WORK_AROUND_JVM_BUG_6346658) { - SelectionKey key = _key; - if (key!=null) - key.cancel(); - } - catch (Throwable e) - { - LOG.ignore(e); + try + { + SelectionKey key = _key; + if (key!=null) + key.cancel(); + } + catch (Throwable e) + { + LOG.ignore(e); + } } try diff --git a/jetty-jmx/src/main/config/etc/jetty-jmx.xml b/jetty-jmx/src/main/config/etc/jetty-jmx.xml index a685eded058..4db0dbb473a 100644 --- a/jetty-jmx/src/main/config/etc/jetty-jmx.xml +++ b/jetty-jmx/src/main/config/etc/jetty-jmx.xml @@ -69,7 +69,7 @@ --> diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java index c07ab027131..d8491eeacbe 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/DefaultJettyAtJettyHomeHelper.java @@ -39,7 +39,7 @@ import org.osgi.framework.BundleContext; public class DefaultJettyAtJettyHomeHelper { private static final Logger LOG = Log.getLogger(DefaultJettyAtJettyHomeHelper.class); - + /** * contains a comma separated list of pathes to the etc/jetty-*.xml files * used to configure jetty. By default the value is 'etc/jetty.xml' when the @@ -69,7 +69,7 @@ public class DefaultJettyAtJettyHomeHelper { * Usual system property used as the port for https for a typical jetty configuration. */ public static final String SYS_PROP_JETTY_PORT_SSL = "jetty.port.ssl"; - + /** * Called by the JettyBootStrapActivator. * If the system property jetty.home is defined and points to a folder, @@ -88,81 +88,76 @@ public class DefaultJettyAtJettyHomeHelper { * that might use them as part of their properties. *

*/ - public static void startJettyAtJettyHome(BundleContext bundleContext) + public static void startJettyAtJettyHome(BundleContext bundleContext) throws Exception { - String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME); - String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE); - File jettyHome = null; - Bundle jettyHomeBundle = null; - if (jettyHomeSysProp != null) - { - jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); - //bug 329621 - if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") - || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) { - jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); - } - if (jettyHomeBundleSysProp != null) - { - LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." - + " jetty.home.bundle is not taken into account."); - } - jettyHome = new File(jettyHomeSysProp); - if (!jettyHome.exists() || !jettyHome.isDirectory()) - { - LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); - return; - } - } - else if (jettyHomeBundleSysProp != null) - { - jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp); - for (Bundle b : bundleContext.getBundles()) - { - if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) - { - jettyHomeBundle = b; - break; - } - } - if (jettyHomeBundle == null) - { - LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); - return; - } - - } - if (jettyHome == null && jettyHomeBundle == null) - { - LOG.warn("No default jetty started."); - return; - } - try - { - Server server = new Server(); - Dictionary properties = new Hashtable(); - properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); - - String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle); - properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); + String jettyHomeSysProp = System.getProperty(SYS_PROP_JETTY_HOME); + String jettyHomeBundleSysProp = System.getProperty(SYS_PROP_JETTY_HOME_BUNDLE); + File jettyHome = null; + Bundle jettyHomeBundle = null; + if (jettyHomeSysProp != null) + { + jettyHomeSysProp = resolvePropertyValue(jettyHomeSysProp); + //bug 329621 + if (jettyHomeSysProp.startsWith("\"") && jettyHomeSysProp.endsWith("\"") + || (jettyHomeSysProp.startsWith("'") && jettyHomeSysProp.endsWith("'"))) { + jettyHomeSysProp = jettyHomeSysProp.substring(1, jettyHomeSysProp.length() - 1); + } + if (jettyHomeBundleSysProp != null) + { + LOG.warn("Both the jetty.home property and the jetty.home.bundle property are defined." + + " jetty.home.bundle is not taken into account."); + } + jettyHome = new File(jettyHomeSysProp); + if (!jettyHome.exists() || !jettyHome.isDirectory()) + { + LOG.warn("Unable to locate the jetty.home folder " + jettyHomeSysProp); + return; + } + } + else if (jettyHomeBundleSysProp != null) + { + jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp); + for (Bundle b : bundleContext.getBundles()) + { + if (b.getSymbolicName().equals(jettyHomeBundleSysProp)) + { + jettyHomeBundle = b; + break; + } + } + if (jettyHomeBundle == null) + { + LOG.warn("Unable to find the jetty.home.bundle named " + jettyHomeSysProp); + return; + } - LOG.info("Configuring the default jetty server with " + configURLs); - - //these properties usually are the ones passed to this type of configuration. - setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); - setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); - setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); - setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); + } + if (jettyHome == null && jettyHomeBundle == null) + { + LOG.warn("No default jetty started."); + return; + } + + Server server = new Server(); + Dictionary properties = new Hashtable(); + properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME); + + String configURLs = jettyHome != null ? getJettyConfigurationURLs(jettyHome) : getJettyConfigurationURLs(jettyHomeBundle); + properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, configURLs); + + LOG.info("Configuring the default jetty server with " + configURLs); + + //these properties usually are the ones passed to this type of configuration. + setProperty(properties,SYS_PROP_JETTY_HOME,System.getProperty(SYS_PROP_JETTY_HOME)); + setProperty(properties,SYS_PROP_JETTY_HOST,System.getProperty(SYS_PROP_JETTY_HOST)); + setProperty(properties,SYS_PROP_JETTY_PORT,System.getProperty(SYS_PROP_JETTY_PORT)); + setProperty(properties,SYS_PROP_JETTY_PORT_SSL,System.getProperty(SYS_PROP_JETTY_PORT_SSL)); + + bundleContext.registerService(Server.class.getName(), server, properties); + // hookNestedConnectorToBridgeServlet(server); - bundleContext.registerService(Server.class.getName(), server, properties); -// hookNestedConnectorToBridgeServlet(server); - } - catch (Throwable t) - { - t.printStackTrace(); - } } - + /** * Minimum setup for the location of the configuration files given a jettyhome folder. * Reads the system property jetty.etc.config.urls and look for the corresponding jetty @@ -172,22 +167,22 @@ public class DefaultJettyAtJettyHomeHelper { */ private static String getJettyConfigurationURLs(File jettyhome) { - String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); + String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false); StringBuilder res = new StringBuilder(); while (tokenizer.hasMoreTokens()) { - String next = tokenizer.nextToken().trim(); - if (!next.startsWith("/") && next.indexOf(':') == -1) - { - try { - next = new File(jettyhome, next).toURI().toURL().toString(); - } catch (MalformedURLException e) { - e.printStackTrace(); - continue; - } - } - appendToCommaSeparatedList(res, next); + String next = tokenizer.nextToken().trim(); + if (!next.startsWith("/") && next.indexOf(':') == -1) + { + try { + next = new File(jettyhome, next).toURI().toURL().toString(); + } catch (MalformedURLException e) { + e.printStackTrace(); + continue; + } + } + appendToCommaSeparatedList(res, next); } return res.toString(); } @@ -202,108 +197,108 @@ public class DefaultJettyAtJettyHomeHelper { */ private static String getJettyConfigurationURLs(Bundle configurationBundle) { - String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); + String jettyetc = System.getProperty(SYS_PROP_JETTY_ETC_FILES,"etc/jetty.xml"); StringTokenizer tokenizer = new StringTokenizer(jettyetc,";,", false); StringBuilder res = new StringBuilder(); - + while (tokenizer.hasMoreTokens()) { String etcFile = tokenizer.nextToken().trim(); if (etcFile.startsWith("/") || etcFile.indexOf(":") != -1) { - appendToCommaSeparatedList(res, etcFile); + appendToCommaSeparatedList(res, etcFile); } else { - Enumeration enUrls = BundleFileLocatorHelper.DEFAULT - .findEntries(configurationBundle, etcFile); - - //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. - //default inside jettyhome. this way fragments to the bundle can define their own configuration. - if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml")) - { - enUrls = BundleFileLocatorHelper.DEFAULT - .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); - System.err.println("Configuring jetty with the default embedded configuration:" + - "bundle: " + configurationBundle.getSymbolicName() + - " config: /jettyhome/etc/jetty-osgi-default.xml"); - } - if (enUrls == null || !enUrls.hasMoreElements()) - { - System.err.println("Unable to locate a jetty configuration file for " + etcFile); - } - if (enUrls != null) - { - while (enUrls.hasMoreElements()) - { - appendToCommaSeparatedList(res, enUrls.nextElement().toString()); - } - } + Enumeration enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, etcFile); + + //default for org.eclipse.osgi.boot where we look inside jettyhome for the default embedded configuration. + //default inside jettyhome. this way fragments to the bundle can define their own configuration. + if ((enUrls == null || !enUrls.hasMoreElements()) && etcFile.endsWith("etc/jetty.xml")) + { + enUrls = BundleFileLocatorHelper.DEFAULT + .findEntries(configurationBundle, "/jettyhome/etc/jetty-osgi-default.xml"); + System.err.println("Configuring jetty with the default embedded configuration:" + + "bundle: " + configurationBundle.getSymbolicName() + + " config: /jettyhome/etc/jetty-osgi-default.xml"); + } + if (enUrls == null || !enUrls.hasMoreElements()) + { + System.err.println("Unable to locate a jetty configuration file for " + etcFile); + } + if (enUrls != null) + { + while (enUrls.hasMoreElements()) + { + appendToCommaSeparatedList(res, enUrls.nextElement().toString()); + } + } } } return res.toString(); } - - private static void appendToCommaSeparatedList(StringBuilder buffer, String value) - { - if (buffer.length() != 0) - { - buffer.append(","); - } - buffer.append(value); - } - - private static void setProperty(Dictionary properties, String key, String value) - { - if (value != null) - { - properties.put(key, value); - } - } - - /** - * recursively substitute the ${sysprop} by their actual system property. - * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined. - * Not the most efficient code but we are shooting for simplicity and speed of development here. - * - * @param value - * @return - */ - public static String resolvePropertyValue(String value) - { - int ind = value.indexOf("${"); - if (ind == -1) { - return value; - } - int ind2 = value.indexOf('}', ind); - if (ind2 == -1) { - return value; - } - String sysprop = value.substring(ind+2, ind2); - String defaultValue = null; - int comma = sysprop.indexOf(','); - if (comma != -1 && comma+1 != sysprop.length()) - { - defaultValue = sysprop.substring(comma+1); - defaultValue = resolvePropertyValue(defaultValue); - sysprop = sysprop.substring(0,comma); - } - else - { - defaultValue = "${" + sysprop + "}"; - } - - String v = System.getProperty(sysprop); - - String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : ""; - reminder = resolvePropertyValue(reminder); - if (v != null) - { - return value.substring(0, ind) + v + reminder; - } - else - { - return value.substring(0, ind) + defaultValue + reminder; - } - } + + private static void appendToCommaSeparatedList(StringBuilder buffer, String value) + { + if (buffer.length() != 0) + { + buffer.append(","); + } + buffer.append(value); + } + + private static void setProperty(Dictionary properties, String key, String value) + { + if (value != null) + { + properties.put(key, value); + } + } + + /** + * recursively substitute the ${sysprop} by their actual system property. + * ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no sysprop is defined. + * Not the most efficient code but we are shooting for simplicity and speed of development here. + * + * @param value + * @return + */ + public static String resolvePropertyValue(String value) + { + int ind = value.indexOf("${"); + if (ind == -1) { + return value; + } + int ind2 = value.indexOf('}', ind); + if (ind2 == -1) { + return value; + } + String sysprop = value.substring(ind+2, ind2); + String defaultValue = null; + int comma = sysprop.indexOf(','); + if (comma != -1 && comma+1 != sysprop.length()) + { + defaultValue = sysprop.substring(comma+1); + defaultValue = resolvePropertyValue(defaultValue); + sysprop = sysprop.substring(0,comma); + } + else + { + defaultValue = "${" + sysprop + "}"; + } + + String v = System.getProperty(sysprop); + + String reminder = value.length() > ind2 + 1 ? value.substring(ind2+1) : ""; + reminder = resolvePropertyValue(reminder); + if (v != null) + { + return value.substring(0, ind) + v + reminder; + } + else + { + return value.substring(0, ind) + defaultValue + reminder; + } + } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java index 200647cecc9..88f1d7f4f5c 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServerServiceTracker.java @@ -18,50 +18,53 @@ import java.util.Properties; import org.eclipse.jetty.osgi.boot.OSGiServerConstants; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; /** - * Deploy the jetty server instances when they are registered as an OSGi service. + * Deploy the jetty server instances when they are registered as an OSGi + * service. */ public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry { - + private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName()); + /** - * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service. + * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin + * service. */ private Map _serversIndexedByName = new HashMap(); + /** The context-handler to deactivate indexed by ServerInstanceWrapper */ private Map _indexByServiceReference = new HashMap(); - /** * Stops each one of the registered servers. */ public void stop() { - //not sure that this is really useful but here we go. - for (ServerInstanceWrapper wrapper : _serversIndexedByName.values()) - { - try - { - wrapper.stop(); - } - catch (Throwable t) - { - - } - } + // not sure that this is really useful but here we go. + for (ServerInstanceWrapper wrapper : _serversIndexedByName.values()) + { + try + { + wrapper.stop(); + } + catch (Throwable t) + { + LOG.warn(t); + } + } } - /** * Receives notification that a service has had a lifecycle change. * - * @param ev - * The ServiceEvent object. + * @param ev The ServiceEvent object. */ public void serviceChanged(ServiceEvent ev) { @@ -71,17 +74,16 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty case ServiceEvent.MODIFIED: case ServiceEvent.UNREGISTERING: { - ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference()); + ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference()); if (instance != null) { try { - instance.stop(); + instance.stop(); } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOG.warn(e); } } } @@ -96,32 +98,35 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty } case ServiceEvent.REGISTERED: { - Bundle contributor = sr.getBundle(); - Server server = (Server)contributor.getBundleContext().getService(sr); - ServerInstanceWrapper wrapper = registerInIndex(server, sr); - Properties props = new Properties(); - for (String key : sr.getPropertyKeys()) - { - Object value = sr.getProperty(key); - props.put(key, value); - } - wrapper.start(server, props); - break; + try + { + Bundle contributor = sr.getBundle(); + Server server = (Server) contributor.getBundleContext().getService(sr); + ServerInstanceWrapper wrapper = registerInIndex(server, sr); + Properties props = new Properties(); + for (String key : sr.getPropertyKeys()) + { + Object value = sr.getProperty(key); + props.put(key, value); + } + wrapper.start(server, props); + } + catch (Exception e) + { + LOG.warn(e); + } + break; } } } private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr) { - String name = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); - if (name == null) - { - throw new IllegalArgumentException("The property " + - OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); - } + String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); + if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); } ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name); - _indexByServiceReference.put(sr,wrapper); - _serversIndexedByName.put(name,wrapper); + _indexByServiceReference.put(sr, wrapper); + _serversIndexedByName.put(name, wrapper); return wrapper; } @@ -133,7 +138,7 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty */ private ServerInstanceWrapper unregisterInIndex(ServiceReference sr) { - ServerInstanceWrapper handler = _indexByServiceReference.remove(sr); + ServerInstanceWrapper handler = _indexByServiceReference.remove(sr); if (handler == null) { // a warning? @@ -149,13 +154,12 @@ public class JettyServerServiceTracker implements ServiceListener, IManagedJetty /** * @param managedServerName The server name - * @return the corresponding jetty server wrapped with its deployment properties. + * @return the corresponding jetty server wrapped with its deployment + * properties. */ public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName) { - return _serversIndexedByName.get(managedServerName == null - ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName); + return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName); } - - + } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java index 31ad22534b2..3872fad70ff 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/JettyServersManagedFactory.java @@ -99,14 +99,21 @@ public class JettyServersManagedFactory implements ManagedServiceFactory, IManag String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME); if (name == null) { - throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, - "The name of the server is mandatory"); + throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, + "The name of the server is mandatory"); } serverInstanceWrapper = new ServerInstanceWrapper(name); _serversIndexedByPID.put(pid, serverInstanceWrapper); _serversNameIndexedByPID.put(pid, name); _serversPIDIndexedByName.put(name, pid); - serverInstanceWrapper.start(new Server(), properties); + try + { + serverInstanceWrapper.start(new Server(), properties); + } + catch (Exception e) + { + throw new ConfigurationException(null, "Error starting jetty server instance", e); + } } public synchronized void deleted(String pid) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java index 21d0d6adb7d..bb274fe313e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.java @@ -44,28 +44,29 @@ import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.xml.XmlConfiguration; import org.xml.sax.SAXParseException; - /** * Exposes a Jetty Server to be managed by an OSGi ManagedServiceFactory - * Configure and start it. - * Can also be used from the ManagedServiceFactory + * Configure and start it. Can also be used from the ManagedServiceFactory */ -public class ServerInstanceWrapper { +public class ServerInstanceWrapper +{ - /** The value of this property points to the parent director of - * the jetty.xml configuration file currently executed. - * Everything is passed as a URL to support the - * case where the bundle is zipped. */ + /** + * The value of this property points to the parent director of the jetty.xml + * configuration file currently executed. Everything is passed as a URL to + * support the case where the bundle is zipped. + */ public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url"; - private static Logger __logger = Log.getLogger(ServerInstanceWrapper.class.getName()); - + private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName()); + private final String _managedServerName; - + /** * The managed jetty server */ private Server _server; + private ContextHandlerCollection _ctxtHandler; /** @@ -74,32 +75,34 @@ public class ServerInstanceWrapper { * let the TldScanner find the jars where the tld files are. */ private ClassLoader _commonParentClassLoaderForWebapps; + private DeploymentManager _deploymentManager; + private OSGiAppProvider _provider; - + private WebBundleDeployerHelper _webBundleDeployerHelper; - - + public ServerInstanceWrapper(String managedServerName) { _managedServerName = managedServerName; } - + public String getManagedServerName() { return _managedServerName; } - + /** - * The classloader that should be the parent classloader for - * each webapp deployed on this server. + * The classloader that should be the parent classloader for each webapp + * deployed on this server. + * * @return */ public ClassLoader getParentClassLoaderForWebapps() { return _commonParentClassLoaderForWebapps; } - + /** * @return The deployment manager registered on this server. */ @@ -107,7 +110,7 @@ public class ServerInstanceWrapper { { return _deploymentManager; } - + /** * @return The app provider registered on this server. */ @@ -115,19 +118,17 @@ public class ServerInstanceWrapper { { return _provider; } - - + public Server getServer() { return _server; } - - + public WebBundleDeployerHelper getWebBundleDeployerHelp() { return _webBundleDeployerHelper; } - + /** * @return The collection of context handlers */ @@ -136,8 +137,7 @@ public class ServerInstanceWrapper { return _ctxtHandler; } - - public void start(Server server, Dictionary props) + public void start(Server server, Dictionary props) throws Exception { _server = server; ClassLoader contextCl = Thread.currentThread().getContextClassLoader(); @@ -146,62 +146,61 @@ public class ServerInstanceWrapper { // passing this bundle's classloader as the context classlaoder // makes sure there is access to all the jetty's bundles ClassLoader libExtClassLoader = null; - String sharedURLs = (String)props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); - try - { - List shared = sharedURLs != null ? extractFiles(sharedURLs) : null; - libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader( - shared, null, server, JettyBootstrapActivator.class.getClassLoader()); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } + String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS); + + List shared = sharedURLs != null ? extractFiles(sharedURLs) : null; + libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader()); Thread.currentThread().setContextClassLoader(libExtClassLoader); - + configure(server, props); init(); - //now that we have an app provider we can call the registration customizer. - try - { - URL[] jarsWithTlds = getJarsWithTlds(); - _commonParentClassLoaderForWebapps = jarsWithTlds == null - ? libExtClassLoader - :new TldLocatableURLClassloader(libExtClassLoader,jarsWithTlds); - } - catch (MalformedURLException e) - { - e.printStackTrace(); - } + // now that we have an app provider we can call the registration + // customizer. + + URL[] jarsWithTlds = getJarsWithTlds(); + _commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds); - server.start(); + _webBundleDeployerHelper = new WebBundleDeployerHelper(this); } - catch (Throwable t) + catch (Exception e) { - t.printStackTrace(); + if (server != null) + { + try + { + server.stop(); + } + catch (Exception x) + { + LOG.ignore(x); + } + } + throw e; } finally { Thread.currentThread().setContextClassLoader(contextCl); } - _webBundleDeployerHelper = new WebBundleDeployerHelper(this); + + } - - + public void stop() { - try { + try + { if (_server.isRunning()) { _server.stop(); } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } + catch (Exception e) + { + LOG.warn(e); } } @@ -229,14 +228,13 @@ public class ServerInstanceWrapper { private URL[] getJarsWithTlds() throws Exception { ArrayList res = new ArrayList(); - WebBundleDeployerHelper.staticInit();//that is not looking great. + WebBundleDeployerHelper.staticInit();// that is not looking great. for (WebappRegistrationCustomizer regCustomizer : WebBundleDeployerHelper.JSP_REGISTRATION_HELPERS) { URL[] urls = regCustomizer.getJarsWithTlds(_provider, WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER); for (URL url : urls) { - if (!res.contains(url)) - res.add(url); + if (!res.contains(url)) res.add(url); } } if (!res.isEmpty()) @@ -244,19 +242,15 @@ public class ServerInstanceWrapper { else return null; } - + private void configure(Server server, Dictionary props) throws Exception { String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS); - List jettyConfigurations = jettyConfigurationUrls != null - ? extractResources(jettyConfigurationUrls) : null; - if (jettyConfigurations == null || jettyConfigurations.isEmpty()) - { - return; - } - Map id_map = new HashMap(); - id_map.put("Server",server); - Map properties = new HashMap(); + List jettyConfigurations = jettyConfigurationUrls != null ? extractResources(jettyConfigurationUrls) : null; + if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; } + Map id_map = new HashMap(); + id_map.put("Server", server); + Map properties = new HashMap(); Enumeration en = props.keys(); while (en.hasMoreElements()) { @@ -275,15 +269,17 @@ public class ServerInstanceWrapper { is = r.getInputStream(); XmlConfiguration config = new XmlConfiguration(is); config.getIdMap().putAll(id_map); - - //#334062 compute the URL of the folder that contains the jetty.xml conf file - //and set it as a property so we can compute relative paths from it. + + // #334062 compute the URL of the folder that contains the + // jetty.xml conf file + // and set it as a property so we can compute relative paths + // from it. String urlPath = jettyConfiguration.toString(); int lastSlash = urlPath.lastIndexOf('/'); if (lastSlash > 4) { urlPath = urlPath.substring(0, lastSlash); - Map properties2 = new HashMap(properties); + Map properties2 = new HashMap(properties); properties2.put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath); config.getProperties().putAll(properties2); } @@ -292,11 +288,11 @@ public class ServerInstanceWrapper { config.getProperties().putAll(properties); } config.configure(); - id_map=config.getIdMap(); + id_map = config.getIdMap(); } catch (SAXParseException saxparse) { - __logger.warn("Unable to configure the jetty/etc file " + jettyConfiguration,saxparse); + LOG.warn("Unable to configure the jetty/etc file " + jettyConfiguration, saxparse); throw saxparse; } finally @@ -306,8 +302,7 @@ public class ServerInstanceWrapper { } } - - + /** * Must be called after the server is configured. * @@ -319,50 +314,48 @@ public class ServerInstanceWrapper { private void init() { // Get the context handler - _ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class); - + _ctxtHandler = (ContextHandlerCollection) _server.getChildHandlerByClass(ContextHandlerCollection.class); + // get a deployerManager List deployers = _server.getBeans(DeploymentManager.class); if (deployers != null && !deployers.isEmpty()) { _deploymentManager = deployers.get(0); - + for (AppProvider provider : _deploymentManager.getAppProviders()) { if (provider instanceof OSGiAppProvider) { - _provider=(OSGiAppProvider)provider; + _provider = (OSGiAppProvider) provider; break; } } if (_provider == null) { - //create it on the fly with reasonable default values. + // create it on the fly with reasonable default values. try { _provider = new OSGiAppProvider(); - _provider.setMonitoredDirResource( - Resource.newResource(getDefaultOSGiContextsHome( - new File(System.getProperty("jetty.home"))).toURI())); - } catch (IOException e) { - e.printStackTrace(); + _provider.setMonitoredDirResource(Resource.newResource(getDefaultOSGiContextsHome(new File(System.getProperty("jetty.home"))).toURI())); + } + catch (IOException e) + { + LOG.warn(e); } _deploymentManager.addAppProvider(_provider); } } - if (_ctxtHandler == null || _provider==null) - throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured"); - + if (_ctxtHandler == null || _provider == null) throw new IllegalStateException("ERROR: No ContextHandlerCollection or OSGiAppProvider configured"); } - + /** * @return The default folder in which the context files of the osgi bundles * are located and watched. Or null when the system property - * "jetty.osgi.contexts.home" is not defined. - * If the configuration file defines the OSGiAppProvider's context. - * This will not be taken into account. + * "jetty.osgi.contexts.home" is not defined. If the configuration + * file defines the OSGiAppProvider's context. This will not be + * taken into account. */ File getDefaultOSGiContextsHome(File jettyHome) { @@ -370,20 +363,19 @@ public class ServerInstanceWrapper { if (jettyContextsHome != null) { File contextsHome = new File(jettyContextsHome); - if (!contextsHome.exists() || !contextsHome.isDirectory()) - { - throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder"); - } + if (!contextsHome.exists() || !contextsHome.isDirectory()) { throw new IllegalArgumentException( + "the ${jetty.osgi.contexts.home} '" + jettyContextsHome + + " must exist and be a folder"); } return contextsHome; } return new File(jettyHome, "/contexts"); } - + File getOSGiContextsHome() { return _provider.getContextXmlDirAsFile(); } - + /** * @return the urls in this string. */ @@ -396,19 +388,19 @@ public class ServerInstanceWrapper { String tok = tokenizer.nextToken(); try { - urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper - .BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok))); + urls.add(((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getLocalURL(new URL(tok))); } catch (Throwable mfe) { - + LOG.warn(mfe); } } return urls; } - + /** - * Get the folders that might contain jars for the legacy J2EE shared libraries + * Get the folders that might contain jars for the legacy J2EE shared + * libraries */ private List extractFiles(String propertyValue) { @@ -420,8 +412,7 @@ public class ServerInstanceWrapper { try { URL url = new URL(tok); - url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper - .BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url); + url = ((DefaultFileLocatorHelper) WebBundleDeployerHelper.BUNDLE_FILE_LOCATOR_HELPER).getFileURL(url); if (url.getProtocol().equals("file")) { Resource res = Resource.newResource(url); @@ -434,11 +425,10 @@ public class ServerInstanceWrapper { } catch (Throwable mfe) { - + LOG.warn(mfe); } } return files; } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 76c77f072d5..593692232f1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -267,7 +267,7 @@ public class Server extends HandlerWrapper implements Attributes mex.add(e); } - if (_connectors!=null) + if (_connectors!=null && mex.size()==0) { for (int i=0;i<_connectors.length;i++) { diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java index 445a1bf9150..afae2ab946e 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java @@ -414,7 +414,7 @@ public class ProxyServlet implements Servlet if (request.getQueryString() != null) uri += "?" + request.getQueryString(); - HttpURI url = proxyHttpURI(request.getScheme(),request.getServerName(),request.getServerPort(),uri); + HttpURI url = proxyHttpURI(request,uri); if (debug != 0) _log.debug(debug + " proxy " + uri + "-->" + url); @@ -677,6 +677,11 @@ public class ProxyServlet implements Servlet } /* ------------------------------------------------------------ */ + protected HttpURI proxyHttpURI(HttpServletRequest request, String uri) throws MalformedURLException + { + return proxyHttpURI(request.getScheme(), request.getServerName(), request.getServerPort(), uri); + } + protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) throws MalformedURLException { if (!validateDestination(serverName,uri)) diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java index 10e64130726..c69af218385 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/ISession.java @@ -35,6 +35,4 @@ public interface ISession extends Session public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Handler handler, C context); public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Handler handler, C context); - - public int getWindowSize(); } diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java index 314695336ac..f940b63b1ef 100644 --- a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardSession.java @@ -18,10 +18,11 @@ package org.eclipse.jetty.spdy; import java.nio.ByteBuffer; import java.nio.channels.InterruptedByTimeoutException; -import java.util.ArrayList; import java.util.Deque; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -253,9 +254,9 @@ public class StandardSession implements ISession, Parser.Listener, Handler getStreams() + public Set getStreams() { - List result = new ArrayList<>(); + Set result = new HashSet<>(); result.addAll(streams.values()); return result; } @@ -540,7 +541,10 @@ public class StandardSession implements ISession, Parser.Listener, Handler getStreams(); + public Set getStreams(); /** *

Super interface for listeners with callbacks that are invoked on specific session events.

diff --git a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java index 1ee5f8a96c0..6e246409d58 100644 --- a/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java +++ b/jetty-spdy/spdy-jetty/src/test/java/org/eclipse/jetty/spdy/FlowControlTest.java @@ -23,6 +23,7 @@ import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.spdy.api.BytesDataInfo; import org.eclipse.jetty.spdy.api.DataInfo; @@ -41,6 +42,70 @@ import org.junit.Test; public class FlowControlTest extends AbstractTest { + @Test + public void testFlowControlWithConcurrentSettings() throws Exception + { + // Initial window is 64 KiB. We allow the client to send 1024 B + // then we change the window to 512 B. At this point, the client + // must stop sending data (although the initial window allows it) + + final int size = 512; + final AtomicReference dataInfoRef = new AtomicReference<>(); + final CountDownLatch dataLatch = new CountDownLatch(2); + final CountDownLatch settingsLatch = new CountDownLatch(1); + Session session = startClient(startServer(new ServerSessionFrameListener.Adapter() + { + @Override + public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) + { + stream.reply(new ReplyInfo(true)); + return new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int dataFrameCount = dataFrames.incrementAndGet(); + if (dataFrameCount == 1) + { + dataInfoRef.set(dataInfo); + Settings settings = new Settings(); + settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, size)); + stream.getSession().settings(new SettingsInfo(settings)); + } + else if (dataFrameCount > 1) + { + dataInfo.consume(dataInfo.length()); + dataLatch.countDown(); + } + } + }; + } + }), new SessionFrameListener.Adapter() + { + @Override + public void onSettings(Session session, SettingsInfo settingsInfo) + { + settingsLatch.countDown(); + } + }); + + Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS); + stream.data(new BytesDataInfo(new byte[size * 2], false)); + settingsLatch.await(5, TimeUnit.SECONDS); + + // Send the second chunk of data, must not arrive since we're flow control stalled now + stream.data(new BytesDataInfo(new byte[size * 2], true)); + Assert.assertFalse(dataLatch.await(1, TimeUnit.SECONDS)); + + // Consume the data arrived to server, this will resume flow control + DataInfo dataInfo = dataInfoRef.get(); + dataInfo.consume(dataInfo.length()); + + Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS)); + } + @Test public void testServerFlowControlOneBigWrite() throws Exception { @@ -294,6 +359,98 @@ public class FlowControlTest extends AbstractTest Assert.assertEquals(dataInfo.length(), dataInfo.consumed()); } + @Test + public void testStreamsStalledDoesNotStallOtherStreams() throws Exception + { + final int windowSize = 1024; + final CountDownLatch settingsLatch = new CountDownLatch(1); + Session session = startClient(startServer(new ServerSessionFrameListener.Adapter() + { + @Override + public void onSettings(Session session, SettingsInfo settingsInfo) + { + settingsLatch.countDown(); + } + + @Override + public StreamFrameListener onSyn(Stream stream, SynInfo synInfo) + { + stream.reply(new ReplyInfo(false)); + stream.data(new BytesDataInfo(new byte[windowSize * 2], true)); + return null; + } + }), null); + Settings settings = new Settings(); + settings.put(new Settings.Setting(Settings.ID.INITIAL_WINDOW_SIZE, windowSize)); + session.settings(new SettingsInfo(settings)); + + Assert.assertTrue(settingsLatch.await(5, TimeUnit.SECONDS)); + + final CountDownLatch latch = new CountDownLatch(3); + final AtomicReference dataInfoRef1 = new AtomicReference<>(); + final AtomicReference dataInfoRef2 = new AtomicReference<>(); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int frames = dataFrames.incrementAndGet(); + if (frames == 1) + { + // Do not consume it to stall flow control + dataInfoRef1.set(dataInfo); + } + else + { + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + } + }).get(5, TimeUnit.SECONDS); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + private final AtomicInteger dataFrames = new AtomicInteger(); + + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + int frames = dataFrames.incrementAndGet(); + if (frames == 1) + { + // Do not consume it to stall flow control + dataInfoRef2.set(dataInfo); + } + else + { + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + } + }).get(5, TimeUnit.SECONDS); + session.syn(new SynInfo(true), new StreamFrameListener.Adapter() + { + @Override + public void onData(Stream stream, DataInfo dataInfo) + { + DataInfo dataInfo1 = dataInfoRef1.getAndSet(null); + if (dataInfo1 != null) + dataInfo1.consume(dataInfo1.length()); + DataInfo dataInfo2 = dataInfoRef2.getAndSet(null); + if (dataInfo2 != null) + dataInfo2.consume(dataInfo2.length()); + dataInfo.consume(dataInfo.length()); + if (dataInfo.isClose()) + latch.countDown(); + } + }).get(5, TimeUnit.SECONDS); + + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } + private void expectException(Class exception, Callable command) { try diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index d625814ba26..70fbe1063f8 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -381,7 +381,7 @@ public class Main } else if (info.equals("@STARTINI")) { - List ini = loadStartIni(null); + List ini = loadStartIni(new File(_jettyHome,"start.ini")); if (ini != null && ini.size() > 0) { for (String a : ini) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java index 9495f68a923..d7748365c8e 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebInfConfiguration.java @@ -402,8 +402,7 @@ public class WebInfConfiguration extends AbstractConfiguration } if (LOG.isDebugEnabled()) - LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()); - + LOG.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory()+" file="+(web_app.getFile())); // Is the WAR usable directly? if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:")) { @@ -485,57 +484,50 @@ public class WebInfConfiguration extends AbstractConfiguration LOG.debug("webapp=" + web_app); } - // Do we need to extract WEB-INF/lib? - if (context.isCopyWebInf()) + if (context.isCopyWebInf() && !context.isCopyWebDir()) { Resource web_inf= web_app.addPath("WEB-INF/"); - if (web_inf instanceof ResourceCollection || - web_inf.exists() && - web_inf.isDirectory() && - (web_inf.getFile()==null || !web_inf.getFile().isDirectory())) - { - File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); - if (extractedWebInfDir.exists()) - IO.delete(extractedWebInfDir); - extractedWebInfDir.mkdir(); - Resource web_inf_lib = web_inf.addPath("lib/"); - File webInfDir=new File(extractedWebInfDir,"WEB-INF"); - webInfDir.mkdir(); + File extractedWebInfDir= new File(context.getTempDirectory(), "webinf"); + if (extractedWebInfDir.exists()) + IO.delete(extractedWebInfDir); + extractedWebInfDir.mkdir(); + Resource web_inf_lib = web_inf.addPath("lib/"); + File webInfDir=new File(extractedWebInfDir,"WEB-INF"); + webInfDir.mkdir(); - if (web_inf_lib.exists()) - { - File webInfLibDir = new File(webInfDir, "lib"); - if (webInfLibDir.exists()) - IO.delete(webInfLibDir); - webInfLibDir.mkdir(); + if (web_inf_lib.exists()) + { + File webInfLibDir = new File(webInfDir, "lib"); + if (webInfLibDir.exists()) + IO.delete(webInfLibDir); + webInfLibDir.mkdir(); - LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); - web_inf_lib.copyTo(webInfLibDir); - } + LOG.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); + web_inf_lib.copyTo(webInfLibDir); + } - Resource web_inf_classes = web_inf.addPath("classes/"); - if (web_inf_classes.exists()) - { - File webInfClassesDir = new File(webInfDir, "classes"); - if (webInfClassesDir.exists()) - IO.delete(webInfClassesDir); - webInfClassesDir.mkdir(); - LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath()); - web_inf_classes.copyTo(webInfClassesDir); - } + Resource web_inf_classes = web_inf.addPath("classes/"); + if (web_inf_classes.exists()) + { + File webInfClassesDir = new File(webInfDir, "classes"); + if (webInfClassesDir.exists()) + IO.delete(webInfClassesDir); + webInfClassesDir.mkdir(); + LOG.info("Copying WEB-INF/classes from "+web_inf_classes+" to "+webInfClassesDir.getAbsolutePath()); + web_inf_classes.copyTo(webInfClassesDir); + } - web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath()); + web_inf=Resource.newResource(extractedWebInfDir.getCanonicalPath()); - ResourceCollection rc = new ResourceCollection(web_inf,web_app); + ResourceCollection rc = new ResourceCollection(web_inf,web_app); - if (LOG.isDebugEnabled()) - LOG.debug("context.resourcebase = "+rc); + if (LOG.isDebugEnabled()) + LOG.debug("context.resourcebase = "+rc); - context.setBaseResource(rc); - } + context.setBaseResource(rc); } } diff --git a/pom.xml b/pom.xml index 24f8b0bf93c..45430ba41e8 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ Jetty :: Project ${jetty.url} pom + UTF-8 http://www.eclipse.org/jetty