diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java index 6e5866bf628..6705496df0d 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java @@ -217,6 +217,7 @@ public class LikeJettyXml // Start the server server.start(); + server.dumpStdErr(); server.join(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java index 392d8417c32..154e3fcf08c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java @@ -53,13 +53,10 @@ public class ClassLoaderDump implements Dumpable Object parent = _loader.getParent(); if (parent != null) { - if (!(parent instanceof Dumpable)) - parent = new ClassLoaderDump((ClassLoader)parent); - if (_loader instanceof URLClassLoader) - ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent)); + ContainerLifeCycle.dump(out,indent,TypeUtil.asList(((URLClassLoader)_loader).getURLs()),Collections.singleton(parent.toString())); else - ContainerLifeCycle.dump(out,indent,Collections.singleton(parent)); + ContainerLifeCycle.dump(out,indent,Collections.singleton(parent.toString())); } } } 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 a530b9a514d..ec323f5f742 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 @@ -81,6 +81,7 @@ import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.component.DumpableCollection; import org.eclipse.jetty.util.component.Graceful; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -231,10 +232,11 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu public void dump(Appendable out, String indent) throws IOException { dumpBeans(out,indent, - Collections.singletonList(new ClassLoaderDump(getClassLoader())), - _initParams.entrySet(), - _attributes.getAttributeEntrySet(), - _scontext.getAttributeEntrySet()); + Collections.singletonList(new ClassLoaderDump(getClassLoader())), + Collections.singletonList(new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet())), + Collections.singletonList(new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet())), + Collections.singletonList(new DumpableCollection("Initparams "+this,getInitParams().entrySet())) + ); } /* ------------------------------------------------------------ */ @@ -1479,7 +1481,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu { if (errorHandler != null) errorHandler.setServer(getServer()); - updateBean(_errorHandler,errorHandler); + updateBean(_errorHandler,errorHandler,true); _errorHandler = errorHandler; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java index b5c966f764c..eb495e14a92 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerWrapper.java @@ -86,7 +86,7 @@ public class HandlerWrapper extends AbstractHandlerContainer Handler old=_handler; _handler=handler; - updateBean(old,_handler); + updateBean(old,_handler,true); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java index de87d977ef4..a0685f2b9cf 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java @@ -77,7 +77,7 @@ public class HotSwapHandler extends AbstractHandlerContainer throw new IllegalArgumentException("Parameter handler is null."); try { - updateBean(_handler,handler); + updateBean(_handler,handler,true); _handler=handler; Server server = getServer(); handler.setServer(server); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java index ace46f550d1..a2450cf53a0 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java @@ -743,7 +743,7 @@ public class StringUtil if (s.length()==2) return new String[]{}; - return s.substring(1,s.length()-1).split(" *, *"); + return s.substring(1,s.length()-1).split("\\s*,\\s*"); } public static String sanitizeXmlString(String html) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java index 060a3d1344a..645fa0599c1 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java @@ -777,6 +777,17 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container, addBean(newBean); } } + + public void updateBean(Object oldBean, final Object newBean, boolean managed) + { + if (newBean!=oldBean) + { + if (oldBean!=null) + removeBean(oldBean); + if (newBean!=null) + addBean(newBean,managed); + } + } public void updateBeans(Object[] oldBeans, final Object[] newBeans) { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java new file mode 100644 index 00000000000..b4c047bcd2d --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 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.util.component; + +import java.io.IOException; +import java.util.Collection; + +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.Dumpable; + +public class DumpableCollection implements Dumpable +{ + private final String _name; + private final Collection _collection; + + public DumpableCollection(String name,Collection collection) + { + _name=name; + _collection=collection; + } + + @Override + public String dump() + { + return ContainerLifeCycle.dump(this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + out.append(_name).append("\n"); + if (_collection!=null) + ContainerLifeCycle.dump(out,indent,_collection); + } +} diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java index 7389f7f344a..0604bd4d115 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/ClasspathPattern.java @@ -19,14 +19,15 @@ package org.eclipse.jetty.webapp; +import java.util.AbstractList; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.StringTokenizer; - +import java.util.ListIterator; /* ------------------------------------------------------------ */ /** - * ClasspathPattern performs sequential pattern matching of a class name + * Classpath classes list performs sequential pattern matching of a class name * against an internal array of classpath pattern entries. * * When an entry starts with '-' (minus), reverse matching is performed. @@ -36,16 +37,30 @@ import java.util.StringTokenizer; * in this string should be separated by ':' (semicolon) or ',' (comma). */ -public class ClasspathPattern +public class ClasspathPattern extends AbstractList { private static class Entry { - public String classpath = null; - public boolean result = false; - public boolean partial = false; + public final String _pattern; + public final String _name; + public final boolean _inclusive; + public final boolean _package; + + Entry(String pattern) + { + _pattern=pattern; + _inclusive = !pattern.startsWith("-"); + _package = pattern.endsWith("."); + _name = _inclusive ? pattern : pattern.substring(1).trim(); + } + + @Override + public String toString() + { + return _pattern; + } } - final private List _patterns = new ArrayList(); final private List _entries = new ArrayList(); /* ------------------------------------------------------------ */ @@ -56,160 +71,140 @@ public class ClasspathPattern /* ------------------------------------------------------------ */ public ClasspathPattern(String[] patterns) { - setPatterns(patterns); + setAll(patterns); } /* ------------------------------------------------------------ */ public ClasspathPattern(String pattern) { - setPattern(pattern); + add(pattern); } + /* ------------------------------------------------------------ */ + @Override + public String get(int index) + { + return _entries.get(index)._pattern; + } + + /* ------------------------------------------------------------ */ + @Override + public String set(int index, String element) + { + Entry e = _entries.set(index,new Entry(element)); + return e==null?null:e._pattern; + } + + /* ------------------------------------------------------------ */ + @Override + public void add(int index, String element) + { + _entries.add(index,new Entry(element)); + } + + /* ------------------------------------------------------------ */ + @Deprecated + public void addPattern(String element) + { + add(element); + } + + /* ------------------------------------------------------------ */ + @Override + public String remove(int index) + { + Entry e = _entries.remove(index); + return e==null?null:e._pattern; + } + + /* ------------------------------------------------------------ */ + public boolean remove(String pattern) + { + for (int i=_entries.size();i-->0;) + { + if (pattern.equals(_entries.get(i)._pattern)) + { + _entries.remove(i); + return true; + } + } + return false; + } + + /* ------------------------------------------------------------ */ + @Override + public int size() + { + return _entries.size(); + } /* ------------------------------------------------------------ */ /** * Initialize the matcher by parsing each classpath pattern in an array * - * @param patterns array of classpath patterns + * @param classes array of classpath patterns */ - private void setPatterns(String[] patterns) + private void setAll(String[] classes) { - _patterns.clear(); _entries.clear(); - addPatterns(patterns); + addAll(classes); } /* ------------------------------------------------------------ */ /** - * @param patterns array of classpath patterns + * @param classes array of classpath patterns */ - private void addPatterns(String[] patterns) + private void addAll(String[] classes) { - if (patterns != null) - { - Entry entry = null; - for (String pattern : patterns) - { - entry = createEntry(pattern); - if (entry != null) - { - _patterns.add(pattern); - _entries.add(entry); - } - } - } + if (classes!=null) + addAll(Arrays.asList(classes)); } /* ------------------------------------------------------------ */ /** - * @param patterns array of classpath patterns + * @param classes array of classpath patterns */ - private void prependPatterns(String[] patterns) + public void prepend(String[] classes) { - if (patterns != null) + if (classes != null) { - Entry entry = null; int i=0; - for (String pattern : patterns) + for (String c : classes) { - entry = createEntry(pattern); - if (entry != null) - { - _patterns.add(i,pattern); - _entries.add(i,entry); - i++; - } + add(i,c); + i++; } } } - - /* ------------------------------------------------------------ */ - /** - * Create an entry object containing information about - * a single classpath pattern - * - * @param pattern single classpath pattern - * @return corresponding Entry object - */ - private Entry createEntry(String pattern) - { - Entry entry = null; - - if (pattern != null) - { - String item = pattern.trim(); - if (item.length() > 0) - { - entry = new Entry(); - entry.result = !item.startsWith("-"); - entry.partial = item.endsWith("."); - entry.classpath = entry.result ? item : item.substring(1).trim(); - } - } - return entry; - } - - /* ------------------------------------------------------------ */ - /** - * Initialize the matcher by parsing a classpath pattern string - * - * @param pattern classpath pattern string - */ - public void setPattern(String pattern) - { - _patterns.clear(); - _entries.clear(); - addPattern(pattern); - } /* ------------------------------------------------------------ */ - /** - * Parse a classpath pattern string and appending the result - * to the existing configuration. - * - * @param pattern classpath pattern string - */ - public void addPattern(String pattern) + public void prependPattern(String pattern) { - ArrayList patterns = new ArrayList(); - StringTokenizer entries = new StringTokenizer(pattern, ":,"); - while (entries.hasMoreTokens()) - { - patterns.add(entries.nextToken()); - } - - addPatterns(patterns.toArray(new String[patterns.size()])); - } - - - /* ------------------------------------------------------------ */ - public void prependPattern(String classOrPackage) - { - ArrayList patterns = new ArrayList(); - StringTokenizer entries = new StringTokenizer(classOrPackage, ":,"); - while (entries.hasMoreTokens()) - { - patterns.add(entries.nextToken()); - } - - prependPatterns(patterns.toArray(new String[patterns.size()])); + add(0,pattern); } - /* ------------------------------------------------------------ */ /** * @return array of classpath patterns */ public String[] getPatterns() { - String[] patterns = null; - - if (_patterns!=null && _patterns.size() > 0) + return toArray(new String[_entries.size()]); + } + + /* ------------------------------------------------------------ */ + /** + * @return List of classes excluded class exclusions and package patterns + */ + public List getClasses() + { + List list = new ArrayList<>(); + for (Entry e:_entries) { - patterns = _patterns.toArray(new String[_patterns.size()]); + if (e._inclusive && !e._package) + list.add(e._name); } - - return patterns; + return list; } /* ------------------------------------------------------------ */ @@ -241,21 +236,21 @@ public class ClasspathPattern { if (entry != null) { - if (entry.partial) + if (entry._package) { - if (name.regionMatches(startIndex, entry.classpath, 0, entry.classpath.length())) + if (name.regionMatches(startIndex, entry._name, 0, entry._name.length())) { - result = entry.result; + result = entry._inclusive; break; } } else { int regionLength = endIndex-startIndex; - if (regionLength == entry.classpath.length() - && name.regionMatches(startIndex, entry.classpath, 0, regionLength)) + if (regionLength == entry._name.length() + && name.regionMatches(startIndex, entry._name, 0, regionLength)) { - result = entry.result; + result = entry._inclusive; break; } } @@ -265,4 +260,42 @@ public class ClasspathPattern return result; } + public void addAfter(String afterPattern,String... patterns) + { + if (patterns!=null && afterPattern!=null) + { + ListIterator iter = listIterator(); + while (iter.hasNext()) + { + String cc=iter.next(); + if (afterPattern.equals(cc)) + { + for (int i=0;i iter = listIterator(); + while (iter.hasNext()) + { + String cc=iter.next(); + if (beforePattern.equals(cc)) + { + iter.previous(); + for (int i=0;i