298667 various deployer improvements

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1174 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Greg Wilkins 2009-12-31 03:02:16 +00:00
parent 8e19d18057
commit 52fc378b93
16 changed files with 418 additions and 88 deletions

View File

@ -7,7 +7,7 @@ jetty-7.0.2-SNAPSHOT
+ 298144 Unit test for jetty-client connecting to a server that uses Basic Auth + 298144 Unit test for jetty-client connecting to a server that uses Basic Auth
+ 298145 Reorganized test harness to separate the HTTP PUT and HTTP GET test URLs + 298145 Reorganized test harness to separate the HTTP PUT and HTTP GET test URLs
+ 298234 Unit test for jetty-client handling different HTTP error codes + 298234 Unit test for jetty-client handling different HTTP error codes
+ 298667 DeploymentManager providers create ContextHandlers + 298667 DeploymentManager uses ContextProvider and WebAppProvider
+ JETTY-910 Allow request listeners to access session + JETTY-910 Allow request listeners to access session
+ JETTY-1155 HttpConnection.close notifies HttpExchange + JETTY-1155 HttpConnection.close notifies HttpExchange
+ JETTY-1156 SSL blocking close with JVM Bug busy key fix + JETTY-1156 SSL blocking close with JVM Bug busy key fix

View File

@ -18,7 +18,7 @@ import java.lang.management.ManagementFactory;
import org.eclipse.jetty.deploy.ContextDeployer; import org.eclipse.jetty.deploy.ContextDeployer;
import org.eclipse.jetty.deploy.DeploymentManager; import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.WebAppDeployer; import org.eclipse.jetty.deploy.WebAppDeployer;
import org.eclipse.jetty.deploy.providers.ContextAppProvider; import org.eclipse.jetty.deploy.providers.ContextProvider;
import org.eclipse.jetty.deploy.providers.WebAppProvider; import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.security.HashLoginService;
@ -85,9 +85,9 @@ public class LikeJettyXml
deployer.setContexts(contexts); deployer.setContexts(contexts);
server.addBean(deployer); server.addBean(deployer);
ContextAppProvider context_provider = new ContextAppProvider(); ContextProvider context_provider = new ContextProvider();
context_provider.setMonitoredDir(jetty_home + "/contexts"); context_provider.setMonitoredDir(jetty_home + "/contexts");
context_provider.setScanInterval(5); context_provider.setScanInterval(2);
server.addBean(context_provider); server.addBean(context_provider);
deployer.addAppProvider(context_provider); deployer.addAppProvider(context_provider);
@ -95,7 +95,9 @@ public class LikeJettyXml
webapp_provider.setMonitoredDir(jetty_home + "/webapps"); webapp_provider.setMonitoredDir(jetty_home + "/webapps");
webapp_provider.setParentLoaderPriority(false); webapp_provider.setParentLoaderPriority(false);
webapp_provider.setExtractWars(true); webapp_provider.setExtractWars(true);
webapp_provider.setScanInterval(2);
webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml"); webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
webapp_provider.setContextXmlDir(jetty_home + "/contexts");
deployer.addAppProvider(webapp_provider); deployer.addAppProvider(webapp_provider);
HashLoginService login = new HashLoginService(); HashLoginService login = new HashLoginService();

View File

@ -62,14 +62,16 @@ public class AppLifeCycle extends Graph
void processBinding(Node node, App app) throws Exception; void processBinding(Node node, App app) throws Exception;
} }
// Private string constants defined to avoid typos on repeatedly used strings // Well known existing lifecycle Nodes
private static final String NODE_UNDEPLOYED = "undeployed"; public static final String UNDEPLOYED = "undeployed";
private static final String NODE_DEPLOYING = "deploying"; public static final String DEPLOYING = "deploying";
private static final String NODE_DEPLOYED = "deployed"; public static final String DEPLOYED = "deployed";
private static final String NODE_STARTING = "starting"; public static final String STARTING = "starting";
private static final String NODE_STARTED = "started"; public static final String STARTED = "started";
private static final String NODE_STOPPING = "stopping"; public static final String STOPPING = "stopping";
private static final String NODE_UNDEPLOYING = "undeploying"; public static final String UNDEPLOYING = "undeploying";
private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>(); private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
public AppLifeCycle() public AppLifeCycle()
@ -77,20 +79,20 @@ public class AppLifeCycle extends Graph
// Define Default Graph // Define Default Graph
// undeployed -> deployed // undeployed -> deployed
addEdge(NODE_UNDEPLOYED,NODE_DEPLOYING); addEdge(UNDEPLOYED,DEPLOYING);
addEdge(NODE_DEPLOYING,NODE_DEPLOYED); addEdge(DEPLOYING,DEPLOYED);
// deployed -> started // deployed -> started
addEdge(NODE_DEPLOYED,NODE_STARTING); addEdge(DEPLOYED,STARTING);
addEdge(NODE_STARTING,NODE_STARTED); addEdge(STARTING,STARTED);
// started -> deployed // started -> deployed
addEdge(NODE_STARTED,NODE_STOPPING); addEdge(STARTED,STOPPING);
addEdge(NODE_STOPPING,NODE_DEPLOYED); addEdge(STOPPING,DEPLOYED);
// deployed -> undeployed // deployed -> undeployed
addEdge(NODE_DEPLOYED,NODE_UNDEPLOYING); addEdge(DEPLOYED,UNDEPLOYING);
addEdge(NODE_UNDEPLOYING,NODE_UNDEPLOYED); addEdge(UNDEPLOYING,UNDEPLOYED);
} }
public void addBinding(AppLifeCycle.Binding binding) public void addBinding(AppLifeCycle.Binding binding)
@ -107,6 +109,16 @@ public class AppLifeCycle extends Graph
lifecyclebindings.put(nodeName,bindings); lifecyclebindings.put(nodeName,bindings);
} }
} }
public void removeBinding(AppLifeCycle.Binding binding)
{
for (String nodeName : binding.getBindingTargets())
{
List<Binding> bindings = lifecyclebindings.get(nodeName);
if (bindings != null)
bindings.remove(binding);
}
}
/** /**
* Get all {@link Node} bound objects. * Get all {@link Node} bound objects.

View File

@ -22,5 +22,5 @@ import java.util.Map;
*/ */
public interface ConfigurationManager public interface ConfigurationManager
{ {
public Map<?, ?> getProperties(); public Map<String, ?> getProperties();
} }

View File

@ -17,12 +17,14 @@ package org.eclipse.jetty.deploy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.deploy.bindings.StandardDeployer; import org.eclipse.jetty.deploy.bindings.StandardDeployer;
import org.eclipse.jetty.deploy.bindings.StandardStarter; import org.eclipse.jetty.deploy.bindings.StandardStarter;
@ -113,7 +115,7 @@ public class DeploymentManager extends AbstractLifeCycle
private AttributesMap _contextAttributes = new AttributesMap(); private AttributesMap _contextAttributes = new AttributesMap();
private ContextHandlerCollection _contexts; private ContextHandlerCollection _contexts;
private boolean _useStandardBindings = true; private boolean _useStandardBindings = true;
private String _defaultLifeCycleGoal = "started"; private String _defaultLifeCycleGoal = AppLifeCycle.STARTED;
/** /**
* Receive an app for processing. * Receive an app for processing.
@ -128,22 +130,51 @@ public class DeploymentManager extends AbstractLifeCycle
entry.setLifeCycleNode(_lifecycle.getNodeByName("undeployed")); entry.setLifeCycleNode(_lifecycle.getNodeByName("undeployed"));
_apps.add(entry); _apps.add(entry);
if (_defaultLifeCycleGoal != null) if (isRunning() && _defaultLifeCycleGoal != null)
{ {
// Immediately attempt to go to default lifecycle state // Immediately attempt to go to default lifecycle state
this.requestAppGoal(entry,_defaultLifeCycleGoal); this.requestAppGoal(entry,_defaultLifeCycleGoal);
} }
} }
public void addAppProvider(AppProvider provider) public void setAppProviders(Collection<AppProvider> providers)
{ {
_providers.add(provider); if (isRunning())
if (isStarted() || isStarting()) throw new IllegalStateException();
{
startAppProvider(provider); _providers.clear();
} for (AppProvider provider:providers)
_providers.add(provider);
} }
public Collection<AppProvider> getAppProviders()
{
return Collections.unmodifiableList(_providers);
}
public void addAppProvider(AppProvider provider)
{
if (isRunning())
throw new IllegalStateException();
_providers.add(provider);
}
public void setLifeCycleBindings(Collection<AppLifeCycle.Binding> bindings)
{
if (isRunning())
throw new IllegalStateException();
for (AppLifeCycle.Binding b : _lifecycle.getBindings())
_lifecycle.removeBinding(b);
for (AppLifeCycle.Binding b : bindings)
_lifecycle.addBinding(b);
}
public Collection<AppLifeCycle.Binding> getLifeCycleBindings()
{
return Collections.unmodifiableSet(_lifecycle.getBindings());
}
public void addLifeCycleBinding(AppLifeCycle.Binding binding) public void addLifeCycleBinding(AppLifeCycle.Binding binding)
{ {
_lifecycle.addBinding(binding); _lifecycle.addBinding(binding);
@ -261,11 +292,6 @@ public class DeploymentManager extends AbstractLifeCycle
return _apps; return _apps;
} }
public Collection<AppProvider> getAppProviders()
{
return _providers;
}
public Collection<App> getApps() public Collection<App> getApps()
{ {
List<App> ret = new ArrayList<App>(); List<App> ret = new ArrayList<App>();
@ -380,8 +406,10 @@ public class DeploymentManager extends AbstractLifeCycle
while (it.hasNext()) while (it.hasNext())
{ {
AppEntry entry = it.next(); AppEntry entry = it.next();
if (entry.app.equals(app) && "undeployed".equals(entry.lifecyleNode.getName())) if (entry.app.equals(app))
{ {
if (! AppLifeCycle.UNDEPLOYED.equals(entry.lifecyleNode.getName()))
requestAppGoal(entry.app,AppLifeCycle.UNDEPLOYED);
it.remove(); it.remove();
Log.info("Deployable removed: " + entry.app); Log.info("Deployable removed: " + entry.app);
} }

View File

@ -16,6 +16,7 @@ package org.eclipse.jetty.deploy;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -29,7 +30,7 @@ import org.eclipse.jetty.util.resource.Resource;
public class FileConfigurationManager implements ConfigurationManager public class FileConfigurationManager implements ConfigurationManager
{ {
private Resource _file; private Resource _file;
private Properties _properties = new Properties(); private Map<String,Object> _map = new HashMap<String,Object>();
public FileConfigurationManager() public FileConfigurationManager()
{ {
@ -43,12 +44,12 @@ public class FileConfigurationManager implements ConfigurationManager
/** /**
* @see org.eclipse.jetty.deploy.ConfigurationManager#getProperties() * @see org.eclipse.jetty.deploy.ConfigurationManager#getProperties()
*/ */
public Map<?, ?> getProperties() public Map<String, ?> getProperties()
{ {
try try
{ {
loadProperties(); loadProperties();
return _properties; return _map;
} }
catch (Exception e) catch (Exception e)
{ {
@ -58,7 +59,12 @@ public class FileConfigurationManager implements ConfigurationManager
private void loadProperties() throws FileNotFoundException, IOException private void loadProperties() throws FileNotFoundException, IOException
{ {
if (_properties.isEmpty()) if (_map.isEmpty())
_properties.load(_file.getInputStream()); {
Properties properties = new Properties();
properties.load(_file.getInputStream());
for (Map.Entry<Object, Object> entry : properties.entrySet())
_map.put(entry.getKey().toString(),entry.getValue());
}
} }
} }

View File

@ -38,8 +38,6 @@ public class StandardUndeployer implements AppLifeCycle.Binding
ContextHandlerCollection chcoll = app.getDeploymentManager().getContexts(); ContextHandlerCollection chcoll = app.getDeploymentManager().getContexts();
recursiveRemoveContext(chcoll,handler); recursiveRemoveContext(chcoll,handler);
app.getDeploymentManager().removeApp(app);
} }
private void recursiveRemoveContext(HandlerCollection coll, ContextHandler context) private void recursiveRemoveContext(HandlerCollection coll, ContextHandler context)

View File

@ -1,21 +0,0 @@
package org.eclipse.jetty.deploy.providers;
import org.eclipse.jetty.deploy.ContextDeployer;
/* ------------------------------------------------------------ */
/** Context directory App Provider.
* <p>This specialisation of {@link MonitoredDirAppProvider} is the
* replacement for {@link ContextDeployer} and it will scan a directory
* only for context.xml files.
* @see ContextDeployer
*/
public class ContextAppProvider extends MonitoredDirAppProvider
{
public ContextAppProvider()
{
super(true,false,false);
setRecursive(false);
}
}

View File

@ -0,0 +1,76 @@
package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.ContextDeployer;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.xml.XmlConfiguration;
/* ------------------------------------------------------------ */
/** Context directory App Provider.
* <p>This specialisation of {@link MonitoredDirAppProvider} is the
* replacement for {@link ContextDeployer} and it will scan a directory
* only for context.xml files.
* @see ContextDeployer
*/
public class ContextProvider extends AbstractAppProvider
{
private ConfigurationManager _configurationManager;
public ContextProvider()
{
super( new FilenameFilter()
{
public boolean accept(File dir, String name)
{
if (!dir.exists())
return false;
String lowername = name.toLowerCase();
return (lowername.endsWith(".xml") && !new File(dir,name).isDirectory());
}
});
}
/* ------------------------------------------------------------ */
public ConfigurationManager getConfigurationManager()
{
return _configurationManager;
}
/* ------------------------------------------------------------ */
/** Set the configurationManager.
* @param configurationManager the configurationManager to set
*/
public void setConfigurationManager(ConfigurationManager configurationManager)
{
_configurationManager = configurationManager;
}
/* ------------------------------------------------------------ */
public ContextHandler createContextHandler(App app) throws Exception
{
Resource resource = Resource.newResource(app.getArchivePath().toURI());
if (resource.exists() && FileID.isXmlFile(app.getArchivePath()))
{
XmlConfiguration xmlc = new XmlConfiguration(resource.getURL());
Map<String,Object> props = new HashMap<String,Object>();
props.put("Server",getDeploymentManager().getServer());
if (getConfigurationManager() != null)
props.putAll(getConfigurationManager().getProperties());
xmlc.setProperties(props);
return (ContextHandler)xmlc.configure();
}
throw new IllegalStateException("App resouce does not exist "+resource);
}
}

View File

@ -41,6 +41,7 @@ import org.eclipse.jetty.xml.XmlConfiguration;
* *
* A Context may either be a WAR, a directory or an XML descriptor. * A Context may either be a WAR, a directory or an XML descriptor.
* *
* @deprecated - Use {@link ContextProvider} or {@link WebAppProvider}
*/ */
public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider
{ {

View File

@ -1,7 +1,21 @@
package org.eclipse.jetty.deploy.providers; package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.ConfigurationManager; import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.WebAppDeployer; import org.eclipse.jetty.deploy.WebAppDeployer;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -11,25 +25,190 @@ import org.eclipse.jetty.deploy.WebAppDeployer;
* only for warfiles or directories files. * only for warfiles or directories files.
* @see WebAppDeployer * @see WebAppDeployer
*/ */
public class WebAppProvider extends MonitoredDirAppProvider public class WebAppProvider extends AbstractAppProvider
{ {
private boolean _extractWars = false;
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
private Filter _filter;
private static class Filter implements FilenameFilter
{
private File _contexts;
public boolean accept(File dir, String name)
{
if (!dir.exists())
return false;
String lowername = name.toLowerCase();
File file = new File(dir,name);
// is it not a directory and not a war ?
if (!file.isDirectory() && !lowername.endsWith(".war"))
return false;
// is it a directory for an existing war file?
if (file.isDirectory() &&
(new File(dir,name+".war").exists() ||
new File(dir,name+".WAR").exists()))
{
return false;
}
// is there a contexts config file
if (_contexts!=null)
{
String context=name;
if (!file.isDirectory())
context=context.substring(0,context.length()-4);
if (new File(_contexts,context+".xml").exists() ||
new File(_contexts,context+".XML").exists() )
{
return false;
}
}
return true;
}
}
/* ------------------------------------------------------------ */
public WebAppProvider() public WebAppProvider()
{ {
super(false,true,true); super(new Filter());
setRecursive(false); _filter=(Filter)_filenameFilter;
setScanInterval(0); setScanInterval(0);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /** Get the extractWars.
* Configuration Managers are not supported for WebAppProvider, so this * @return the extractWars
* methods throws an {@link UnsupportedOperationException}.
*/ */
@Override public boolean isExtractWars()
public void setConfigurationManager(ConfigurationManager configurationManager)
{ {
throw new UnsupportedOperationException(); return _extractWars;
}
/* ------------------------------------------------------------ */
/** Set the extractWars.
* @param extractWars the extractWars to set
*/
public void setExtractWars(boolean extractWars)
{
_extractWars = extractWars;
}
/* ------------------------------------------------------------ */
/** Get the parentLoaderPriority.
* @return the parentLoaderPriority
*/
public boolean isParentLoaderPriority()
{
return _parentLoaderPriority;
}
/* ------------------------------------------------------------ */
/** Set the parentLoaderPriority.
* @param parentLoaderPriority the parentLoaderPriority to set
*/
public void setParentLoaderPriority(boolean parentLoaderPriority)
{
_parentLoaderPriority = parentLoaderPriority;
}
/* ------------------------------------------------------------ */
/** Get the defaultsDescriptor.
* @return the defaultsDescriptor
*/
public String getDefaultsDescriptor()
{
return _defaultsDescriptor;
}
/* ------------------------------------------------------------ */
/** Set the defaultsDescriptor.
* @param defaultsDescriptor the defaultsDescriptor to set
*/
public void setDefaultsDescriptor(String defaultsDescriptor)
{
_defaultsDescriptor = defaultsDescriptor;
}
/* ------------------------------------------------------------ */
public String getContextXmlDir()
{
return _filter._contexts==null?null:_filter._contexts.toString();
}
/* ------------------------------------------------------------ */
/**
* Set the directory in which to look for context XML files.
* <p>
* If a webapp call "foo/" or "foo.war" is discovered in the monitored
* directory, then the ContextXmlDir is examined to see if a foo.xml
* file exists. If it does, then this deployer will not deploy the webapp
* and the ContextProvider should be used to act on the foo.xml file.
* @see ContextProvider
* @param contextsDir
*/
public void setContextXmlDir(String contextsDir)
{
try
{
_filter._contexts=Resource.newResource(contextsDir).getFile();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
} }
/* ------------------------------------------------------------ */
public ContextHandler createContextHandler(final App app) throws Exception
{
Resource resource = Resource.newResource(app.getArchivePath().toURI());
if (!resource.exists())
throw new IllegalStateException("App resouce does not exist "+resource);
String context = app.getArchivePath().getName();
if (app.getArchivePath().isDirectory())
{
// must be a directory
}
else if (FileID.isWebArchiveFile(app.getArchivePath()))
{
// Context Path is the same as the archive.
context = context.substring(0,context.length() - 4);
}
else
throw new IllegalStateException("unable to create ContextHandler for "+app);
// special case of archive (or dir) named "root" is / context
if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
context = URIUtil.SLASH;
// Ensure "/" is Prepended to all context paths.
if (context.charAt(0) != '/')
context = "/" + context;
// Ensure "/" is Not Trailing in context paths.
if (context.endsWith("/") && context.length() > 0)
context = context.substring(0,context.length() - 1);
WebAppContext wah = new WebAppContext();
wah.setContextPath(context);
wah.setWar(app.getArchivePath().getAbsolutePath());
if (_defaultsDescriptor != null)
wah.setDefaultsDescriptor(_defaultsDescriptor);
wah.setExtractWAR(_extractWars);
wah.setParentLoaderPriority(_parentLoaderPriority);
return wah;
}
} }

View File

@ -11,14 +11,12 @@
</Set> </Set>
<!-- Providers of Apps --> <!-- Providers of Apps -->
<Call name="addAppProvider"> <Set name="appProviders">
<Arg> <Array type="org.eclipse.jetty.deploy.AppProvider">
<New class="org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider"> <Item>
<Set name="monitoredDir"> <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
<Property name="jetty.home" />/contexts <Set name="monitoredDir"><Property name="jetty.home" />/contexts</Set>
</Set>
<Set name="scanInterval">1</Set> <Set name="scanInterval">1</Set>
<Set name="recursive">true</Set>
<Set name="configurationManager"> <Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager"> <New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file"> <Set name="file">
@ -26,9 +24,17 @@
</Set> </Set>
</New> </New>
</Set> </Set>
</New> </New>
</Arg> </Item>
</Call> <Item>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDir"><Property name="jetty.home" />/webapps</Set>
<Set name="scanInterval">1</Set>
<Set name="contextXmlDir"><Property name="jetty.home" />/contexts</Set>
</New>
</Item>
</Array>
</Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>

View File

@ -129,6 +129,7 @@
<Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set> <Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set> <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">5</Set> <Set name="scanInterval">5</Set>
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>

View File

@ -248,7 +248,6 @@ public class Server extends HandlerWrapper implements Attributes
if (Log.isDebugEnabled()) if (Log.isDebugEnabled())
Log.debug(dump()); Log.debug(dump());
System.err.println(dump());
mex.ifExceptionThrow(); mex.ifExceptionThrow();
} }

View File

@ -398,8 +398,21 @@ public class WebInfConfiguration implements Configuration
!web_app.isDirectory()) !web_app.isDirectory())
) )
{ {
// Then extract it if necessary to the temporary location // Look for sibling directory.
File extractedWebAppDir= new File(context.getTempDirectory(), "webapp"); File extractedWebAppDir = null;
if (war!=null)
{
// look for a sibling like "foo/" to a "foo.war"
File warfile=Resource.newResource(war).getFile();
File sibling = new File(warfile.getParent(),warfile.getName().substring(0,warfile.getName().length()-4));
if (sibling.exists() && sibling.isDirectory() && sibling.canWrite())
extractedWebAppDir=sibling;
}
if (extractedWebAppDir==null)
// Then extract it if necessary to the temporary location
extractedWebAppDir= new File(context.getTempDirectory(), "webapp");
if (web_app.getFile()!=null && web_app.getFile().isDirectory()) if (web_app.getFile()!=null && web_app.getFile().isDirectory())
{ {
@ -439,7 +452,6 @@ public class WebInfConfiguration implements Configuration
Log.warn("Web application not found " + war); Log.warn("Web application not found " + war);
throw new java.io.FileNotFoundException(war); throw new java.io.FileNotFoundException(war);
} }
context.setBaseResource(web_app); context.setBaseResource(web_app);

View File

@ -28,10 +28,16 @@ import java.net.UnknownHostException;
import java.security.AccessControlException; import java.security.AccessControlException;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.Loader;
@ -343,7 +349,7 @@ public class XmlConfiguration
{ {
Log.ignore(e); Log.ignore(e);
} }
// Try a field // Try a field
try try
{ {
@ -364,8 +370,11 @@ public class XmlConfiguration
Method set = null; Method set = null;
for (int s = 0; sets != null && s < sets.length; s++) for (int s = 0; sets != null && s < sets.length; s++)
{ {
if (name.equals(sets[s].getName()) && sets[s].getParameterTypes().length == 1)
Class<?>[] paramTypes= sets[s].getParameterTypes();
if (name.equals(sets[s].getName()) && paramTypes.length == 1)
{ {
// lets try it // lets try it
try try
{ {
@ -381,6 +390,28 @@ public class XmlConfiguration
{ {
Log.ignore(e); Log.ignore(e);
} }
// Can we convert to a collection
if (paramTypes[0].isAssignableFrom(Collection.class) && value.getClass().isArray())
{
try
{
if (paramTypes[0].isAssignableFrom(Set.class))
sets[s].invoke(obj, new Object[]{new HashSet<Object>(Arrays.asList((Object[])value))});
else
sets[s].invoke(obj, new Object[]{Arrays.asList((Object[])value)});
return;
}
catch (IllegalArgumentException e)
{
Log.ignore(e);
}
catch (IllegalAccessException e)
{
Log.ignore(e);
}
}
} }
} }