diff --git a/VERSION.txt b/VERSION.txt index ac016b9565b..108f8339dbe 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -13,6 +13,7 @@ jetty-7.2.1-SNAPSHOT + 329180 Spin check for Selector to stop + 329410 Enforce XmlConfiguration properties as Map + 329642 Concurrent modification exception in Deployment Manager + + 329643 Improved deployment of resource collections + JETTY-748 Prevent race close of socket by old acceptor threads + JETTY-1291 Extract query parameters even if POST content consumed + JETTY-1295 Contexts mixed up when hot-deploying on virtual hosts diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java index 25f1eae3d3f..1f0393753ac 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceCache.java @@ -46,27 +46,33 @@ public class ResourceCache private final ConcurrentMap _cache; private final AtomicInteger _cachedSize; private final AtomicInteger _cachedFiles; - private final boolean _useFileMappedBuffer; private final ResourceFactory _factory; private final ResourceCache _parent; - private final MimeTypes _mimeTypes; + + private boolean _useFileMappedBuffer=true; private int _maxCachedFileSize =4*1024*1024; private int _maxCachedFiles=2048; private int _maxCacheSize =32*1024*1024; + /* ------------------------------------------------------------ */ + public ResourceCache(ResourceCache parent, ResourceFactory factory, MimeTypes mimeTypes,boolean useFileMappedBuffer) + { + this(parent,factory,mimeTypes); + setUseFileMappedBuffer(useFileMappedBuffer); + } + /* ------------------------------------------------------------ */ /** Constructor. * @param mimeTypes Mimetype to use for meta data * @param fileMappedBuffers True if file mapped buffers can be used for DirectBuffers */ - public ResourceCache(ResourceCache parent, ResourceFactory factory, MimeTypes mimeTypes,boolean fileMappedBuffers) + public ResourceCache(ResourceCache parent, ResourceFactory factory, MimeTypes mimeTypes) { _factory = factory; _cache=new ConcurrentHashMap(); _cachedSize=new AtomicInteger(); _cachedFiles=new AtomicInteger(); - _useFileMappedBuffer=fileMappedBuffers; _mimeTypes=mimeTypes; _parent=parent; } @@ -127,7 +133,19 @@ public class ResourceCache _maxCachedFiles = maxCachedFiles; shrinkCache(); } - + + /* ------------------------------------------------------------ */ + public boolean isUseFileMappedBuffer() + { + return _useFileMappedBuffer; + } + + /* ------------------------------------------------------------ */ + public void setUseFileMappedBuffer(boolean useFileMappedBuffer) + { + _useFileMappedBuffer = useFileMappedBuffer; + } + /* ------------------------------------------------------------ */ public void flushCache() { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java index 7ecdc28222a..3f1fb6af76d 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java @@ -146,7 +146,7 @@ public class Scanner /* ------------------------------------------------------------ */ /** * @param recursive True if scanning is recursive - * @deprecated Use {@link #setScanDepth()} + * @see #setScanDepth() */ public void setRecursive (boolean recursive) { @@ -155,8 +155,8 @@ public class Scanner /* ------------------------------------------------------------ */ /** - * @return True if scanning is fully recursive - * @deprecated Use {@link #getScanDepth()} + * @return True if scanning is fully recursive (scandepth==-1) + * @see #getScanDepth() */ public boolean getRecursive () { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java index 8d55ee2f3fe..9407f2444b7 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java @@ -22,6 +22,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.StringTokenizer; import org.eclipse.jetty.util.URIUtil; @@ -38,49 +39,25 @@ import org.eclipse.jetty.util.URIUtil; */ public class ResourceCollection extends Resource { - - private Resource[] _resources; - - public ResourceCollection() - { - - } - + private final Resource[] _resources; + /* ------------------------------------------------------------ */ - public ResourceCollection(Resource[] resources) + public ResourceCollection(Resource... resources) { - setResources(resources); - } - - /* ------------------------------------------------------------ */ - public ResourceCollection(String[] resources) - { - setResources(resources); - } - - /* ------------------------------------------------------------ */ - public ResourceCollection(String csvResources) - { - setResources(csvResources); - } - - /* ------------------------------------------------------------ */ - /** - * - * @param resources Resource array - */ - public void setResources(Resource[] resources) - { - if(_resources!=null) - throw new IllegalStateException("*resources* already set."); - - if(resources==null) - throw new IllegalArgumentException("*resources* must not be null."); - - if(resources.length==0) - throw new IllegalArgumentException("arg *resources* must be one or more resources."); - - _resources = resources; + List list = new ArrayList(); + for (Resource r : resources) + { + if (r==null) + continue; + if (r instanceof ResourceCollection) + { + for (Resource r2 : ((ResourceCollection)r).getResources()) + list.add(r2); + } + else + list.add(r); + } + _resources = list.toArray(new Resource[list.size()]); for(Resource r : _resources) { if(!r.exists() || !r.isDirectory()) @@ -88,22 +65,10 @@ public class ResourceCollection extends Resource } } + /* ------------------------------------------------------------ */ - /** - * - * @param resources String array - */ - public void setResources(String[] resources) + public ResourceCollection(String[] resources) { - if(_resources!=null) - throw new IllegalStateException("*resources* already set."); - - if(resources==null) - throw new IllegalArgumentException("*resources* must not be null."); - - if(resources.length==0) - throw new IllegalArgumentException("arg *resources* must be one or more resources."); - _resources = new Resource[resources.length]; try { @@ -125,18 +90,8 @@ public class ResourceCollection extends Resource } /* ------------------------------------------------------------ */ - /** - * - * @param csvResources Comma separated values - */ - public void setResources(String csvResources) + public ResourceCollection(String csvResources) { - if(_resources!=null) - throw new IllegalStateException("*resources* already set."); - - if(csvResources==null) - throw new IllegalArgumentException("*csvResources* must not be null."); - StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;"); int len = tokenizer.countTokens(); if(len==0) @@ -158,15 +113,6 @@ public class ResourceCollection extends Resource } } - /* ------------------------------------------------------------ */ - /** - * - * @param csvResources Comma separated values - */ - public void setResourcesAsCSV(String csvResources) - { - setResources(csvResources); - } /* ------------------------------------------------------------ */ /** diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 4f311c99084..d1eeff8a471 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -124,6 +124,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL private boolean _distributable=false; private boolean _extractWAR=true; private boolean _copyDir=false; + private boolean _copyWebInf=true; // TODO change to false? private boolean _logUrlOnStart =false; private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority"); private PermissionCollection _permissions; @@ -754,13 +755,22 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL /* ------------------------------------------------------------ */ /** - * @return True if the webdir is copied (to allow hot replacement of jars) + * @return True if the webdir is copied (to allow hot replacement of jars on windows) */ public boolean isCopyWebDir() { return _copyDir; } - + + /* ------------------------------------------------------------ */ + /** + * @return True if the web-inf lib and classes directories are copied (to allow hot replacement of jars on windows) + */ + public boolean isCopyWebInf() + { + return _copyWebInf; + } + /* ------------------------------------------------------------ */ /** * @return True if the classloader should delegate first to the parent @@ -960,7 +970,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL /* ------------------------------------------------------------ */ /** - * * @param copy True if the webdir is copied (to allow hot replacement of jars) */ public void setCopyWebDir(boolean copy) @@ -968,6 +977,15 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL _copyDir = copy; } + /* ------------------------------------------------------------ */ + /** + * @param copyWebInf True if the web-inf lib and classes directories are copied (to allow hot replacement of jars on windows) + */ + public void setCopyWebInf(boolean copyWebInf) + { + _copyWebInf = copyWebInf; + } + /* ------------------------------------------------------------ */ /** * @param java2compliant The java2compliant to set. 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 485dc12b290..714496cfd42 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 @@ -478,54 +478,57 @@ public class WebInfConfiguration extends AbstractConfiguration } - + // Do we need to extract WEB-INF/lib? - 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(); - - if (web_inf_lib.exists()) - { - File webInfLibDir = new File(webInfDir, "lib"); - if (webInfLibDir.exists()) - IO.delete(webInfLibDir); - webInfLibDir.mkdir(); + if (context.isCopyWebInf()) + { + Resource web_inf= web_app.addPath("WEB-INF/"); - Log.info("Copying WEB-INF/lib " + web_inf_lib + " to " + webInfLibDir); - web_inf_lib.copyTo(webInfLibDir); - } + 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(); - 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()); - - ResourceCollection rc = new ResourceCollection(new Resource[]{web_inf,web_app}); - - if (Log.isDebugEnabled()) - Log.debug("context.resourcebase = "+rc); - - context.setBaseResource(rc); - } + 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); + } + + 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()); + + ResourceCollection rc = new ResourceCollection(web_inf,web_app); + + if (Log.isDebugEnabled()) + Log.debug("context.resourcebase = "+rc); + + context.setBaseResource(rc); + } + } }