diff --git a/VERSION.txt b/VERSION.txt index 2538202d258..cc855256cf1 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,5 @@ jetty-7.2-SNAPSHOT + + 319334 Concurrent, sharable ResourceCache jetty-7.1.5.v20100705 + Update ecj to 3.6 Helios release drop diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java index 72813f0d216..32675308efe 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ContentExchangeTest.java @@ -157,7 +157,7 @@ public class ContentExchangeTest getExchange.setMethod(HttpMethods.HEAD); _client.send(getExchange); - int state = getExchange.waitForDone(); + getExchange.waitForDone(); int responseStatus = getExchange.getResponseStatus(); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java index 3ec2d764cb4..d997cde77cb 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpExchangeTest.java @@ -534,7 +534,6 @@ public class HttpExchangeTest extends TestCase } catch(InterruptedException e) { - System.err.println(e); Log.debug(e); } catch(IOException e) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java index 5469ec072a0..be468fb4800 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SecuredErrorStatusTest.java @@ -17,7 +17,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.eclipse.jetty.client.ContentExchangeTest.TestHandler; import org.eclipse.jetty.client.security.Realm; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.security.Constraint; @@ -40,6 +39,7 @@ public class SecuredErrorStatusTest private Realm _testRealm; private Realm _dummyRealm; + @Override public void testPutUnauthorized() throws Exception { @@ -60,6 +60,7 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + @Override public void testGetUnauthorized() throws Exception { @@ -80,6 +81,7 @@ public class SecuredErrorStatusTest setRealm(_testRealm); } + @Override protected void configureServer(Server server) throws Exception { diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java index 93e1e4c1505..7c7025ff815 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpContent.java @@ -28,7 +28,8 @@ public interface HttpContent { Buffer getContentType(); Buffer getLastModified(); - Buffer getBuffer(); + Buffer getIndirectBuffer(); + Buffer getDirectBuffer(); Resource getResource(); long getContentLength(); InputStream getInputStream() throws IOException; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 2111104039b..c8fee4f8f9b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -46,6 +46,8 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.io.UncheckedPrintWriter; +import org.eclipse.jetty.server.nio.NIOConnector; +import org.eclipse.jetty.server.ssl.SslConnector; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; @@ -1162,10 +1164,11 @@ public class HttpConnection implements Connection if (super._generator.getContentWritten() > 0) throw new IllegalStateException("!empty"); + // Convert HTTP content to contentl if (content instanceof HttpContent) { - HttpContent c = (HttpContent) content; - Buffer contentType = c.getContentType(); + HttpContent httpContent = (HttpContent) content; + Buffer contentType = httpContent.getContentType(); if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER)) { String enc = _response.getSetCharacterEncoding(); @@ -1191,21 +1194,22 @@ public class HttpConnection implements Connection } } } - if (c.getContentLength() > 0) - _responseFields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER, c.getContentLength()); - Buffer lm = c.getLastModified(); - long lml=c.getResource().lastModified(); + if (httpContent.getContentLength() > 0) + _responseFields.putLongField(HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength()); + Buffer lm = httpContent.getLastModified(); + long lml=httpContent.getResource().lastModified(); if (lm != null) _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm,lml); - else if (c.getResource()!=null) + else if (httpContent.getResource()!=null) { if (lml!=-1) _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml); } - content = c.getBuffer(); + boolean direct=_connector instanceof NIOConnector && ((NIOConnector)_connector).getUseDirectBuffers() && !(_connector instanceof SslConnector); + content = direct?httpContent.getDirectBuffer():httpContent.getIndirectBuffer(); if (content==null) - content=c.getInputStream(); + content=httpContent.getInputStream(); } else if (content instanceof Resource) { @@ -1214,7 +1218,7 @@ public class HttpConnection implements Connection content=resource.getInputStream(); } - + // Process content. if (content instanceof Buffer) { super._generator.addContent((Buffer) content, Generator.LAST); 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 2431198a1a3..5510f0068e0 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 @@ -13,11 +13,16 @@ package org.eclipse.jetty.server; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.Comparator; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.http.HttpContent; import org.eclipse.jetty.http.HttpFields; @@ -25,7 +30,9 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.ByteArrayBuffer; import org.eclipse.jetty.io.View; -import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.io.nio.DirectNIOBuffer; +import org.eclipse.jetty.io.nio.IndirectNIOBuffer; +import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; @@ -34,38 +41,44 @@ import org.eclipse.jetty.util.resource.ResourceFactory; /** * */ -public class ResourceCache extends AbstractLifeCycle +public class ResourceCache { - protected final Map _cache; + private final ConcurrentMap _cache; + private final AtomicInteger _cachedSize; + private final AtomicInteger _cachedFiles; + private final boolean _useFileMappedBuffer; + private final ResourceFactory _factory; + private final MimeTypes _mimeTypes; private int _maxCachedFileSize =1024*1024; private int _maxCachedFiles=2048; - private int _maxCacheSize =16*1024*1024; - - protected int _cachedSize; - protected int _cachedFiles; - protected Content _mostRecentlyUsed; - protected Content _leastRecentlyUsed; + private int _maxCacheSize =32*1024*1024; /* ------------------------------------------------------------ */ /** Constructor. + * @param mimeTypes Mimetype to use for meta data + * @param fileMappedBuffers True if file mapped buffers can be used for DirectBuffers */ - public ResourceCache(MimeTypes mimeTypes) + public ResourceCache(ResourceFactory factory, MimeTypes mimeTypes,boolean fileMappedBuffers) { - _cache=new HashMap(); + _factory = factory; + _cache=new ConcurrentHashMap(); + _cachedSize=new AtomicInteger(); + _cachedFiles=new AtomicInteger(); + _useFileMappedBuffer=fileMappedBuffers; _mimeTypes=mimeTypes; } /* ------------------------------------------------------------ */ public int getCachedSize() { - return _cachedSize; + return _cachedSize.get(); } /* ------------------------------------------------------------ */ public int getCachedFiles() { - return _cachedFiles; + return _cachedFiles.get(); } @@ -79,7 +92,7 @@ public class ResourceCache extends AbstractLifeCycle public void setMaxCachedFileSize(int maxCachedFileSize) { _maxCachedFileSize = maxCachedFileSize; - flushCache(); + shrinkCache(); } /* ------------------------------------------------------------ */ @@ -92,7 +105,7 @@ public class ResourceCache extends AbstractLifeCycle public void setMaxCacheSize(int maxCacheSize) { _maxCacheSize = maxCacheSize; - flushCache(); + shrinkCache(); } /* ------------------------------------------------------------ */ @@ -111,6 +124,7 @@ public class ResourceCache extends AbstractLifeCycle public void setMaxCachedFiles(int maxCachedFiles) { _maxCachedFiles = maxCachedFiles; + shrinkCache(); } /* ------------------------------------------------------------ */ @@ -118,18 +132,14 @@ public class ResourceCache extends AbstractLifeCycle { if (_cache!=null) { - synchronized(this) + while (_cache.size()>0) { - ArrayList values=new ArrayList(_cache.values()); - for (Content content : values) - content.invalidate(); - - _cache.clear(); - - _cachedSize=0; - _cachedFiles=0; - _mostRecentlyUsed=null; - _leastRecentlyUsed=null; + for (String path : _cache.keySet()) + { + Content content = _cache.remove(path); + if (content!=null) + content.invalidate(); + } } } } @@ -139,49 +149,26 @@ public class ResourceCache extends AbstractLifeCycle * Get either a valid entry object or create a new one if possible. * * @param pathInContext The key into the cache - * @param factory If no matching entry is found, this {@link ResourceFactory} will be used to create the {@link Resource} - * for the new enry that is created. * @return The entry matching pathInContext, or a new entry if no matching entry was found + * @throws IOException Problem loading the resource */ - public Content lookup(String pathInContext, ResourceFactory factory) + public Content lookup(String pathInContext) throws IOException { Content content=null; - + // Look up cache operations - synchronized(_cache) - { - // Look for it in the cache - content = (Content)_cache.get(pathInContext); + content = _cache.get(pathInContext); - if (content!=null && content.isValid()) - { - return content; - } - } - Resource resource=factory.getResource(pathInContext); - return load(pathInContext,resource); + if (content!=null && content.isValid()) + return content; + + Resource resource=_factory.getResource(pathInContext); + Content loaded = load(pathInContext,resource); + + return loaded; } - /* ------------------------------------------------------------ */ - public Content lookup(String pathInContext, Resource resource) - throws IOException - { - Content content=null; - - // Look up cache operations - synchronized(_cache) - { - // Look for it in the cache - content = (Content)_cache.get(pathInContext); - - if (content!=null && content.isValid()) - { - return content; - } - } - return load(pathInContext,resource); - } /* ------------------------------------------------------------ */ private Content load(String pathInContext, Resource resource) @@ -191,115 +178,122 @@ public class ResourceCache extends AbstractLifeCycle if (resource!=null && resource.exists() && !resource.isDirectory()) { long len = resource.length(); + + // Will it fit in the cache? if (len>0 && len<_maxCachedFileSize && len<_maxCacheSize) { - int must_be_smaller_than=_maxCacheSize-(int)len; + // Create the Content (to increment the cache sizes before adding the content + content = new Content(pathInContext,resource); - synchronized(_cache) - { - // check the cache is not full of locked content before loading content - - while(_leastRecentlyUsed!=null && (_cachedSize>must_be_smaller_than || (_maxCachedFiles>0 && _cachedFiles>=_maxCachedFiles))) - _leastRecentlyUsed.invalidate(); - - if(_cachedSize>must_be_smaller_than || (_maxCachedFiles>0 && _cachedFiles>=_maxCachedFiles)) - return null; - } + // reduce the cache to an acceptable size. + shrinkCache(); - content = new Content(resource); - fill(content); - - synchronized(_cache) + // Add it to the cache. + Content added = _cache.putIfAbsent(pathInContext,content); + if (added!=null) { - // check that somebody else did not fill this spot. - Content content2 =(Content)_cache.get(pathInContext); - if (content2!=null) - { - content.release(); - return content2; - } - - while(_leastRecentlyUsed!=null && (_cachedSize>must_be_smaller_than || (_maxCachedFiles>0 && _cachedFiles>=_maxCachedFiles))) - _leastRecentlyUsed.invalidate(); - - if(_cachedSize>must_be_smaller_than || (_maxCachedFiles>0 && _cachedFiles>=_maxCachedFiles)) - return null; // this could waste an allocated File or DirectBuffer - - content.cache(pathInContext); - - return content; + content.invalidate(); + content=added; } + return content; } } return null; } + + /* ------------------------------------------------------------ */ + private void shrinkCache() + { + // While we need to shrink + while (_cache.size()>0 && (_cachedFiles.get()>_maxCachedFiles || _cachedSize.get()>_maxCacheSize)) + { + // Scan the entire cache and generate an ordered list by last accessed time. + SortedSet sorted= new TreeSet( + new Comparator() + { + public int compare(Content c1, Content c2) + { + if (c1._lastAccessedc2._lastAccessed) + return 1; + + if (c1._length0 && _cachedFiles>=_maxCachedFiles && _leastRecentlyUsed!=null) - _leastRecentlyUsed.invalidate(); - if (_maxCachedFiles>0 && _cachedFiles>=_maxCachedFiles) - return; - - // check that somebody else did not fill this spot. - Miss miss = new Miss(resource); - Content content2 =(Content)_cache.get(pathInContext); - if (content2!=null) - { - miss.release(); - return; - } + if (_maxCachedFiles>0 && _cachedFiles.get()>=_maxCachedFiles) + return; - miss.cache(pathInContext); - } + // check that somebody else did not fill this spot. + Miss miss = new Miss(pathInContext,resource); + if (_cache.putIfAbsent(pathInContext,miss)!=null) + miss.invalidate(); } /* ------------------------------------------------------------ */ - @Override - public synchronized void doStart() - throws Exception - { - _cache.clear(); - _cachedSize=0; - _cachedFiles=0; - } - - /* ------------------------------------------------------------ */ - /** Stop the context. - */ - @Override - public void doStop() - throws InterruptedException - { - flushCache(); - } - - /* ------------------------------------------------------------ */ - protected void fill(Content content) - throws IOException + protected Buffer getIndirectBuffer(Resource resource) { try { - InputStream in = content.getResource().getInputStream(); - int len=(int)content.getResource().length(); - Buffer buffer = new ByteArrayBuffer(len); - buffer.readFrom(in,len); - in.close(); - content.setBuffer(buffer); + int len=(int)resource.length(); + Buffer buffer = new IndirectNIOBuffer(len); + InputStream is = resource.getInputStream(); + buffer.readFrom(is,len); + is.close(); + return buffer; } - finally + catch(IOException e) { - content.getResource().release(); + Log.warn(e); + return null; + } + } + + /* ------------------------------------------------------------ */ + protected Buffer getDirectBuffer(Resource resource) + { + try + { + if (_useFileMappedBuffer && resource.getFile()!=null) + return new DirectNIOBuffer(resource.getFile()); + + int len=(int)resource.length(); + Buffer buffer = new DirectNIOBuffer(len); + InputStream is = resource.getInputStream(); + buffer.readFrom(is,len); + is.close(); + return buffer; + } + catch(IOException e) + { + Log.warn(e); + return null; } } @@ -310,95 +304,34 @@ public class ResourceCache extends AbstractLifeCycle public class Content implements HttpContent { final Resource _resource; + final int _length; + final String _key; final long _lastModified; - boolean _locked; - String _key; - Content _prev; - Content _next; + final Buffer _lastModifiedBytes; + final Buffer _contentType; - Buffer _lastModifiedBytes; - Buffer _contentType; - Buffer _buffer; + volatile long _lastAccessed; + AtomicReference _indirectBuffer=new AtomicReference(); + AtomicReference _directBuffer=new AtomicReference(); /* ------------------------------------------------------------ */ - Content(Resource resource) - { - _resource=resource; - - _next=this; - _prev=this; - _contentType=_mimeTypes.getMimeByExtension(_resource.toString()); - - _lastModified=resource.lastModified(); - } - - - /* ------------------------------------------------------------ */ - /** - * @return true if the content is locked in the cache - */ - public boolean isLocked() - { - return _locked; - } - - - /* ------------------------------------------------------------ */ - /** - * @param locked true if the content is locked in the cache - */ - public void setLocked(boolean locked) - { - synchronized (_cache) - { - if (_locked && !locked) - { - _locked = locked; - _next=_mostRecentlyUsed; - _mostRecentlyUsed=this; - if (_next!=null) - _next._prev=this; - _prev=null; - if (_leastRecentlyUsed==null) - _leastRecentlyUsed=this; - } - else if (!_locked && locked) - { - if (_prev!=null) - _prev._next=_next; - if (_next!=null) - _next._prev=_prev; - _next=_prev=null; - } - else - _locked = locked; - } - } - - - /* ------------------------------------------------------------ */ - void cache(String pathInContext) + Content(String pathInContext,Resource resource) { _key=pathInContext; + _resource=resource; + + _contentType=_mimeTypes.getMimeByExtension(_resource.toString()); + boolean exists=resource.exists(); + _lastModified=exists?resource.lastModified():-1; + _lastModifiedBytes=_lastModified<0?null:new ByteArrayBuffer(HttpFields.formatDate(_lastModified)); - if (!_locked) - { - _next=_mostRecentlyUsed; - _mostRecentlyUsed=this; - if (_next!=null) - _next._prev=this; - _prev=null; - if (_leastRecentlyUsed==null) - _leastRecentlyUsed=this; - } - _cache.put(_key,this); - if (_buffer!=null) - _cachedSize+=_buffer.length(); - _cachedFiles++; - if (_lastModified!=-1) - _lastModifiedBytes=new ByteArrayBuffer(HttpFields.formatDate(_lastModified)); + _length=exists?(int)resource.length():0; + _cachedSize.addAndGet(_length); + _cachedFiles.incrementAndGet(); + _lastAccessed=System.currentTimeMillis(); } + /* ------------------------------------------------------------ */ public String getKey() { @@ -422,59 +355,22 @@ public class ResourceCache extends AbstractLifeCycle { if (_lastModified==_resource.lastModified()) { - if (!_locked && _mostRecentlyUsed!=this) - { - Content tp = _prev; - Content tn = _next; - - _next=_mostRecentlyUsed; - _mostRecentlyUsed=this; - if (_next!=null) - _next._prev=this; - _prev=null; - - if (tp!=null) - tp._next=tn; - if (tn!=null) - tn._prev=tp; - - if (_leastRecentlyUsed==this && tp!=null) - _leastRecentlyUsed=tp; - } + _lastAccessed=System.currentTimeMillis(); return true; } - invalidate(); + if (this==_cache.remove(_key)) + invalidate(); return false; } /* ------------------------------------------------------------ */ - public void invalidate() + protected void invalidate() { - synchronized(this) - { - // Invalidate it - _cache.remove(_key); - _key=null; - if (_buffer!=null) - _cachedSize=_cachedSize-_buffer.length(); - _cachedFiles--; - - if (_mostRecentlyUsed==this) - _mostRecentlyUsed=_next; - else - _prev._next=_next; - - if (_leastRecentlyUsed==this) - _leastRecentlyUsed=_prev; - else - _next._prev=_prev; - - _prev=null; - _next=null; - _resource.release(); - - } + // Invalidate it + _cachedSize.addAndGet(-_length); + _cachedFiles.decrementAndGet(); + _resource.release(); } /* ------------------------------------------------------------ */ @@ -489,46 +385,67 @@ public class ResourceCache extends AbstractLifeCycle return _contentType; } - /* ------------------------------------------------------------ */ - public void setContentType(Buffer type) - { - _contentType=type; - } - /* ------------------------------------------------------------ */ public void release() { + // don't release while cached. Release when invalidated. } /* ------------------------------------------------------------ */ - public Buffer getBuffer() + public Buffer getIndirectBuffer() { - if (_buffer==null) + Buffer buffer = _indirectBuffer.get(); + if (buffer==null) + { + synchronized (_indirectBuffer) + { + if (_indirectBuffer.get()==null) + { + buffer=ResourceCache.this.getIndirectBuffer(_resource); + _indirectBuffer.set(buffer); + } + } + } + if (buffer==null) return null; - return new View(_buffer); + return new View(buffer); + } + + + /* ------------------------------------------------------------ */ + public Buffer getDirectBuffer() + { + Buffer buffer = _directBuffer.get(); + if (buffer==null) + { + synchronized (_directBuffer) + { + if (_directBuffer.get()==null) + { + buffer=ResourceCache.this.getDirectBuffer(_resource); + _directBuffer.set(buffer); + } + } + } + if (buffer==null) + return null; + + return new View(buffer); } - /* ------------------------------------------------------------ */ - public void setBuffer(Buffer buffer) - { - _buffer=buffer; - } - /* ------------------------------------------------------------ */ public long getContentLength() { - if (_buffer==null) - { - if (_resource!=null) - return _resource.length(); - return -1; - } - return _buffer.length(); + return _length; } /* ------------------------------------------------------------ */ public InputStream getInputStream() throws IOException { + Buffer indirect = getIndirectBuffer(); + if (indirect!=null && indirect.array()!=null) + return new ByteArrayInputStream(indirect.array(),indirect.getIndex(),indirect.length()); + return _resource.getInputStream(); } @@ -549,9 +466,9 @@ public class ResourceCache extends AbstractLifeCycle */ public class Miss extends Content { - Miss(Resource resource) + Miss(String pathInContext,Resource resource) { - super(resource); + super(pathInContext,resource); } /* ------------------------------------------------------------ */ @@ -560,7 +477,8 @@ public class ResourceCache extends AbstractLifeCycle { if (_resource.exists()) { - invalidate(); + if (this==_cache.remove(_key)) + invalidate(); return false; } return true; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index 34a8a3286bb..faf7a73fa3f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -270,26 +270,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server. return _vhosts; } - /* ------------------------------------------------------------ */ - /** - * @deprecated use {@link #setConnectorNames(String[])} - */ - @Deprecated - public void setHosts(String[] hosts) - { - setConnectorNames(hosts); - } - - /* ------------------------------------------------------------ */ - /** Get the hosts for the context. - * @deprecated - */ - @Deprecated - public String[] getHosts() - { - return getConnectorNames(); - } - /* ------------------------------------------------------------ */ /** * @return an array of connector names that this context diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java index f90e1220cad..0dfbb8ca4fa 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceCacheTest.java @@ -32,7 +32,7 @@ public class ResourceCacheTest private Resource directory; private File[] files=new File[10]; private String[] names=new String[files.length]; - private ResourceCache cache = new ResourceCache(new MimeTypes()); + private ResourceCache cache; private ResourceFactory factory; @Before @@ -40,7 +40,7 @@ public class ResourceCacheTest { for (int i=0;i0) - { - _nioCache=new NIOResourceCache(_mimeTypes); - _nioCache.setUseFileMappedBuffer(_useFileMappedBuffer); - if (max_cache_size>0) - _nioCache.setMaxCacheSize(max_cache_size); - if (max_cached_file_size>=-1) - _nioCache.setMaxCachedFileSize(max_cached_file_size); - if (max_cached_files>=-1) - _nioCache.setMaxCachedFiles(max_cached_files); - _nioCache.start(); - } - } - if ("bio".equals(cache_type)|| "both".equals(cache_type)) - { - if (max_cache_size==-2 || max_cache_size>0) - { - _bioCache=new ResourceCache(_mimeTypes); - if (max_cache_size>0) - _bioCache.setMaxCacheSize(max_cache_size); - if (max_cached_file_size>=-1) - _bioCache.setMaxCachedFileSize(max_cached_file_size); - if (max_cached_files>=-1) - _bioCache.setMaxCachedFiles(max_cached_files); - _bioCache.start(); - } - } - if (_nioCache==null) - _bioCache=null; + if (max_cache_size!=-1 || max_cached_file_size!= -2 || max_cached_files!=-2) + _servletContext.log("ignoring resource cache configuration, using resourceCache attribute"); + if (_relativeResourceBase!=null || _resourceBase!=null) + throw new UnavailableException("resourceCache specified with resource bases"); + _cache=(ResourceCache)_servletContext.getAttribute(resourceCache); + if (_cache==null) + throw new UnavailableException("Could not find resourceCache "+resourceCache); } - catch (Exception e) + else { - Log.warn(Log.EXCEPTION,e); - throw new UnavailableException(e.toString()); + try + { + if (max_cached_files>0) + { + _cache= new ResourceCache(this,_mimeTypes,_useFileMappedBuffer); + + if (max_cache_size>0) + _cache.setMaxCacheSize(max_cache_size); + if (max_cached_file_size>=-1) + _cache.setMaxCachedFileSize(max_cached_file_size); + if (max_cached_files>=-1) + _cache.setMaxCachedFiles(max_cached_files); + } + } + catch (Exception e) + { + Log.warn(Log.EXCEPTION,e); + throw new UnavailableException(e.toString()); + } } _servletHandler= (ServletHandler) _contextHandler.getChildHandlerByClass(ServletHandler.class); @@ -332,13 +324,14 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory } /* ------------------------------------------------------------ */ + @SuppressWarnings("unchecked") @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String servletPath=null; String pathInfo=null; - Enumeration reqRanges = null; + Enumeration reqRanges = null; Boolean included =request.getAttribute(Dispatcher.INCLUDE_REQUEST_URI)!=null; if (included!=null && included.booleanValue()) { @@ -378,9 +371,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory // Find the resource and content Resource resource=null; HttpContent content=null; - - Connector connector = HttpConnection.getCurrentConnection().getConnector(); - ResourceCache cache=(connector instanceof NIOConnector && !(connector instanceof SslConnector)) ?_nioCache:_bioCache; + try { // Try gzipped content first @@ -388,27 +379,27 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory { pathInContextGz=pathInContext+".gz"; - if (cache==null) + if (_cache==null) { resource=getResource(pathInContextGz); } else { - content=cache.lookup(pathInContextGz,this); + content=_cache.lookup(pathInContextGz); if (content!=null) resource=content.getResource(); - else + else if (!(content instanceof ResourceCache.Miss)) resource=getResource(pathInContextGz); } if (resource==null || !resource.exists()|| resource.isDirectory()) { - if (cache!=null && content==null) + if (_cache!=null && content==null) { String real_path=_servletContext.getRealPath(pathInContextGz); if (real_path!=null) - cache.miss(pathInContextGz,_contextHandler.newResource(real_path)); + _cache.miss(pathInContextGz,_contextHandler.newResource(real_path)); } gzip=false; pathInContextGz=null; @@ -418,11 +409,11 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory // find resource if (!gzip) { - if (cache==null) + if (_cache==null) resource=getResource(pathInContext); else { - content=cache.lookup(pathInContext,this); + content=_cache.lookup(pathInContext); if (content!=null) resource=content.getResource(); @@ -544,7 +535,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory } /* ------------------------------------------------------------ */ - private boolean hasDefinedRange(Enumeration reqRanges) + private boolean hasDefinedRange(Enumeration reqRanges) { return (reqRanges!=null && reqRanges.hasMoreElements()); } @@ -723,8 +714,21 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory Enumeration reqRanges) throws IOException { - long content_length=content==null?resource.length():content.getContentLength(); - + boolean direct; + long content_length; + if (content==null) + { + direct=false; + content_length=resource.length(); + } + else + { + Connector connector = HttpConnection.getCurrentConnection().getConnector(); + direct=connector instanceof NIOConnector && ((NIOConnector)connector).getUseDirectBuffers() && !(connector instanceof SslConnector); + content_length=content.getContentLength(); + } + + // Get the output stream (or writer) OutputStream out =null; try{out = response.getOutputStream();} @@ -740,29 +744,39 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory else { // See if a direct methods can be used? - if (out instanceof HttpConnection.Output) + if (out instanceof HttpConnection.Output && content!=null) { if (response instanceof Response) { writeOptionHeaders(((Response)response).getHttpFields()); ((HttpConnection.Output)out).sendContent(content); } - else if (content.getBuffer()!=null) + else { - writeHeaders(response,content,content_length); - ((HttpConnection.Output)out).sendContent(content.getBuffer()); - } - else - { - writeHeaders(response,content,content_length); - resource.writeTo(out,0,content_length); + Buffer buffer = direct?content.getDirectBuffer():content.getIndirectBuffer(); + if (buffer!=null) + { + writeHeaders(response,content,content_length); + ((HttpConnection.Output)out).sendContent(buffer); + } + else + { + writeHeaders(response,content,content_length); + resource.writeTo(out,0,content_length); + } } } - else + else { - // Write content normally + // Write headers normally writeHeaders(response,content,content_length); - resource.writeTo(out,0,content_length); + + // Write content normally + Buffer buffer = (content==null)?null:content.getIndirectBuffer(); + if (buffer!=null) + buffer.writeTo(out); + else + resource.writeTo(out,0,content_length); } } } @@ -944,31 +958,9 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory @Override public void destroy() { - try - { - if (_nioCache!=null) - _nioCache.stop(); - } - catch(Exception e) - { - Log.warn(Log.EXCEPTION,e); - } - finally - { - try - { - if (_bioCache!=null) - _bioCache.stop(); - } - catch(Exception e) - { - Log.warn(Log.EXCEPTION,e); - } - finally - { - super.destroy(); - } - } + if (_cache!=null) + _cache.flushCache(); + super.destroy(); } /* ------------------------------------------------------------ */ @@ -996,7 +988,13 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory } /* ------------------------------------------------------------ */ - public Buffer getBuffer() + public Buffer getDirectBuffer() + { + return null; + } + + /* ------------------------------------------------------------ */ + public Buffer getIndirectBuffer() { return null; } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/NIOResourceCache.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/NIOResourceCache.java deleted file mode 100644 index 12c900bf264..00000000000 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/NIOResourceCache.java +++ /dev/null @@ -1,86 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== - -/** - * - */ -package org.eclipse.jetty.servlet; - -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.jetty.http.MimeTypes; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.nio.DirectNIOBuffer; -import org.eclipse.jetty.io.nio.IndirectNIOBuffer; -import org.eclipse.jetty.io.nio.NIOBuffer; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.HttpConnection; -import org.eclipse.jetty.server.ResourceCache; -import org.eclipse.jetty.server.nio.NIOConnector; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.resource.Resource; - -class NIOResourceCache extends ResourceCache -{ - boolean _useFileMappedBuffer; - - /* ------------------------------------------------------------ */ - public NIOResourceCache(MimeTypes mimeTypes) - { - super(mimeTypes); - } - - /* ------------------------------------------------------------ */ - protected void fill(Content content) throws IOException - { - Buffer buffer=null; - Resource resource=content.getResource(); - long length=resource.length(); - - if (_useFileMappedBuffer && resource.getFile()!=null) - { - buffer = new DirectNIOBuffer(resource.getFile()); - } - else - { - InputStream is = resource.getInputStream(); - try - { - Connector connector = HttpConnection.getCurrentConnection().getConnector(); - buffer = ((NIOConnector)connector).getUseDirectBuffers()? - (NIOBuffer)new DirectNIOBuffer((int)length): - (NIOBuffer)new IndirectNIOBuffer((int)length); - } - catch(OutOfMemoryError e) - { - Log.warn(e.toString()); - Log.debug(e); - buffer = new IndirectNIOBuffer((int) length); - } - buffer.readFrom(is,(int)length); - is.close(); - } - content.setBuffer(buffer); - } - - public boolean isUseFileMappedBuffer() - { - return _useFileMappedBuffer; - } - - public void setUseFileMappedBuffer(boolean useFileMappedBuffer) - { - _useFileMappedBuffer = useFileMappedBuffer; - } -} diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index a38afdde443..cbb65017634 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -595,25 +595,6 @@ public class ServletHandler extends ScopedHandler return chain; } - /* ------------------------------------------------------------ */ - /** - * @return Returns the initializeAtStart. - * @deprecated - */ - public boolean isInitializeAtStart() - { - return false; - } - - /* ------------------------------------------------------------ */ - /** - * @param initializeAtStart The initializeAtStart to set. - * @deprecated - */ - public void setInitializeAtStart(boolean initializeAtStart) - { - } - /* ------------------------------------------------------------ */ /** * @return true if the handler is started and there are no unavailable servlets @@ -719,7 +700,7 @@ public class ServletHandler extends ScopedHandler } /* ------------------------------------------------------------ */ - public ServletHolder newServletHolder(Class servlet) + public ServletHolder newServletHolder(Class servlet) { return new ServletHolder(servlet); } @@ -782,18 +763,6 @@ public class ServletHandler extends ScopedHandler } } - /* ------------------------------------------------------------ */ - /** Convenience method to add a servlet with a servlet mapping. - * @param className - * @param pathSpec - * @return the ServletHolder - * @deprecated use {@link #addServletWithMapping(Class, String)} instead - */ - public ServletHolder addServlet (String className, String pathSpec) - { - return addServletWithMapping (className, pathSpec); - } - /* ------------------------------------------------------------ */ /**Convenience method to add a pre-constructed ServletHolder. @@ -901,19 +870,6 @@ public class ServletHandler extends ScopedHandler } - /* ------------------------------------------------------------ */ - /** Convenience method to add a filter with a mapping - * @param className - * @param pathSpec - * @param dispatches - * @return the filter holder created - * @deprecated use {@link #addFilterWithMapping(Class, String, int)} instead - */ - public FilterHolder addFilter (String className,String pathSpec,int dispatches) - { - return addFilterWithMapping(className, pathSpec, dispatches); - } - /* ------------------------------------------------------------ */ /** * convenience method to add a filter and mapping @@ -1325,6 +1281,7 @@ public class ServletHandler extends ScopedHandler _maxFilterChainsCacheSize = maxFilterChainsCacheSize; } + /* ------------------------------------------------------------ */ /** * Customize a servlet. * @@ -1342,14 +1299,14 @@ public class ServletHandler extends ScopedHandler return servlet; } - + /* ------------------------------------------------------------ */ public Servlet customizeServletDestroy (Servlet servlet) throws Exception { return servlet; } - + /* ------------------------------------------------------------ */ /** * Customize a Filter. * @@ -1357,9 +1314,9 @@ public class ServletHandler extends ScopedHandler * Subclasses of ServletHandler should override * this method. * - * @param filter + * @param filter The filter to customize. * @return the potentially customized filter - * @throws Exception + * @throws Exception If there was a problem */ public Filter customizeFilter (Filter filter) throws Exception @@ -1367,7 +1324,7 @@ public class ServletHandler extends ScopedHandler return filter; } - + /* ------------------------------------------------------------ */ public Filter customizeFilterDestroy (Filter filter) throws Exception { @@ -1375,8 +1332,8 @@ public class ServletHandler extends ScopedHandler } - /* ------------------------------------------------------------ */ + @Override protected void dump(StringBuilder b,String indent) { super.dump(b,indent); @@ -1423,6 +1380,4 @@ public class ServletHandler extends ScopedHandler } } - - } 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 dc933bafb76..a7fdc9f7ee1 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 @@ -27,16 +27,14 @@ import org.eclipse.jetty.util.log.Log; /* ------------------------------------------------------------ */ class JarFileResource extends JarResource { - - transient JarFile _jarFile; - transient File _file; - transient String[] _list; - transient JarEntry _entry; - transient boolean _directory; - transient String _jarUrl; - transient String _path; - transient boolean _exists; - + private JarFile _jarFile; + private File _file; + private String[] _list; + private JarEntry _entry; + private boolean _directory; + private String _jarUrl; + private String _path; + private boolean _exists; /* -------------------------------------------------------- */ JarFileResource(URL url) @@ -44,6 +42,7 @@ class JarFileResource extends JarResource super(url); } + /* ------------------------------------------------------------ */ JarFileResource(URL url, boolean useCaches) { super(url, useCaches); @@ -65,7 +64,8 @@ class JarFileResource extends JarResource @Override protected boolean checkConnection() { - try{ + try + { super.checkConnection(); } finally @@ -84,7 +84,7 @@ class JarFileResource extends JarResource /* ------------------------------------------------------------ */ @Override - protected void newConnection() + protected synchronized void newConnection() throws IOException { super.newConnection(); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java index b7534fffe32..c79b1a6ed40 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarResource.java @@ -31,8 +31,7 @@ import org.eclipse.jetty.util.log.Log; /* ------------------------------------------------------------ */ public class JarResource extends URLResource { - - protected transient JarURLConnection _jarConnection; + protected JarURLConnection _jarConnection; /* -------------------------------------------------------- */ JarResource(URL url) @@ -56,7 +55,7 @@ public class JarResource extends URLResource /* ------------------------------------------------------------ */ @Override - protected boolean checkConnection() + protected synchronized boolean checkConnection() { super.checkConnection(); try @@ -120,16 +119,6 @@ public class JarResource extends URLResource InputStream is = url.openStream(); return is; } - - /* ------------------------------------------------------------ */ - @Deprecated - public void extract(File dest, boolean deleteOnExit) - throws IOException - { - if (deleteOnExit) - dest.deleteOnExit(); - copyTo(dest); - } /* ------------------------------------------------------------ */ @Override diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java index 44e8ba69164..8e55d973166 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java @@ -37,10 +37,10 @@ import org.eclipse.jetty.util.log.Log; /** * Abstract resource class. */ -public abstract class Resource implements Serializable +public abstract class Resource { public static boolean __defaultUseCaches = true; - Object _associate; + volatile Object _associate; /** * Change the default setting for url connection caches. @@ -51,7 +51,8 @@ public abstract class Resource implements Serializable { __defaultUseCaches=useCaches; } - + + /* ------------------------------------------------------------ */ public static boolean getDefaultUseCaches () { return __defaultUseCaches; @@ -61,6 +62,7 @@ public abstract class Resource implements Serializable /** Construct a resource from a uri. * @param uri A URI. * @return A Resource object. + * @throws IOException Problem accessing URI */ public static Resource newResource(URI uri) throws IOException @@ -72,6 +74,7 @@ public abstract class Resource implements Serializable /** Construct a resource from a url. * @param url A URL. * @return A Resource object. + * @throws IOException Problem accessing URL */ public static Resource newResource(URL url) throws IOException @@ -199,6 +202,9 @@ public abstract class Resource implements Serializable /** Construct a system resource from a string. * The resource is tried as classloader resource before being * treated as a normal resource. + * @param resource Resource as string representation + * @return The new Resource + * @throws IOException Problem accessing resource. */ public static Resource newSystemResource(String resource) throws IOException @@ -287,6 +293,7 @@ public abstract class Resource implements Serializable return newResource(url,useCaches); } + /* ------------------------------------------------------------ */ public static boolean isContainedIn (Resource r, Resource containingResource) throws MalformedURLException { return r.isContainedIn(containingResource); @@ -298,12 +305,13 @@ public abstract class Resource implements Serializable { release(); } - + + /* ------------------------------------------------------------ */ public abstract boolean isContainedIn (Resource r) throws MalformedURLException; /* ------------------------------------------------------------ */ - /** Release any resources held by the resource. + /** Release any temporary resources held by the resource. */ public abstract void release(); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/URLResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/URLResource.java index 016322cfb86..f7629c9c2b1 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/URLResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/URLResource.java @@ -32,12 +32,11 @@ import org.eclipse.jetty.util.log.Log; */ public class URLResource extends Resource { - - - protected URL _url; + protected final URL _url; protected String _urlString; - protected transient URLConnection _connection; - protected transient InputStream _in=null; + + protected URLConnection _connection; + protected InputStream _in=null; transient boolean _useCaches = Resource.__defaultUseCaches; /* ------------------------------------------------------------ */ @@ -48,6 +47,7 @@ public class URLResource extends Resource _connection=connection; } + /* ------------------------------------------------------------ */ protected URLResource (URL url, URLConnection connection, boolean useCaches) { this (url, connection); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index 6c89832e70f..45a07b9fdb2 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -125,7 +125,21 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E Thread.yield(); int size=_threads.size(); if (size>0) + { Log.warn(size+" threads could not be stopped"); + + if (Log.isDebugEnabled()) + { + for (Thread unstopped : _threads) + { + Log.debug("Couldn't stop "+unstopped); + for (StackTraceElement element : unstopped.getStackTrace()) + { + Log.debug(" at "+element); + } + } + } + } synchronized (_joinLock) { diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml index 9cb725596a8..a696ab55d40 100644 --- a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml +++ b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml @@ -93,7 +93,7 @@ GzipFilter - /* + /dump/gzip/* diff --git a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java index 952752173b9..432a6fe15f8 100644 --- a/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java +++ b/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java @@ -22,6 +22,7 @@ import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.bio.SocketConnector; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; @@ -37,7 +38,7 @@ public class TestServer { public static void main(String[] args) throws Exception { - Log.getLog().setDebugEnabled(true); + Log.getLog().setDebugEnabled(false); ((StdErrLog)Log.getLog()).setSource(false); String jetty_root = ".."; @@ -50,7 +51,6 @@ public class TestServer server.getContainer().addEventListener(mbContainer); server.addBean(mbContainer); mbContainer.addBean(Log.getLog()); - // Setup Threadpool QueuedThreadPool threadPool = new QueuedThreadPool(); @@ -58,12 +58,27 @@ public class TestServer server.setThreadPool(threadPool); // Setup Connectors - SelectChannelConnector connector = new SelectChannelConnector(); - connector.setPort(8080); - connector.setMaxIdleTime(30000); - connector.setConfidentialPort(8443); - server.setConnectors(new Connector[] - { connector }); + SelectChannelConnector connector0 = new SelectChannelConnector(); + connector0.setPort(8080); + connector0.setMaxIdleTime(30000); + connector0.setConfidentialPort(8443); + connector0.setUseDirectBuffers(true); + server.addConnector(connector0); + + // Setup Connectors + SelectChannelConnector connector1 = new SelectChannelConnector(); + connector1.setPort(8081); + connector1.setMaxIdleTime(30000); + connector1.setConfidentialPort(8443); + connector1.setUseDirectBuffers(false); + server.addConnector(connector1); + + // Setup Connectors + SocketConnector connector2 = new SocketConnector(); + connector2.setPort(8082); + connector2.setMaxIdleTime(30000); + connector2.setConfidentialPort(8443); + server.addConnector(connector2); SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector(); ssl_connector.setPort(8443);