Issue #963 location based white/black classpath lists - removed outdated annotations/ClassNameResolver - implemented loadedFrom in TypeUtil - created a growable Trie - reimplemented classpathpattern - simplified OSGi classloading
This commit is contained in:
parent
85f50da053
commit
afb750515e
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.annotations;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -48,6 +47,7 @@ import org.eclipse.jetty.plus.annotation.ContainerInitializer;
|
||||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||||
import org.eclipse.jetty.util.MultiException;
|
import org.eclipse.jetty.util.MultiException;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
@ -81,8 +81,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
protected List<ContainerInitializerAnnotationHandler> _containerInitializerAnnotationHandlers = new ArrayList<ContainerInitializerAnnotationHandler>();
|
protected List<ContainerInitializerAnnotationHandler> _containerInitializerAnnotationHandlers = new ArrayList<ContainerInitializerAnnotationHandler>();
|
||||||
|
|
||||||
protected List<ParserTask> _parserTasks;
|
protected List<ParserTask> _parserTasks;
|
||||||
protected WebAppClassNameResolver _webAppClassNameResolver;
|
|
||||||
protected ContainerClassNameResolver _containerClassNameResolver;
|
|
||||||
|
|
||||||
protected CounterStatistic _containerPathStats;
|
protected CounterStatistic _containerPathStats;
|
||||||
protected CounterStatistic _webInfLibStats;
|
protected CounterStatistic _webInfLibStats;
|
||||||
|
@ -138,15 +136,13 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
protected Exception _exception;
|
protected Exception _exception;
|
||||||
protected final AnnotationParser _parser;
|
protected final AnnotationParser _parser;
|
||||||
protected final Set<? extends Handler> _handlers;
|
protected final Set<? extends Handler> _handlers;
|
||||||
protected final ClassNameResolver _resolver;
|
|
||||||
protected final Resource _resource;
|
protected final Resource _resource;
|
||||||
protected TimeStatistic _stat;
|
protected TimeStatistic _stat;
|
||||||
|
|
||||||
public ParserTask (AnnotationParser parser, Set<? extends Handler>handlers, Resource resource, ClassNameResolver resolver)
|
public ParserTask (AnnotationParser parser, Set<? extends Handler>handlers, Resource resource)
|
||||||
{
|
{
|
||||||
_parser = parser;
|
_parser = parser;
|
||||||
_handlers = handlers;
|
_handlers = handlers;
|
||||||
_resolver = resolver;
|
|
||||||
_resource = resource;
|
_resource = resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +156,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
if (_stat != null)
|
if (_stat != null)
|
||||||
_stat.start();
|
_stat.start();
|
||||||
if (_parser != null)
|
if (_parser != null)
|
||||||
_parser.parse(_handlers, _resource, _resolver);
|
_parser.parse(_handlers, _resource);
|
||||||
if (_stat != null)
|
if (_stat != null)
|
||||||
_stat.end();
|
_stat.end();
|
||||||
return null;
|
return null;
|
||||||
|
@ -174,83 +170,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
public Resource getResource()
|
public Resource getResource()
|
||||||
{
|
{
|
||||||
return _resource;
|
return _resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WebAppClassNameResolver
|
|
||||||
*
|
|
||||||
* Checks to see if a classname belongs to hidden or visible packages when scanning,
|
|
||||||
* and whether a classname that is a duplicate should override a previously
|
|
||||||
* scanned classname.
|
|
||||||
*
|
|
||||||
* This is analogous to the management of classes that the WebAppClassLoader is doing,
|
|
||||||
* however we don't want to load the classes at this point so we are doing it on
|
|
||||||
* the name only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WebAppClassNameResolver implements ClassNameResolver
|
|
||||||
{
|
|
||||||
private WebAppContext _context;
|
|
||||||
|
|
||||||
public WebAppClassNameResolver (WebAppContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExcluded (String name)
|
|
||||||
{
|
|
||||||
if (_context.isSystemClass(name)) return true;
|
|
||||||
if (_context.isServerClass(name)) return false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
|
||||||
{
|
|
||||||
//looking at webapp classpath, found already-parsed class
|
|
||||||
//of same name - did it come from system or duplicate in webapp?
|
|
||||||
if (_context.isParentLoaderPriority())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ContainerClassNameResolver
|
|
||||||
*
|
|
||||||
* Checks to see if a classname belongs to a hidden or visible package
|
|
||||||
* when scanning for annotations and thus whether it should be excluded from
|
|
||||||
* consideration or not.
|
|
||||||
*
|
|
||||||
* This is analogous to the management of classes that the WebAppClassLoader is doing,
|
|
||||||
* however we don't want to load the classes at this point so we are doing it on
|
|
||||||
* the name only.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ContainerClassNameResolver implements ClassNameResolver
|
|
||||||
{
|
|
||||||
private WebAppContext _context;
|
|
||||||
|
|
||||||
public ContainerClassNameResolver (WebAppContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
public boolean isExcluded (String name)
|
|
||||||
{
|
|
||||||
if (_context.isSystemClass(name)) return false;
|
|
||||||
if (_context.isServerClass(name)) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
|
||||||
{
|
|
||||||
//visiting the container classpath,
|
|
||||||
if (_context.isParentLoaderPriority())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -390,8 +310,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
@Override
|
@Override
|
||||||
public void preConfigure(final WebAppContext context) throws Exception
|
public void preConfigure(final WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
_webAppClassNameResolver = new WebAppClassNameResolver(context);
|
|
||||||
_containerClassNameResolver = new ContainerClassNameResolver(context);
|
|
||||||
String tmp = (String)context.getAttribute(SERVLET_CONTAINER_INITIALIZER_EXCLUSION_PATTERN);
|
String tmp = (String)context.getAttribute(SERVLET_CONTAINER_INITIALIZER_EXCLUSION_PATTERN);
|
||||||
_sciExcludePattern = (tmp==null?null:Pattern.compile(tmp));
|
_sciExcludePattern = (tmp==null?null:Pattern.compile(tmp));
|
||||||
}
|
}
|
||||||
|
@ -445,15 +363,15 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
|
|
||||||
if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
|
if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
|
||||||
scanForAnnotations(context);
|
scanForAnnotations(context);
|
||||||
|
|
||||||
// Resolve container initializers
|
// Resolve container initializers
|
||||||
List<ContainerInitializer> initializers =
|
List<ContainerInitializer> initializers =
|
||||||
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
|
(List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
|
||||||
if (initializers != null && initializers.size()>0)
|
if (initializers != null && initializers.size()>0)
|
||||||
{
|
{
|
||||||
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
|
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
|
||||||
for (ContainerInitializer i : initializers)
|
for (ContainerInitializer i : initializers)
|
||||||
i.resolveClasses(context,map);
|
i.resolveClasses(context,map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,23 +641,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
public Resource getJarFor (ServletContainerInitializer service)
|
public Resource getJarFor (ServletContainerInitializer service)
|
||||||
throws MalformedURLException, IOException
|
throws MalformedURLException, IOException
|
||||||
{
|
{
|
||||||
//try the thread context classloader to get the jar that loaded the class
|
return TypeUtil.getLoadedFrom(service.getClass());
|
||||||
URL jarURL = Thread.currentThread().getContextClassLoader().getResource(service.getClass().getName().replace('.','/')+".class");
|
|
||||||
|
|
||||||
//if for some reason that failed (eg we're in osgi and the TCCL does not know about the service) try the classloader that
|
|
||||||
//loaded the class
|
|
||||||
if (jarURL == null)
|
|
||||||
jarURL = service.getClass().getClassLoader().getResource(service.getClass().getName().replace('.','/')+".class");
|
|
||||||
|
|
||||||
String loadingJarName = jarURL.toString();
|
|
||||||
|
|
||||||
int i = loadingJarName.indexOf(".jar");
|
|
||||||
if (i < 0)
|
|
||||||
return null; //not from a jar
|
|
||||||
|
|
||||||
loadingJarName = loadingJarName.substring(0,i+4);
|
|
||||||
loadingJarName = (loadingJarName.startsWith("jar:")?loadingJarName.substring(4):loadingJarName);
|
|
||||||
return Resource.newResource(loadingJarName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -760,26 +662,41 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
if (context == null)
|
if (context == null)
|
||||||
throw new IllegalArgumentException("WebAppContext null");
|
throw new IllegalArgumentException("WebAppContext null");
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("Checking {} for jar exclusion", sci);
|
|
||||||
|
|
||||||
//A ServletContainerInitializer that came from the container's classpath cannot be excluded by an ordering
|
//A ServletContainerInitializer that came from the container's classpath cannot be excluded by an ordering
|
||||||
//of WEB-INF/lib jars
|
//of WEB-INF/lib jars
|
||||||
if (isFromContainerClassPath(context, sci))
|
if (isFromContainerClassPath(context, sci))
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("!Excluded {} from container classpath", sci);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//If no ordering, nothing is excluded
|
//If no ordering, nothing is excluded
|
||||||
if (context.getMetaData().getOrdering() == null)
|
if (context.getMetaData().getOrdering() == null)
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("!Excluded {} no ordering", sci);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
List<Resource> orderedJars = context.getMetaData().getOrderedWebInfJars();
|
List<Resource> orderedJars = context.getMetaData().getOrderedWebInfJars();
|
||||||
|
|
||||||
//there is an ordering, but there are no jars resulting from the ordering, everything excluded
|
//there is an ordering, but there are no jars resulting from the ordering, everything excluded
|
||||||
if (orderedJars.isEmpty())
|
if (orderedJars.isEmpty())
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Excluded {} empty ordering", sci);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (sciResource == null)
|
if (sciResource == null)
|
||||||
return false; //not from a jar therefore not from WEB-INF so not excludable
|
{
|
||||||
|
//not from a jar therefore not from WEB-INF so not excludable
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("!Excluded {} not from jar", sci);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
URI loadingJarURI = sciResource.getURI();
|
URI loadingJarURI = sciResource.getURI();
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
@ -790,10 +707,11 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
found = r.getURI().equals(loadingJarURI);
|
found = r.getURI().equals(loadingJarURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{}Excluded {} found={}",found?"!":"",sci,found);
|
||||||
return !found;
|
return !found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the ServletContainerIntializer is excluded by the
|
* Test if the ServletContainerIntializer is excluded by the
|
||||||
* o.e.j.containerInitializerExclusionPattern
|
* o.e.j.containerInitializerExclusionPattern
|
||||||
|
@ -808,7 +726,8 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//test if name of class matches the regex
|
//test if name of class matches the regex
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("Checking {} against containerInitializerExclusionPattern",sci.getClass().getName());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Checking {} against containerInitializerExclusionPattern",sci.getClass().getName());
|
||||||
return _sciExcludePattern.matcher(sci.getClass().getName()).matches();
|
return _sciExcludePattern.matcher(sci.getClass().getName()).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,17 +785,20 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
//because containerInitializerOrdering omits it
|
//because containerInitializerOrdering omits it
|
||||||
for (ServletContainerInitializer sci:_loadedInitializers)
|
for (ServletContainerInitializer sci:_loadedInitializers)
|
||||||
{
|
{
|
||||||
|
LOG.setDebugEnabled(true);
|
||||||
|
|
||||||
if (matchesExclusionPattern(sci))
|
if (matchesExclusionPattern(sci))
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("{} excluded by pattern", sci);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} excluded by pattern", sci);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource sciResource = getJarFor(sci);
|
Resource sciResource = getJarFor(sci);
|
||||||
if (isFromExcludedJar(context, sci, sciResource))
|
if (isFromExcludedJar(context, sci, sciResource))
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("{} is from excluded jar", sci);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} is from excluded jar", sci);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,7 +807,8 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
if (initializerOrdering != null
|
if (initializerOrdering != null
|
||||||
&& (!initializerOrdering.hasWildcard() && initializerOrdering.getIndexOf(name) < 0))
|
&& (!initializerOrdering.hasWildcard() && initializerOrdering.getIndexOf(name) < 0))
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("{} is excluded by ordering", sci);
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("{} is excluded by ordering", sci);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,12 +835,14 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
//no web.xml ordering defined, add SCIs in any order
|
//no web.xml ordering defined, add SCIs in any order
|
||||||
if (context.getMetaData().getOrdering() == null)
|
if (context.getMetaData().getOrdering() == null)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("No web.xml ordering, ServletContainerInitializers in random order");
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("No web.xml ordering, ServletContainerInitializers in random order");
|
||||||
nonExcludedInitializers.addAll(sciResourceMap.keySet());
|
nonExcludedInitializers.addAll(sciResourceMap.keySet());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled()) LOG.debug("Ordering ServletContainerInitializers with ordering {}",context.getMetaData().getOrdering());
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Ordering ServletContainerInitializers with ordering {}",context.getMetaData().getOrdering());
|
||||||
for (Map.Entry<ServletContainerInitializer, Resource> entry:sciResourceMap.entrySet())
|
for (Map.Entry<ServletContainerInitializer, Resource> entry:sciResourceMap.entrySet())
|
||||||
{
|
{
|
||||||
//add in SCIs from the container classpath
|
//add in SCIs from the container classpath
|
||||||
|
@ -992,7 +917,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
//queue it up for scanning if using multithreaded mode
|
//queue it up for scanning if using multithreaded mode
|
||||||
if (_parserTasks != null)
|
if (_parserTasks != null)
|
||||||
{
|
{
|
||||||
ParserTask task = new ParserTask(parser, handlers, r, _containerClassNameResolver);
|
ParserTask task = new ParserTask(parser, handlers, r);
|
||||||
_parserTasks.add(task);
|
_parserTasks.add(task);
|
||||||
_containerPathStats.increment();
|
_containerPathStats.increment();
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -1054,7 +979,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
|
|
||||||
if (_parserTasks != null)
|
if (_parserTasks != null)
|
||||||
{
|
{
|
||||||
ParserTask task = new ParserTask(parser, handlers,r, _webAppClassNameResolver);
|
ParserTask task = new ParserTask(parser, handlers,r);
|
||||||
_parserTasks.add (task);
|
_parserTasks.add (task);
|
||||||
_webInfLibStats.increment();
|
_webInfLibStats.increment();
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
@ -1087,7 +1012,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
|
||||||
{
|
{
|
||||||
if (_parserTasks != null)
|
if (_parserTasks != null)
|
||||||
{
|
{
|
||||||
ParserTask task = new ParserTask(parser, handlers, dir, _webAppClassNameResolver);
|
ParserTask task = new ParserTask(parser, handlers, dir);
|
||||||
_parserTasks.add(task);
|
_parserTasks.add(task);
|
||||||
_webInfClassesStats.increment();
|
_webInfClassesStats.increment();
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
|
|
|
@ -547,25 +547,22 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver to use
|
* @param resolver the class name resolver to use
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (Set<? extends Handler> handlers, String className, ClassNameResolver resolver)
|
public void parse (Set<? extends Handler> handlers, String className)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (className == null)
|
if (className == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!resolver.isExcluded(className))
|
if (!isParsed(className))
|
||||||
{
|
{
|
||||||
if (!isParsed(className) || resolver.shouldOverride(className))
|
className = className.replace('.', '/')+".class";
|
||||||
|
URL resource = Loader.getResource(className);
|
||||||
|
if (resource!= null)
|
||||||
{
|
{
|
||||||
className = className.replace('.', '/')+".class";
|
Resource r = Resource.newResource(resource);
|
||||||
URL resource = Loader.getResource(className);
|
try (InputStream is = r.getInputStream())
|
||||||
if (resource!= null)
|
|
||||||
{
|
{
|
||||||
Resource r = Resource.newResource(resource);
|
scanClass(handlers, null, is);
|
||||||
try (InputStream is = r.getInputStream())
|
|
||||||
{
|
|
||||||
scanClass(handlers, null, is);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,29 +579,27 @@ public class AnnotationParser
|
||||||
* @param visitSuperClasses if true, also visit super classes for parse
|
* @param visitSuperClasses if true, also visit super classes for parse
|
||||||
* @throws Exception if unable to parse class
|
* @throws Exception if unable to parse class
|
||||||
*/
|
*/
|
||||||
public void parse (Set<? extends Handler> handlers, Class<?> clazz, ClassNameResolver resolver, boolean visitSuperClasses)
|
public void parse (Set<? extends Handler> handlers, Class<?> clazz, boolean visitSuperClasses)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
Class<?> cz = clazz;
|
Class<?> cz = clazz;
|
||||||
while (cz != null)
|
while (cz != null)
|
||||||
{
|
{
|
||||||
if (!resolver.isExcluded(cz.getName()))
|
if (!isParsed(cz.getName()))
|
||||||
{
|
{
|
||||||
if (!isParsed(cz.getName()) || resolver.shouldOverride(cz.getName()))
|
String nameAsResource = cz.getName().replace('.', '/')+".class";
|
||||||
|
URL resource = Loader.getResource(nameAsResource);
|
||||||
|
if (resource!= null)
|
||||||
{
|
{
|
||||||
String nameAsResource = cz.getName().replace('.', '/')+".class";
|
Resource r = Resource.newResource(resource);
|
||||||
URL resource = Loader.getResource(nameAsResource);
|
try (InputStream is = r.getInputStream())
|
||||||
if (resource!= null)
|
|
||||||
{
|
{
|
||||||
Resource r = Resource.newResource(resource);
|
scanClass(handlers, null, is);
|
||||||
try (InputStream is = r.getInputStream())
|
|
||||||
{
|
|
||||||
scanClass(handlers, null, is);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (visitSuperClasses)
|
if (visitSuperClasses)
|
||||||
cz = cz.getSuperclass();
|
cz = cz.getSuperclass();
|
||||||
else
|
else
|
||||||
|
@ -622,13 +617,13 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (Set<? extends Handler> handlers, String[] classNames, ClassNameResolver resolver)
|
public void parse (Set<? extends Handler> handlers, String[] classNames)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (classNames == null)
|
if (classNames == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parse(handlers, Arrays.asList(classNames), resolver);
|
parse(handlers, Arrays.asList(classNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -640,7 +635,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (Set<? extends Handler> handlers, List<String> classNames, ClassNameResolver resolver)
|
public void parse (Set<? extends Handler> handlers, List<String> classNames)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
MultiException me = new MultiException();
|
MultiException me = new MultiException();
|
||||||
|
@ -649,7 +644,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((resolver == null) || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s))))
|
if (!isParsed(s))
|
||||||
{
|
{
|
||||||
s = s.replace('.', '/')+".class";
|
s = s.replace('.', '/')+".class";
|
||||||
URL resource = Loader.getResource(s);
|
URL resource = Loader.getResource(s);
|
||||||
|
@ -680,7 +675,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
protected void parseDir (Set<? extends Handler> handlers, Resource dir, ClassNameResolver resolver)
|
protected void parseDir (Set<? extends Handler> handlers, Resource dir)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
// skip dirs whose name start with . (ie hidden)
|
// skip dirs whose name start with . (ie hidden)
|
||||||
|
@ -696,7 +691,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
Resource res = dir.addPath(files[f]);
|
Resource res = dir.addPath(files[f]);
|
||||||
if (res.isDirectory())
|
if (res.isDirectory())
|
||||||
parseDir(handlers, res, resolver);
|
parseDir(handlers, res);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//we've already verified the directories, so just verify the class file name
|
//we've already verified the directories, so just verify the class file name
|
||||||
|
@ -706,7 +701,7 @@ public class AnnotationParser
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String name = res.getName();
|
String name = res.getName();
|
||||||
if ((resolver == null)|| (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name))))
|
if (!isParsed(name))
|
||||||
{
|
{
|
||||||
Resource r = Resource.newResource(res.getURL());
|
Resource r = Resource.newResource(res.getURL());
|
||||||
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class {}", r);};
|
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class {}", r);};
|
||||||
|
@ -744,7 +739,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (final Set<? extends Handler> handlers, ClassLoader loader, boolean visitParents, boolean nullInclusive, final ClassNameResolver resolver)
|
public void parse (final Set<? extends Handler> handlers, ClassLoader loader, boolean visitParents, boolean nullInclusive)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (loader==null)
|
if (loader==null)
|
||||||
|
@ -762,7 +757,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parseJarEntry(handlers, Resource.newResource(jarUri), entry, resolver);
|
parseJarEntry(handlers, Resource.newResource(jarUri), entry);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -785,7 +780,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (final Set<? extends Handler> handlers, final URI[] uris, final ClassNameResolver resolver)
|
public void parse (final Set<? extends Handler> handlers, final URI[] uris)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (uris==null)
|
if (uris==null)
|
||||||
|
@ -797,7 +792,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parse(handlers, uri, resolver);
|
parse(handlers, uri);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -815,13 +810,13 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (final Set<? extends Handler> handlers, URI uri, final ClassNameResolver resolver)
|
public void parse (final Set<? extends Handler> handlers, URI uri)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parse (handlers, Resource.newResource(uri), resolver);
|
parse (handlers, Resource.newResource(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -833,7 +828,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
public void parse (final Set<? extends Handler> handlers, Resource r, final ClassNameResolver resolver)
|
public void parse (final Set<? extends Handler> handlers, Resource r)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (r == null)
|
if (r == null)
|
||||||
|
@ -841,14 +836,14 @@ public class AnnotationParser
|
||||||
|
|
||||||
if (r.exists() && r.isDirectory())
|
if (r.exists() && r.isDirectory())
|
||||||
{
|
{
|
||||||
parseDir(handlers, r, resolver);
|
parseDir(handlers, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fullname = r.toString();
|
String fullname = r.toString();
|
||||||
if (fullname.endsWith(".jar"))
|
if (fullname.endsWith(".jar"))
|
||||||
{
|
{
|
||||||
parseJar(handlers, r, resolver);
|
parseJar(handlers, r);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,7 +870,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
protected void parseJar (Set<? extends Handler> handlers, Resource jarResource, final ClassNameResolver resolver)
|
protected void parseJar (Set<? extends Handler> handlers, Resource jarResource)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (jarResource == null)
|
if (jarResource == null)
|
||||||
|
@ -899,7 +894,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parseJarEntry(handlers, jarResource, entry, resolver);
|
parseJarEntry(handlers, jarResource, entry);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +925,7 @@ public class AnnotationParser
|
||||||
* @param resolver the class name resolver
|
* @param resolver the class name resolver
|
||||||
* @throws Exception if unable to parse
|
* @throws Exception if unable to parse
|
||||||
*/
|
*/
|
||||||
protected void parseJarEntry (Set<? extends Handler> handlers, Resource jar, JarEntry entry, final ClassNameResolver resolver)
|
protected void parseJarEntry (Set<? extends Handler> handlers, Resource jar, JarEntry entry)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (jar == null || entry == null)
|
if (jar == null || entry == null)
|
||||||
|
@ -947,9 +942,7 @@ public class AnnotationParser
|
||||||
{
|
{
|
||||||
String shortName = name.replace('/', '.').substring(0,name.length()-6);
|
String shortName = name.replace('/', '.').substring(0,name.length()-6);
|
||||||
|
|
||||||
if ((resolver == null)
|
if (!isParsed(shortName))
|
||||||
||
|
|
||||||
(!resolver.isExcluded(shortName) && (!isParsed(shortName) || resolver.shouldOverride(shortName))))
|
|
||||||
{
|
{
|
||||||
Resource clazz = Resource.newResource("jar:"+jar.getURI()+"!/"+name);
|
Resource clazz = Resource.newResource("jar:"+jar.getURI()+"!/"+name);
|
||||||
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class from jar {}", clazz);};
|
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class from jar {}", clazz);};
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2016 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.annotations;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface ClassNameResolver
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Based on the execution context, should the class represented
|
|
||||||
* by "name" be excluded from consideration?
|
|
||||||
* @param name the name to test
|
|
||||||
* @return true if classname is excluded
|
|
||||||
*/
|
|
||||||
public boolean isExcluded (String name);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on the execution context, if a duplicate class
|
|
||||||
* represented by "name" is detected, should the existing
|
|
||||||
* one be overridden or not?
|
|
||||||
* @param name the name to test
|
|
||||||
* @return true if name should be overridden
|
|
||||||
*/
|
|
||||||
public boolean shouldOverride (String name);
|
|
||||||
}
|
|
|
@ -74,6 +74,12 @@ public class TestAnnotationInheritance
|
||||||
return;
|
return;
|
||||||
annotatedMethods.add(info.getClassInfo().getClassName()+"."+info.getMethodName());
|
annotatedMethods.add(info.getClassInfo().getClassName()+"."+info.getMethodName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return annotatedClassNames.toString()+annotatedMethods+annotatedFields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -93,18 +99,7 @@ public class TestAnnotationInheritance
|
||||||
|
|
||||||
SampleHandler handler = new SampleHandler();
|
SampleHandler handler = new SampleHandler();
|
||||||
AnnotationParser parser = new AnnotationParser();
|
AnnotationParser parser = new AnnotationParser();
|
||||||
parser.parse(Collections.singleton(handler), classNames, new ClassNameResolver ()
|
parser.parse(Collections.singleton(handler), classNames);
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//check we got 2 class annotations
|
//check we got 2 class annotations
|
||||||
assertEquals(2, handler.annotatedClassNames.size());
|
assertEquals(2, handler.annotatedClassNames.size());
|
||||||
|
@ -129,18 +124,7 @@ public class TestAnnotationInheritance
|
||||||
{
|
{
|
||||||
SampleHandler handler = new SampleHandler();
|
SampleHandler handler = new SampleHandler();
|
||||||
AnnotationParser parser = new AnnotationParser();
|
AnnotationParser parser = new AnnotationParser();
|
||||||
parser.parse(Collections.singleton(handler), ClassB.class, new ClassNameResolver ()
|
parser.parse(Collections.singleton(handler), ClassB.class, true);
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
//check we got 2 class annotations
|
//check we got 2 class annotations
|
||||||
assertEquals(2, handler.annotatedClassNames.size());
|
assertEquals(2, handler.annotatedClassNames.size());
|
||||||
|
@ -160,46 +144,6 @@ public class TestAnnotationInheritance
|
||||||
assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
|
assertEquals("org.eclipse.jetty.annotations.ClassA.m", handler.annotatedFields.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExclusions() throws Exception
|
|
||||||
{
|
|
||||||
AnnotationParser parser = new AnnotationParser();
|
|
||||||
SampleHandler handler = new SampleHandler();
|
|
||||||
parser.parse(Collections.singleton(handler), ClassA.class.getName(), new ClassNameResolver()
|
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals (0, handler.annotatedClassNames.size());
|
|
||||||
assertEquals (0, handler.annotatedFields.size());
|
|
||||||
assertEquals (0, handler.annotatedMethods.size());
|
|
||||||
|
|
||||||
handler.annotatedClassNames.clear();
|
|
||||||
handler.annotatedFields.clear();
|
|
||||||
handler.annotatedMethods.clear();
|
|
||||||
|
|
||||||
parser.parse (Collections.singleton(handler), ClassA.class.getName(), new ClassNameResolver()
|
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals (1, handler.annotatedClassNames.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTypeInheritanceHandling() throws Exception
|
public void testTypeInheritanceHandling() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -218,7 +162,7 @@ public class TestAnnotationInheritance
|
||||||
classNames.add(InterfaceD.class.getName());
|
classNames.add(InterfaceD.class.getName());
|
||||||
classNames.add(Foo.class.getName());
|
classNames.add(Foo.class.getName());
|
||||||
|
|
||||||
parser.parse(Collections.singleton(handler), classNames, null);
|
parser.parse(Collections.singleton(handler), classNames);
|
||||||
|
|
||||||
assertNotNull(map);
|
assertNotNull(map);
|
||||||
assertFalse(map.isEmpty());
|
assertFalse(map.isEmpty());
|
||||||
|
|
|
@ -111,19 +111,7 @@ public class TestAnnotationParser
|
||||||
}
|
}
|
||||||
|
|
||||||
//long start = System.currentTimeMillis();
|
//long start = System.currentTimeMillis();
|
||||||
parser.parse(Collections.singleton(new SampleAnnotationHandler()), classNames,new ClassNameResolver()
|
parser.parse(Collections.singleton(new SampleAnnotationHandler()), classNames);
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
//long end = System.currentTimeMillis();
|
//long end = System.currentTimeMillis();
|
||||||
|
|
||||||
//System.err.println("Time to parse class: " + ((end - start)));
|
//System.err.println("Time to parse class: " + ((end - start)));
|
||||||
|
@ -162,7 +150,7 @@ public class TestAnnotationParser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.parse(Collections.singleton(new MultiAnnotationHandler()), classNames,null);
|
parser.parse(Collections.singleton(new MultiAnnotationHandler()), classNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -171,7 +159,7 @@ public class TestAnnotationParser
|
||||||
File badClassesJar = MavenTestingUtils.getTestResourceFile("bad-classes.jar");
|
File badClassesJar = MavenTestingUtils.getTestResourceFile("bad-classes.jar");
|
||||||
AnnotationParser parser = new AnnotationParser();
|
AnnotationParser parser = new AnnotationParser();
|
||||||
Set<Handler> emptySet = Collections.emptySet();
|
Set<Handler> emptySet = Collections.emptySet();
|
||||||
parser.parse(emptySet, badClassesJar.toURI(),null);
|
parser.parse(emptySet, badClassesJar.toURI());
|
||||||
// only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
|
// only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +184,7 @@ public class TestAnnotationParser
|
||||||
AnnotationParser parser = new AnnotationParser();
|
AnnotationParser parser = new AnnotationParser();
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
parser.parse(Collections.singleton(tracker), basedir.toURI(),null);
|
parser.parse(Collections.singleton(tracker), basedir.toURI());
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
Assert.assertThat("Found Class", tracker.foundClasses, contains(ClassA.class.getName()));
|
Assert.assertThat("Found Class", tracker.foundClasses, contains(ClassA.class.getName()));
|
||||||
|
|
|
@ -73,18 +73,7 @@ public class TestServletAnnotations
|
||||||
|
|
||||||
TestWebServletAnnotationHandler handler = new TestWebServletAnnotationHandler(wac, results);
|
TestWebServletAnnotationHandler handler = new TestWebServletAnnotationHandler(wac, results);
|
||||||
|
|
||||||
parser.parse(Collections.singleton(handler), classes, new ClassNameResolver ()
|
parser.parse(Collections.singleton(handler), classes);
|
||||||
{
|
|
||||||
public boolean isExcluded(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride(String name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertEquals(1, results.size());
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
[description]
|
||||||
|
Enables GCloud Datastore API and implementation
|
||||||
|
|
||||||
|
[depends]
|
||||||
|
gcloud
|
||||||
|
jcl-api
|
||||||
|
jcl-impl
|
||||||
|
|
||||||
|
[files]
|
||||||
|
maven://com.google.cloud/google-cloud-datastore/0.3.0|lib/gcloud/google-cloud-datastore-0.3.0.jar
|
||||||
|
maven://com.google.cloud/google-cloud-core/0.3.0|lib/gcloud/google-cloud-core-0.3.0.jar
|
||||||
|
maven://com.google.auth/google-auth-library-credentials/0.3.1|lib/gcloud/google-auth-library-credentials-0.3.1.jar
|
||||||
|
maven://com.google.auth/google-auth-library-oauth2-http/0.3.1|lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
|
||||||
|
maven://com.google.http-client/google-http-client-jackson2/1.19.0|lib/gcloud/google-http-client-jackson2-1.19.0.jar
|
||||||
|
maven://com.fasterxml.jackson.core/jackson-core/2.1.3|lib/gcloud/jackson-core-2.1.3.jar
|
||||||
|
maven://com.google.http-client/google-http-client/1.21.0|lib/gcloud/google-http-client-1.21.0.jar
|
||||||
|
maven://com.google.code.findbugs/jsr305/1.3.9|lib/gcloud/jsr305-1.3.9.jar
|
||||||
|
maven://org.apache.httpcomponents/httpclient/4.0.1|lib/gcloud/httpclient-4.0.1.jar
|
||||||
|
maven://org.apache.httpcomponents/httpcore/4.0.1|lib/gcloud/httpcore-4.0.1.jar
|
||||||
|
maven://commons-codec/commons-codec/1.3|lib/gcloud/commons-codec-1.3.jar
|
||||||
|
maven://com.google.oauth-client/google-oauth-client/1.21.0|lib/gcloud/google-oauth-client-1.21.0.jar
|
||||||
|
maven://com.google.guava/guava/19.0|lib/gcloud/guava-19.0.jar
|
||||||
|
maven://com.google.api-client/google-api-client-appengine/1.21.0|lib/gcloud/google-api-client-appengine-1.21.0.jar
|
||||||
|
maven://com.google.oauth-client/google-oauth-client-appengine/1.21.0|lib/gcloud/google-oauth-client-appengine-1.21.0.jar
|
||||||
|
maven://com.google.oauth-client/google-oauth-client-servlet/1.21.0|lib/gcloud/google-oauth-client-servlet-1.21.0.jar
|
||||||
|
maven://com.google.http-client/google-http-client-jdo/1.21.0|lib/gcloud/google-http-client-jdo-1.21.0.jar
|
||||||
|
maven://com.google.api-client/google-api-client-servlet/1.21.0|lib/gcloud/google-api-client-servlet-1.21.0.jar
|
||||||
|
maven://javax.jdo/jdo2-api/2.3-eb|lib/gcloud/jdo2-api-2.3-eb.jar
|
||||||
|
maven://javax.transaction/transaction-api/1.1|lib/gcloud/transaction-api-1.1.jar
|
||||||
|
maven://com.google.http-client/google-http-client-appengine/1.21.0|lib/gcloud/google-http-client-appengine-1.21.0.jar
|
||||||
|
maven://com.google.http-client/google-http-client-jackson/1.21.0|lib/gcloud/google-http-client-jackson-1.21.0.jar
|
||||||
|
maven://org.codehaus.jackson/jackson-core-asl/1.9.11|lib/gcloud/jackson-core-asl-1.9.11.jar
|
||||||
|
maven://joda-time/joda-time/2.9.2|lib/gcloud/joda-time-2.9.2.jar
|
||||||
|
maven://com.google.protobuf/protobuf-java/3.0.0-beta-3|lib/gcloud/protobuf-java-3.0.0-beta-3.jar
|
||||||
|
maven://com.google.api/gax/0.0.16|lib/gcloud/gax-0.0.16.jar
|
||||||
|
maven://io.grpc/grpc-all/0.15.0|lib/gcloud/grpc-all-0.15.0.jar
|
||||||
|
maven://io.grpc/grpc-auth/0.15.0|lib/gcloud/grpc-auth-0.15.0.jar
|
||||||
|
maven://io.grpc/grpc-netty/0.15.0|lib/gcloud/grpc-netty-0.15.0.jar
|
||||||
|
maven://io.netty/netty-codec-http2/4.1.1.Final|lib/gcloud/netty-codec-http2-4.1.1.jar
|
||||||
|
maven://io.netty/netty-codec-http/4.1.1.Final|lib/gcloud/netty-codec-http-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-codec/4.1.1.Final|lib/gcloud/netty-codec-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-handler/4.1.1.Final|lib/gcloud/netty-handler-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-buffer/4.1.1.Final|lib/gcloud/netty-buffer-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-common/4.1.1.Final|lib/gcloud/netty-common-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-transport/4.1.1.Final|lib/gcloud/netty-transport-4.1.1.Final.jar
|
||||||
|
maven://io.netty/netty-resolver/4.1.1.Final|lib/gcloud/netty-resolver-4.1.1.Final.jar
|
||||||
|
maven://io.grpc/grpc-okhttp/0.15.0|lib/gcloud/grpc-okhttp-0.15.0.jar
|
||||||
|
maven://com.squareup.okio/okio/1.6.0|lib/gcloud/okio-1.6.0.jar
|
||||||
|
maven://com.squareup.okhttp/okhttp/2.5.0|lib/gcloud/okhttp-2.5.0.jar
|
||||||
|
maven://io.grpc/grpc-protobuf-nano/0.15.0|lib/gcloud/grpc-protobuf-nano-0.15.0.jar
|
||||||
|
maven://com.google.protobuf.nano/protobuf-javanano/3.0.0-alpha-5|lib/gcloud/protobuf-javanano-3.0.0-alpha-5.jar
|
||||||
|
maven://io.grpc/grpc-stub/0.15.0|lib/gcloud/grpc-stub-0.15.0.jar
|
||||||
|
maven://io.grpc/grpc-protobuf/0.15.0|lib/gcloud/grpc-protobuf-0.15.0.jar
|
||||||
|
maven://com.google.protobuf/protobuf-java-util/3.0.0-beta-3|lib/gcloud/protobuf-java-util-3.0.0-beta-3.jar
|
||||||
|
maven://com.google.code.gson/gson/2.3|lib/gcloud/gson-2.3.jar
|
||||||
|
maven://io.grpc/grpc-protobuf-lite/0.15.0|lib/gcloud/grpc-protobuf-lite-0.15.0.jar
|
||||||
|
maven://io.grpc/grpc-core/0.15.0|lib/gcloud/grpc-core-0.15.0.jar
|
||||||
|
maven://com.google.auto.value/auto-value/1.1|lib/gcloud/auto-value-1.1.jar
|
||||||
|
maven://com.google.inject/guice/4.0|lib/gcloud/guice-4.0.jar
|
||||||
|
maven://javax.inject/javax.inject/1|lib/gcloud/javax.inject-1.jar
|
||||||
|
maven://aopalliance/aopalliance/1.0|lib/gcloud/aopalliance-1.0.jar
|
||||||
|
maven://com.google.api.grpc/grpc-google-common-protos/0.0.7|lib/gcloud/grpc-google-common-protos-0.0.7.jar
|
||||||
|
maven://org.json/json/20151123|lib/gcloud/json-20151123.jar
|
||||||
|
maven://com.google.cloud.datastore/datastore-v1-protos/1.0.1|lib/gcloud/datastore-v1-protos-1.0.1-beta.jar
|
||||||
|
maven://com.google.cloud.datastore/datastore-v1-proto-client/1.1.0|lib/gcloud/datastore-v1-proto-client-1.1.0.jar
|
||||||
|
maven://com.google.http-client/google-http-client-protobuf/1.20.0|lib/gcloud/google-http-client-protobuf-1.20.0.jar
|
||||||
|
maven://com.google.api-client/google-api-client/1.20.0|lib/gcloud/google-api-client-1.20.0.jar
|
||||||
|
maven://com.google.guava/guava-jdk5/13.0|lib/gcloud/guava-jdk5-13.0.jar
|
|
@ -0,0 +1,23 @@
|
||||||
|
[description]
|
||||||
|
Control GCloud API classpath
|
||||||
|
|
||||||
|
[files]
|
||||||
|
basehome:modules/gcloud/gcloud.xml|etc/gcloud.xml
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
lib/gcloud/*.jar
|
||||||
|
|
||||||
|
[xml]
|
||||||
|
etc/gcloud.xml
|
||||||
|
|
||||||
|
[license]
|
||||||
|
GCloudDatastore is an open source project hosted on Github and released under the Apache 2.0 license.
|
||||||
|
https://github.com/GoogleCloudPlatform/gcloud-java
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
[ini-template]
|
||||||
|
## Configure the jars and packages exposed or hidden from webapps by comma separated
|
||||||
|
## list of classnames, package names or file URIs (See ClasspathPattern)
|
||||||
|
## Eg. to hide all gcloud dependencies other than the com.google.guava package:
|
||||||
|
## Default is all jars in lib/gcloud are hidden
|
||||||
|
# gcloud.addServerClasses=file:${jetty.base}/lib/gcloud,-com.google.guava.
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||||
|
|
||||||
|
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||||
|
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<!-- Configure a GCloud classpath exposed to webapps -->
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<Call class="org.eclipse.jetty.webapp.WebAppContext" name="addServerClasses">
|
||||||
|
<Arg><Ref refid="Server"/></Arg>
|
||||||
|
<Arg>
|
||||||
|
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||||
|
<Arg><Property name="gcloud.addServerClasses"><Default>file:${jetty.base}/lib/gcloud</Default></Property></Arg>
|
||||||
|
</Call>
|
||||||
|
</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
</Configure>
|
|
@ -5,88 +5,20 @@ Enables GCloudDatastore session management.
|
||||||
session-store
|
session-store
|
||||||
|
|
||||||
[depends]
|
[depends]
|
||||||
|
gcloud-datastore
|
||||||
annotations
|
annotations
|
||||||
webapp
|
webapp
|
||||||
sessions
|
sessions
|
||||||
jcl-api
|
|
||||||
jcl-impl
|
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
basehome:etc/sessions/gcloud/index.yaml|etc/index.yaml
|
basehome:modules/gcloud/index.yaml|etc/index.yaml
|
||||||
maven://com.google.cloud/google-cloud-datastore/0.3.0|lib/gcloud/google-cloud-datastore-0.3.0.jar
|
|
||||||
maven://com.google.cloud/google-cloud-core/0.3.0|lib/gcloud/google-cloud-core-0.3.0.jar
|
|
||||||
maven://com.google.auth/google-auth-library-credentials/0.3.1|lib/gcloud/google-auth-library-credentials-0.3.1.jar
|
|
||||||
maven://com.google.auth/google-auth-library-oauth2-http/0.3.1|lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
|
|
||||||
maven://com.google.http-client/google-http-client-jackson2/1.19.0|lib/gcloud/google-http-client-jackson2-1.19.0.jar
|
|
||||||
maven://com.fasterxml.jackson.core/jackson-core/2.1.3|lib/gcloud/jackson-core-2.1.3.jar
|
|
||||||
maven://com.google.http-client/google-http-client/1.21.0|lib/gcloud/google-http-client-1.21.0.jar
|
|
||||||
maven://com.google.code.findbugs/jsr305/1.3.9|lib/gcloud/jsr305-1.3.9.jar
|
|
||||||
maven://org.apache.httpcomponents/httpclient/4.0.1|lib/gcloud/httpclient-4.0.1.jar
|
|
||||||
maven://org.apache.httpcomponents/httpcore/4.0.1|lib/gcloud/httpcore-4.0.1.jar
|
|
||||||
maven://commons-codec/commons-codec/1.3|lib/gcloud/commons-codec-1.3.jar
|
|
||||||
maven://com.google.oauth-client/google-oauth-client/1.21.0|lib/gcloud/google-oauth-client-1.21.0.jar
|
|
||||||
maven://com.google.guava/guava/19.0|lib/gcloud/guava-19.0.jar
|
|
||||||
maven://com.google.api-client/google-api-client-appengine/1.21.0|lib/gcloud/google-api-client-appengine-1.21.0.jar
|
|
||||||
maven://com.google.oauth-client/google-oauth-client-appengine/1.21.0|lib/gcloud/google-oauth-client-appengine-1.21.0.jar
|
|
||||||
maven://com.google.oauth-client/google-oauth-client-servlet/1.21.0|lib/gcloud/google-oauth-client-servlet-1.21.0.jar
|
|
||||||
maven://com.google.http-client/google-http-client-jdo/1.21.0|lib/gcloud/google-http-client-jdo-1.21.0.jar
|
|
||||||
maven://com.google.api-client/google-api-client-servlet/1.21.0|lib/gcloud/google-api-client-servlet-1.21.0.jar
|
|
||||||
maven://javax.jdo/jdo2-api/2.3-eb|lib/gcloud/jdo2-api-2.3-eb.jar
|
|
||||||
maven://javax.transaction/transaction-api/1.1|lib/gcloud/transaction-api-1.1.jar
|
|
||||||
maven://com.google.http-client/google-http-client-appengine/1.21.0|lib/gcloud/google-http-client-appengine-1.21.0.jar
|
|
||||||
maven://com.google.http-client/google-http-client-jackson/1.21.0|lib/gcloud/google-http-client-jackson-1.21.0.jar
|
|
||||||
maven://org.codehaus.jackson/jackson-core-asl/1.9.11|lib/gcloud/jackson-core-asl-1.9.11.jar
|
|
||||||
maven://joda-time/joda-time/2.9.2|lib/gcloud/joda-time-2.9.2.jar
|
|
||||||
maven://com.google.protobuf/protobuf-java/3.0.0-beta-3|lib/gcloud/protobuf-java-3.0.0-beta-3.jar
|
|
||||||
maven://com.google.api/gax/0.0.16|lib/gcloud/gax-0.0.16.jar
|
|
||||||
maven://io.grpc/grpc-all/0.15.0|lib/gcloud/grpc-all-0.15.0.jar
|
|
||||||
maven://io.grpc/grpc-auth/0.15.0|lib/gcloud/grpc-auth-0.15.0.jar
|
|
||||||
maven://io.grpc/grpc-netty/0.15.0|lib/gcloud/grpc-netty-0.15.0.jar
|
|
||||||
maven://io.netty/netty-codec-http2/4.1.1.Final|lib/gcloud/netty-codec-http2-4.1.1.jar
|
|
||||||
maven://io.netty/netty-codec-http/4.1.1.Final|lib/gcloud/netty-codec-http-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-codec/4.1.1.Final|lib/gcloud/netty-codec-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-handler/4.1.1.Final|lib/gcloud/netty-handler-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-buffer/4.1.1.Final|lib/gcloud/netty-buffer-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-common/4.1.1.Final|lib/gcloud/netty-common-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-transport/4.1.1.Final|lib/gcloud/netty-transport-4.1.1.Final.jar
|
|
||||||
maven://io.netty/netty-resolver/4.1.1.Final|lib/gcloud/netty-resolver-4.1.1.Final.jar
|
|
||||||
maven://io.grpc/grpc-okhttp/0.15.0|lib/gcloud/grpc-okhttp-0.15.0.jar
|
|
||||||
maven://com.squareup.okio/okio/1.6.0|lib/gcloud/okio-1.6.0.jar
|
|
||||||
maven://com.squareup.okhttp/okhttp/2.5.0|lib/gcloud/okhttp-2.5.0.jar
|
|
||||||
maven://io.grpc/grpc-protobuf-nano/0.15.0|lib/gcloud/grpc-protobuf-nano-0.15.0.jar
|
|
||||||
maven://com.google.protobuf.nano/protobuf-javanano/3.0.0-alpha-5|lib/gcloud/protobuf-javanano-3.0.0-alpha-5.jar
|
|
||||||
maven://io.grpc/grpc-stub/0.15.0|lib/gcloud/grpc-stub-0.15.0.jar
|
|
||||||
maven://io.grpc/grpc-protobuf/0.15.0|lib/gcloud/grpc-protobuf-0.15.0.jar
|
|
||||||
maven://com.google.protobuf/protobuf-java-util/3.0.0-beta-3|lib/gcloud/protobuf-java-util-3.0.0-beta-3.jar
|
|
||||||
maven://com.google.code.gson/gson/2.3|lib/gcloud/gson-2.3.jar
|
|
||||||
maven://io.grpc/grpc-protobuf-lite/0.15.0|lib/gcloud/grpc-protobuf-lite-0.15.0.jar
|
|
||||||
maven://io.grpc/grpc-core/0.15.0|lib/gcloud/grpc-core-0.15.0.jar
|
|
||||||
maven://com.google.auto.value/auto-value/1.1|lib/gcloud/auto-value-1.1.jar
|
|
||||||
maven://com.google.inject/guice/4.0|lib/gcloud/guice-4.0.jar
|
|
||||||
maven://javax.inject/javax.inject/1|lib/gcloud/javax.inject-1.jar
|
|
||||||
maven://aopalliance/aopalliance/1.0|lib/gcloud/aopalliance-1.0.jar
|
|
||||||
maven://com.google.api.grpc/grpc-google-common-protos/0.0.7|lib/gcloud/grpc-google-common-protos-0.0.7.jar
|
|
||||||
maven://org.json/json/20151123|lib/gcloud/json-20151123.jar
|
|
||||||
maven://com.google.cloud.datastore/datastore-v1-protos/1.0.1|lib/gcloud/datastore-v1-protos-1.0.1-beta.jar
|
|
||||||
maven://com.google.cloud.datastore/datastore-v1-proto-client/1.1.0|lib/gcloud/datastore-v1-proto-client-1.1.0.jar
|
|
||||||
maven://com.google.http-client/google-http-client-protobuf/1.20.0|lib/gcloud/google-http-client-protobuf-1.20.0.jar
|
|
||||||
maven://com.google.api-client/google-api-client/1.20.0|lib/gcloud/google-api-client-1.20.0.jar
|
|
||||||
maven://com.google.guava/guava-jdk5/13.0|lib/gcloud/guava-jdk5-13.0.jar
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
lib/jetty-gcloud-session-manager-${jetty.version}.jar
|
lib/jetty-gcloud-session-manager-${jetty.version}.jar
|
||||||
lib/gcloud/*.jar
|
|
||||||
|
|
||||||
[xml]
|
[xml]
|
||||||
etc/sessions/gcloud/session-store.xml
|
etc/sessions/gcloud/session-store.xml
|
||||||
|
|
||||||
[license]
|
|
||||||
GCloudDatastore is an open source project hosted on Github and released under the Apache 2.0 license.
|
|
||||||
https://github.com/GoogleCloudPlatform/gcloud-java
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
|
|
||||||
[ini-template]
|
[ini-template]
|
||||||
|
|
||||||
## GCloudDatastore Session config
|
## GCloudDatastore Session config
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<name>Jetty :: GCloud</name>
|
<name>Jetty :: GCloud</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<gcloud.version>0.3.0</gcloud.version>
|
<gcloud.version>0.4.0</gcloud.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|
|
@ -18,11 +18,14 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.osgi.annotations;
|
package org.eclipse.jetty.osgi.annotations;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContainerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.annotations.AnnotationParser.Handler;
|
import org.eclipse.jetty.annotations.AnnotationParser.Handler;
|
||||||
import org.eclipse.jetty.annotations.ClassNameResolver;
|
|
||||||
import org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration;
|
import org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration;
|
||||||
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -44,9 +47,9 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot
|
||||||
public class BundleParserTask extends ParserTask
|
public class BundleParserTask extends ParserTask
|
||||||
{
|
{
|
||||||
|
|
||||||
public BundleParserTask (AnnotationParser parser, Set<? extends Handler>handlers, Resource resource, ClassNameResolver resolver)
|
public BundleParserTask (AnnotationParser parser, Set<? extends Handler>handlers, Resource resource)
|
||||||
{
|
{
|
||||||
super(parser, handlers, resource, resolver);
|
super(parser, handlers, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Void call() throws Exception
|
public Void call() throws Exception
|
||||||
|
@ -57,7 +60,7 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot
|
||||||
Bundle bundle = osgiAnnotationParser.getBundle(_resource);
|
Bundle bundle = osgiAnnotationParser.getBundle(_resource);
|
||||||
if (_stat != null)
|
if (_stat != null)
|
||||||
_stat.start();
|
_stat.start();
|
||||||
osgiAnnotationParser.parse(_handlers, bundle, _resolver);
|
osgiAnnotationParser.parse(_handlers, bundle);
|
||||||
if (_stat != null)
|
if (_stat != null)
|
||||||
_stat.end();
|
_stat.end();
|
||||||
}
|
}
|
||||||
|
@ -79,6 +82,17 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot
|
||||||
return new AnnotationParser();
|
return new AnnotationParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resource getJarFor(ServletContainerInitializer service) throws MalformedURLException, IOException
|
||||||
|
{
|
||||||
|
Resource resource = super.getJarFor(service);
|
||||||
|
// TODO This is not correct, but implemented like this to be bug for bug compatible
|
||||||
|
// with previous implementation that could only handle actual jars and not bundles.
|
||||||
|
if (resource!=null && !resource.toString().endsWith(".jar"))
|
||||||
|
return null;
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here is the order in which jars and osgi artifacts are scanned for discoverable annotations.
|
* Here is the order in which jars and osgi artifacts are scanned for discoverable annotations.
|
||||||
* <ol>
|
* <ol>
|
||||||
|
@ -195,47 +209,13 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot
|
||||||
handlers.add(_classInheritanceHandler);
|
handlers.add(_classInheritanceHandler);
|
||||||
handlers.addAll(_containerInitializerAnnotationHandlers);
|
handlers.addAll(_containerInitializerAnnotationHandlers);
|
||||||
|
|
||||||
ClassNameResolver classNameResolver = createClassNameResolver(context);
|
|
||||||
if (_parserTasks != null)
|
if (_parserTasks != null)
|
||||||
{
|
{
|
||||||
BundleParserTask task = new BundleParserTask(parser, handlers, bundleRes, classNameResolver);
|
BundleParserTask task = new BundleParserTask(parser, handlers, bundleRes);
|
||||||
_parserTasks.add(task);
|
_parserTasks.add(task);
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
task.setStatistic(new TimeStatistic());
|
task.setStatistic(new TimeStatistic());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the same classname resolver than for the webInfjar scanner
|
|
||||||
* @param context the web app context
|
|
||||||
* @return the class name resolver
|
|
||||||
*/
|
|
||||||
protected ClassNameResolver createClassNameResolver(final WebAppContext context)
|
|
||||||
{
|
|
||||||
return createClassNameResolver(context,true,false,false,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ClassNameResolver createClassNameResolver(final WebAppContext context,
|
|
||||||
final boolean excludeSysClass, final boolean excludeServerClass, final boolean excludeEverythingElse,
|
|
||||||
final boolean overrideIsParenLoaderIsPriority)
|
|
||||||
{
|
|
||||||
return new ClassNameResolver ()
|
|
||||||
{
|
|
||||||
public boolean isExcluded (String name)
|
|
||||||
{
|
|
||||||
if (context.isSystemClass(name)) return excludeSysClass;
|
|
||||||
if (context.isServerClass(name)) return excludeServerClass;
|
|
||||||
return excludeEverythingElse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
|
||||||
{
|
|
||||||
//looking at system classpath
|
|
||||||
if (context.isParentLoaderPriority())
|
|
||||||
return overrideIsParenLoaderIsPriority;
|
|
||||||
return !overrideIsParenLoaderIsPriority;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import java.util.StringTokenizer;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.eclipse.jetty.annotations.ClassNameResolver;
|
|
||||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
||||||
import org.eclipse.jetty.util.ConcurrentHashSet;
|
import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
@ -85,7 +84,7 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void parse (Set<? extends Handler> handlers, URI[] uris, ClassNameResolver resolver)
|
public void parse (Set<? extends Handler> handlers, URI[] uris)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
for (URI uri : uris)
|
for (URI uri : uris)
|
||||||
|
@ -99,16 +98,16 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
|
||||||
}
|
}
|
||||||
//a jar in WEB-INF/lib or the WEB-INF/classes
|
//a jar in WEB-INF/lib or the WEB-INF/classes
|
||||||
//use the behavior of the super class for a standard jar.
|
//use the behavior of the super class for a standard jar.
|
||||||
super.parse(handlers, new URI[] {uri},resolver);
|
super.parse(handlers, new URI[] {uri});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parse(handlers, associatedBundle,resolver);
|
parse(handlers, associatedBundle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void parse(Set<? extends Handler> handlers, Bundle bundle, ClassNameResolver resolver)
|
protected void parse(Set<? extends Handler> handlers, Bundle bundle)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
URI uri = _bundleToUri.get(bundle);
|
URI uri = _bundleToUri.get(bundle);
|
||||||
|
@ -205,7 +204,7 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
|
||||||
}
|
}
|
||||||
//transform into a classname to pass to the resolver
|
//transform into a classname to pass to the resolver
|
||||||
String shortName = name.replace('/', '.').substring(0,name.length()-6);
|
String shortName = name.replace('/', '.').substring(0,name.length()-6);
|
||||||
if ((resolver == null) || (!resolver.isExcluded(shortName) && (!isParsed(shortName) || resolver.shouldOverride(shortName))))
|
if (!isParsed(shortName))
|
||||||
{
|
{
|
||||||
try (InputStream classInputStream = classUrl.openStream())
|
try (InputStream classInputStream = classUrl.openStream())
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,18 +47,16 @@ public abstract class AbstractOSGiApp extends App
|
||||||
private static final Logger LOG = Log.getLogger(AbstractOSGiApp.class);
|
private static final Logger LOG = Log.getLogger(AbstractOSGiApp.class);
|
||||||
|
|
||||||
protected Bundle _bundle;
|
protected Bundle _bundle;
|
||||||
protected Dictionary _properties;
|
protected Dictionary<?,?> _properties;
|
||||||
protected ServiceRegistration _registration;
|
protected ServiceRegistration _registration;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId)
|
public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId)
|
||||||
{
|
{
|
||||||
super(manager, provider, originId);
|
this (manager, provider, bundle, bundle.getHeaders(), originId);
|
||||||
_properties = bundle.getHeaders();
|
|
||||||
_bundle = bundle;
|
|
||||||
}
|
}
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId)
|
public AbstractOSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary<?,?> properties, String originId)
|
||||||
{
|
{
|
||||||
super(manager, provider, originId);
|
super(manager, provider, originId);
|
||||||
_properties = properties;
|
_properties = properties;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.resource.JarResource;
|
import org.eclipse.jetty.util.resource.JarResource;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.webapp.Configuration;
|
import org.eclipse.jetty.webapp.Configuration;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
|
@ -436,18 +437,23 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contextXmlUrl == null) return;
|
if (contextXmlUrl == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Apply it just as the standard jetty ContextProvider would do
|
// Apply it just as the standard jetty ContextProvider would do
|
||||||
LOG.info("Applying " + contextXmlUrl + " to " + _webApp);
|
LOG.info("Applying " + contextXmlUrl + " to " + _webApp);
|
||||||
|
|
||||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl);
|
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl);
|
||||||
HashMap properties = new HashMap();
|
WebAppClassLoader.runWithServerClassAccess(()->
|
||||||
properties.put("Server", getDeploymentManager().getServer());
|
{
|
||||||
properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString());
|
HashMap<String,String> properties = new HashMap<>();
|
||||||
properties.put(OSGiServerConstants.JETTY_HOME, getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME));
|
xmlConfiguration.getIdMap().put("Server",getDeploymentManager().getServer());
|
||||||
xmlConfiguration.getProperties().putAll(properties);
|
properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString());
|
||||||
xmlConfiguration.configure(_webApp);
|
properties.put(OSGiServerConstants.JETTY_HOME, (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME));
|
||||||
|
xmlConfiguration.getProperties().putAll(properties);
|
||||||
|
xmlConfiguration.configure(_webApp);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -175,7 +175,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
|
||||||
String contextPath = null;
|
String contextPath = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dictionary headers = bundle.getHeaders();
|
Dictionary<String,String> headers = bundle.getHeaders();
|
||||||
|
|
||||||
//does the bundle have a OSGiWebappConstants.JETTY_WAR_FOLDER_PATH
|
//does the bundle have a OSGiWebappConstants.JETTY_WAR_FOLDER_PATH
|
||||||
String resourcePath = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH, OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers);
|
String resourcePath = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH, OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH, headers);
|
||||||
|
@ -217,7 +217,7 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
|
||||||
{
|
{
|
||||||
//Could be a static webapp with no web.xml
|
//Could be a static webapp with no web.xml
|
||||||
String base = ".";
|
String base = ".";
|
||||||
contextPath = (String)headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
contextPath = headers.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||||
String originId = getOriginId(bundle,base);
|
String originId = getOriginId(bundle,base);
|
||||||
|
|
||||||
OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId);
|
OSGiApp app = new OSGiApp(getDeploymentManager(), this, bundle, originId);
|
||||||
|
|
|
@ -78,8 +78,6 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
|
|
||||||
private Bundle _contributor;
|
private Bundle _contributor;
|
||||||
|
|
||||||
private boolean _lookInOsgiFirst = true;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param parent The parent classloader.
|
* @param parent The parent classloader.
|
||||||
|
@ -96,11 +94,26 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public Class<?> loadClass(String name) throws ClassNotFoundException
|
public Class<?> loadClass(String name) throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
return super.loadClass(name);
|
try
|
||||||
|
{
|
||||||
|
return _osgiBundleClassLoader.loadClass(name);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException cne)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return super.loadClass(name);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException cne2)
|
||||||
|
{
|
||||||
|
throw cne;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -121,36 +134,18 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
{
|
{
|
||||||
Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
|
Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
|
||||||
Enumeration<URL> urls = super.getResources(name);
|
Enumeration<URL> urls = super.getResources(name);
|
||||||
if (_lookInOsgiFirst)
|
List<URL> resources = toList(osgiUrls, urls);
|
||||||
{
|
return Collections.enumeration(resources);
|
||||||
return Collections.enumeration(toList(osgiUrls, urls));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Collections.enumeration(toList(urls, osgiUrls));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public URL getResource(String name)
|
public URL getResource(String name)
|
||||||
{
|
{
|
||||||
if (_lookInOsgiFirst)
|
URL url = _osgiBundleClassLoader.getResource(name);
|
||||||
{
|
return url != null ? url : super.getResource(name);
|
||||||
URL url = _osgiBundleClassLoader.getResource(name);
|
|
||||||
return url != null ? url : super.getResource(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
URL url = super.getResource(name);
|
|
||||||
return url != null ? url : _osgiBundleClassLoader.getResource(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
|
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
|
||||||
{
|
{
|
||||||
|
@ -160,30 +155,7 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
while (e2 != null && e2.hasMoreElements())
|
while (e2 != null && e2.hasMoreElements())
|
||||||
list.add(e2.nextElement());
|
list.add(e2.nextElement());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException cne)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException cne2)
|
|
||||||
{
|
|
||||||
throw cne;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class BufferedResponseHandler extends HandlerWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not a supported method - no Vary because no matter what client, this URI is always excluded
|
// If not a supported method - no Vary because no matter what client, this URI is always excluded
|
||||||
if (!_methods.matches(baseRequest.getMethod()))
|
if (!_methods.test(baseRequest.getMethod()))
|
||||||
{
|
{
|
||||||
LOG.debug("{} excluded by method {}",this,request);
|
LOG.debug("{} excluded by method {}",this,request);
|
||||||
_handler.handle(target,baseRequest, request, response);
|
_handler.handle(target,baseRequest, request, response);
|
||||||
|
@ -173,7 +173,7 @@ public class BufferedResponseHandler extends HandlerWrapper
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected boolean isMimeTypeBufferable(String mimetype)
|
protected boolean isMimeTypeBufferable(String mimetype)
|
||||||
{
|
{
|
||||||
return _mimeTypes.matches(mimetype);
|
return _mimeTypes.test(mimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -182,7 +182,7 @@ public class BufferedResponseHandler extends HandlerWrapper
|
||||||
if (requestURI == null)
|
if (requestURI == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return _paths.matches(requestURI);
|
return _paths.test(requestURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -457,7 +457,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not a supported method - no Vary because no matter what client, this URI is always excluded
|
// If not a supported method - no Vary because no matter what client, this URI is always excluded
|
||||||
if (!_methods.matches(baseRequest.getMethod()))
|
if (!_methods.test(baseRequest.getMethod()))
|
||||||
{
|
{
|
||||||
LOG.debug("{} excluded by method {}",this,request);
|
LOG.debug("{} excluded by method {}",this,request);
|
||||||
_handler.handle(target,baseRequest, request, response);
|
_handler.handle(target,baseRequest, request, response);
|
||||||
|
@ -549,14 +549,14 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
||||||
if (ua == null)
|
if (ua == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return _agentPatterns.matches(ua);
|
return _agentPatterns.test(ua);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public boolean isMimeTypeGzipable(String mimetype)
|
public boolean isMimeTypeGzipable(String mimetype)
|
||||||
{
|
{
|
||||||
return _mimeTypes.matches(mimetype);
|
return _mimeTypes.test(mimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -572,7 +572,7 @@ public class GzipHandler extends HandlerWrapper implements GzipFactory
|
||||||
if (requestURI == null)
|
if (requestURI == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return _paths.matches(requestURI);
|
return _paths.test(requestURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.AbstractMap;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
@ -495,6 +497,39 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
int s=0;
|
||||||
|
for (int r=0;r<=_rows;r++)
|
||||||
|
{
|
||||||
|
if (_key[r]!=null && _value[r]!=null)
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
for (int r=0;r<=_rows;r++)
|
||||||
|
{
|
||||||
|
if (_key[r]!=null && _value[r]!=null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<Map.Entry<String,V>> entrySet()
|
||||||
|
{
|
||||||
|
Set<Map.Entry<String,V>> entries = new HashSet<>();
|
||||||
|
for (int r=0;r<=_rows;r++)
|
||||||
|
{
|
||||||
|
if (_key[r]!=null && _value[r]!=null)
|
||||||
|
entries.add(new AbstractMap.SimpleEntry<>(_key[r],_value[r]));
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFull()
|
public boolean isFull()
|
||||||
{
|
{
|
||||||
|
@ -524,4 +559,143 @@ public class ArrayTernaryTrie<V> extends AbstractTrie<V>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Growing<V> implements Trie<V>
|
||||||
|
{
|
||||||
|
private final int _growby;
|
||||||
|
private ArrayTernaryTrie<V> _trie;
|
||||||
|
|
||||||
|
public Growing()
|
||||||
|
{
|
||||||
|
this(1024,1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Growing(int capacity, int growby)
|
||||||
|
{
|
||||||
|
_growby=growby;
|
||||||
|
_trie = new ArrayTernaryTrie<>(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Growing(boolean insensitive, int capacity, int growby)
|
||||||
|
{
|
||||||
|
_growby=growby;
|
||||||
|
_trie = new ArrayTernaryTrie<>(insensitive,capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean put(V v)
|
||||||
|
{
|
||||||
|
return put(v.toString(),v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return _trie.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public V remove(String s)
|
||||||
|
{
|
||||||
|
return _trie.remove(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(String s)
|
||||||
|
{
|
||||||
|
return _trie.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(ByteBuffer b)
|
||||||
|
{
|
||||||
|
return _trie.get(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getBest(byte[] b, int offset, int len)
|
||||||
|
{
|
||||||
|
return _trie.getBest(b,offset,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCaseInsensitive()
|
||||||
|
{
|
||||||
|
return _trie.isCaseInsensitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
return _trie.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
_trie.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean put(String s, V v)
|
||||||
|
{
|
||||||
|
boolean added = _trie.put(s,v);
|
||||||
|
while (!added)
|
||||||
|
{
|
||||||
|
ArrayTernaryTrie<V> bigger = new ArrayTernaryTrie<>(_trie._key.length+_growby);
|
||||||
|
for (Map.Entry<String,V> entry : _trie.entrySet())
|
||||||
|
bigger.put(entry.getKey(),entry.getValue());
|
||||||
|
added = _trie.put(s,v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(String s, int offset, int len)
|
||||||
|
{
|
||||||
|
return _trie.get(s,offset,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(ByteBuffer b, int offset, int len)
|
||||||
|
{
|
||||||
|
return _trie.get(b,offset,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getBest(String s)
|
||||||
|
{
|
||||||
|
return _trie.getBest(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getBest(String s, int offset, int length)
|
||||||
|
{
|
||||||
|
return _trie.getBest(s,offset,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V getBest(ByteBuffer b, int offset, int len)
|
||||||
|
{
|
||||||
|
return _trie.getBest(b,offset,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return _trie.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> keySet()
|
||||||
|
{
|
||||||
|
return _trie.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFull()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump()
|
||||||
|
{
|
||||||
|
_trie.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return _trie.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return _trie.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,21 +25,21 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
|
|
||||||
/** Utility class to maintain a set of inclusions and exclusions.
|
/** Utility class to maintain a set of inclusions and exclusions.
|
||||||
* <p>Maintains a set of included and excluded elements. The method {@link #matches(Object)}
|
* <p>Maintains a set of included and excluded elements. The method {@link #test(Object)}
|
||||||
* will return true IFF the passed object is not in the excluded set AND ( either the
|
* will return true IFF the passed object is not in the excluded set AND ( either the
|
||||||
* included set is empty OR the object is in the included set)
|
* included set is empty OR the object is in the included set)
|
||||||
* <p>The type of the underlying {@link Set} used may be passed into the
|
* <p>The type of the underlying {@link Set} used may be passed into the
|
||||||
* constructor, so special sets like Servlet PathMap may be used.
|
* constructor, so special sets like Servlet PathMap may be used.
|
||||||
* <p>
|
* <p>
|
||||||
* @param <P> The type of element of the set (often a pattern)
|
* @param <T> The type of element of the set (often a pattern)
|
||||||
* @param <T> The type of the instance passed to the predicate
|
* @param <P> The type of the instance passed to the predicate
|
||||||
*/
|
*/
|
||||||
public class IncludeExcludeSet<P,T> implements Predicate<T>
|
public class IncludeExcludeSet<T,P> implements Predicate<P>
|
||||||
{
|
{
|
||||||
private final Set<P> _includes;
|
private final Set<T> _includes;
|
||||||
private final Predicate<T> _includePredicate;
|
private final Predicate<P> _includePredicate;
|
||||||
private final Set<P> _excludes;
|
private final Set<T> _excludes;
|
||||||
private final Predicate<T> _excludePredicate;
|
private final Predicate<P> _excludePredicate;
|
||||||
|
|
||||||
private static class SetContainsPredicate<T> implements Predicate<T>
|
private static class SetContainsPredicate<T> implements Predicate<T>
|
||||||
{
|
{
|
||||||
|
@ -73,7 +73,7 @@ public class IncludeExcludeSet<P,T> implements Predicate<T>
|
||||||
* is created.
|
* is created.
|
||||||
* @param <SET> The type of a set to use as the backing store
|
* @param <SET> The type of a set to use as the backing store
|
||||||
*/
|
*/
|
||||||
public <SET extends Set<P>> IncludeExcludeSet(Class<SET> setClass)
|
public <SET extends Set<T>> IncludeExcludeSet(Class<SET> setClass)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -82,7 +82,7 @@ public class IncludeExcludeSet<P,T> implements Predicate<T>
|
||||||
|
|
||||||
if(_includes instanceof Predicate)
|
if(_includes instanceof Predicate)
|
||||||
{
|
{
|
||||||
_includePredicate = (Predicate<T>)_includes;
|
_includePredicate = (Predicate<P>)_includes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ public class IncludeExcludeSet<P,T> implements Predicate<T>
|
||||||
|
|
||||||
if(_excludes instanceof Predicate)
|
if(_excludes instanceof Predicate)
|
||||||
{
|
{
|
||||||
_excludePredicate = (Predicate<T>)_excludes;
|
_excludePredicate = (Predicate<P>)_excludes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,7 @@ public class IncludeExcludeSet<P,T> implements Predicate<T>
|
||||||
* @param excludePredicate the Predicate for excluded item testing (null for simple {@link Set#contains(Object)} test)
|
* @param excludePredicate the Predicate for excluded item testing (null for simple {@link Set#contains(Object)} test)
|
||||||
* @param <SET> The type of a set to use as the backing store
|
* @param <SET> The type of a set to use as the backing store
|
||||||
*/
|
*/
|
||||||
public <SET extends Set<P>> IncludeExcludeSet(Set<P> includeSet, Predicate<T> includePredicate, Set<P> excludeSet, Predicate<T> excludePredicate)
|
public <SET extends Set<T>> IncludeExcludeSet(Set<T> includeSet, Predicate<P> includePredicate, Set<T> excludeSet, Predicate<P> excludePredicate)
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(includeSet,"Include Set");
|
Objects.requireNonNull(includeSet,"Include Set");
|
||||||
Objects.requireNonNull(includePredicate,"Include Predicate");
|
Objects.requireNonNull(includePredicate,"Include Predicate");
|
||||||
|
@ -126,51 +126,73 @@ public class IncludeExcludeSet<P,T> implements Predicate<T>
|
||||||
_excludePredicate = excludePredicate;
|
_excludePredicate = excludePredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void include(P element)
|
public void include(T element)
|
||||||
{
|
{
|
||||||
_includes.add(element);
|
_includes.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void include(P... element)
|
public void include(T... element)
|
||||||
{
|
{
|
||||||
for (P e: element)
|
for (T e: element)
|
||||||
_includes.add(e);
|
_includes.add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exclude(P element)
|
public void exclude(T element)
|
||||||
{
|
{
|
||||||
_excludes.add(element);
|
_excludes.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exclude(P... element)
|
public void exclude(T... element)
|
||||||
{
|
{
|
||||||
for (P e: element)
|
for (T e: element)
|
||||||
_excludes.add(e);
|
_excludes.add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(T t)
|
@Deprecated
|
||||||
|
public boolean matches(P t)
|
||||||
{
|
{
|
||||||
return test(t);
|
return test(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean test(T t)
|
@Override
|
||||||
|
public boolean test(P t)
|
||||||
{
|
{
|
||||||
if (!_includes.isEmpty() && !_includePredicate.test(t))
|
if (!_includes.isEmpty() && !_includePredicate.test(t))
|
||||||
return false;
|
return false;
|
||||||
return !_excludePredicate.test(t);
|
return !_excludePredicate.test(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Included and not Excluded
|
||||||
|
* @param t The item to test
|
||||||
|
* @return Boolean.TRUE if t is included, Boolean.FALSE if t is excluded and null if neither
|
||||||
|
*/
|
||||||
|
public Boolean isIncludedAndNotExcluded(P t)
|
||||||
|
{
|
||||||
|
if (_excludePredicate.test(t))
|
||||||
|
return Boolean.FALSE;
|
||||||
|
if (_includePredicate.test(t))
|
||||||
|
return Boolean.TRUE;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasIncludes()
|
||||||
|
{
|
||||||
|
return !_includes.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public int size()
|
public int size()
|
||||||
{
|
{
|
||||||
return _includes.size()+_excludes.size();
|
return _includes.size()+_excludes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<P> getIncluded()
|
public Set<T> getIncluded()
|
||||||
{
|
{
|
||||||
return _includes;
|
return _includes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<P> getExcluded()
|
public Set<T> getExcluded()
|
||||||
{
|
{
|
||||||
return _excludes;
|
return _excludes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.Set;
|
||||||
public interface Trie<V>
|
public interface Trie<V>
|
||||||
{
|
{
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Put and entry into the Trie
|
/** Put an entry into the Trie
|
||||||
* @param s The key for the entry
|
* @param s The key for the entry
|
||||||
* @param v The value of the entry
|
* @param v The value of the entry
|
||||||
* @return True if the Trie had capacity to add the field.
|
* @return True if the Trie had capacity to add the field.
|
||||||
|
@ -47,14 +47,14 @@ public interface Trie<V>
|
||||||
public V remove(String s);
|
public V remove(String s);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Get and exact match from a String key
|
/** Get an exact match from a String key
|
||||||
* @param s The key
|
* @param s The key
|
||||||
* @return the value for the string key
|
* @return the value for the string key
|
||||||
*/
|
*/
|
||||||
public V get(String s);
|
public V get(String s);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Get and exact match from a String key
|
/** Get an exact match from a String key
|
||||||
* @param s The key
|
* @param s The key
|
||||||
* @param offset The offset within the string of the key
|
* @param offset The offset within the string of the key
|
||||||
* @param len the length of the key
|
* @param len the length of the key
|
||||||
|
@ -63,14 +63,14 @@ public interface Trie<V>
|
||||||
public V get(String s,int offset,int len);
|
public V get(String s,int offset,int len);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Get and exact match from a segment of a ByteBuufer as key
|
/** Get an exact match from a segment of a ByteBuufer as key
|
||||||
* @param b The buffer
|
* @param b The buffer
|
||||||
* @return The value or null if not found
|
* @return The value or null if not found
|
||||||
*/
|
*/
|
||||||
public V get(ByteBuffer b);
|
public V get(ByteBuffer b);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Get and exact match from a segment of a ByteBuufer as key
|
/** Get an exact match from a segment of a ByteBuufer as key
|
||||||
* @param b The buffer
|
* @param b The buffer
|
||||||
* @param offset The offset within the buffer of the key
|
* @param offset The offset within the buffer of the key
|
||||||
* @param len the length of the key
|
* @param len the length of the key
|
||||||
|
|
|
@ -24,6 +24,9 @@ import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -31,9 +34,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContainerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.annotation.Name;
|
import org.eclipse.jetty.util.annotation.Name;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -693,4 +699,38 @@ public class TypeUtil
|
||||||
return !((Boolean)o).booleanValue();
|
return !((Boolean)o).booleanValue();
|
||||||
return "false".equalsIgnoreCase(o.toString());
|
return "false".equalsIgnoreCase(o.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public static Resource getLoadedFrom(Class<?> clazz)
|
||||||
|
{
|
||||||
|
ProtectionDomain domain = clazz.getProtectionDomain();
|
||||||
|
if (domain!=null)
|
||||||
|
{
|
||||||
|
CodeSource source = domain.getCodeSource();
|
||||||
|
if (source!=null)
|
||||||
|
{
|
||||||
|
URL location = source.getLocation();
|
||||||
|
|
||||||
|
if (location!=null)
|
||||||
|
return Resource.newResource(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String rname = clazz.getName().replace('.','/')+".class";
|
||||||
|
ClassLoader loader = clazz.getClassLoader();
|
||||||
|
URL url = (loader==null?ClassLoader.getSystemClassLoader():loader).getResource(rname);
|
||||||
|
if (url!=null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Resource.newResource(URIUtil.getJarSource(url.toString()));
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.debug(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -843,4 +844,30 @@ public class URIUtil
|
||||||
|
|
||||||
return URI.create(buf.toString());
|
return URI.create(buf.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static URI getJarSource(URI uri)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!"jar".equals(uri.getScheme()))
|
||||||
|
return uri;
|
||||||
|
String s = uri.getSchemeSpecificPart();
|
||||||
|
int bang_slash = s.indexOf("!/");
|
||||||
|
if (bang_slash>=0)
|
||||||
|
s=s.substring(0,bang_slash);
|
||||||
|
return new URI(s);
|
||||||
|
}
|
||||||
|
catch(URISyntaxException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getJarSource(String uri)
|
||||||
|
{
|
||||||
|
if (!uri.startsWith("jar:"))
|
||||||
|
return uri;
|
||||||
|
int bang_slash = uri.indexOf("!/");
|
||||||
|
return (bang_slash>=0)?uri.substring(4,bang_slash):uri.substring(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class IncludeExcludeTest
|
||||||
IncludeExclude<String> ie = new IncludeExclude<>();
|
IncludeExclude<String> ie = new IncludeExclude<>();
|
||||||
|
|
||||||
assertThat("Empty IncludeExclude", ie.size(), is(0));
|
assertThat("Empty IncludeExclude", ie.size(), is(0));
|
||||||
assertThat("Matches 'foo'",ie.matches("foo"),is(true));
|
assertThat("Matches 'foo'",ie.test("foo"),is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -43,10 +43,10 @@ public class IncludeExcludeTest
|
||||||
ie.include("bar");
|
ie.include("bar");
|
||||||
|
|
||||||
assertThat("IncludeExclude.size", ie.size(), is(2));
|
assertThat("IncludeExclude.size", ie.size(), is(2));
|
||||||
assertEquals(false,ie.matches(""));
|
assertEquals(false,ie.test(""));
|
||||||
assertEquals(true,ie.matches("foo"));
|
assertEquals(true,ie.test("foo"));
|
||||||
assertEquals(true,ie.matches("bar"));
|
assertEquals(true,ie.test("bar"));
|
||||||
assertEquals(false,ie.matches("foobar"));
|
assertEquals(false,ie.test("foobar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -58,11 +58,11 @@ public class IncludeExcludeTest
|
||||||
|
|
||||||
assertEquals(2,ie.size());
|
assertEquals(2,ie.size());
|
||||||
|
|
||||||
assertEquals(false,ie.matches("foo"));
|
assertEquals(false,ie.test("foo"));
|
||||||
assertEquals(false,ie.matches("bar"));
|
assertEquals(false,ie.test("bar"));
|
||||||
assertEquals(true,ie.matches(""));
|
assertEquals(true,ie.test(""));
|
||||||
assertEquals(true,ie.matches("foobar"));
|
assertEquals(true,ie.test("foobar"));
|
||||||
assertEquals(true,ie.matches("wibble"));
|
assertEquals(true,ie.test("wibble"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -76,11 +76,11 @@ public class IncludeExcludeTest
|
||||||
|
|
||||||
assertEquals(4,ie.size());
|
assertEquals(4,ie.size());
|
||||||
|
|
||||||
assertEquals(true,ie.matches("foo"));
|
assertEquals(true,ie.test("foo"));
|
||||||
assertEquals(false,ie.matches("bar"));
|
assertEquals(false,ie.test("bar"));
|
||||||
assertEquals(false,ie.matches(""));
|
assertEquals(false,ie.test(""));
|
||||||
assertEquals(false,ie.matches("foobar"));
|
assertEquals(false,ie.test("foobar"));
|
||||||
assertEquals(false,ie.matches("xxx"));
|
assertEquals(false,ie.test("xxx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class IncludeExcludeTest
|
||||||
IncludeExclude<String> ie = new IncludeExclude<>(RegexSet.class);
|
IncludeExclude<String> ie = new IncludeExclude<>(RegexSet.class);
|
||||||
|
|
||||||
assertEquals(0,ie.size());
|
assertEquals(0,ie.size());
|
||||||
assertEquals(true,ie.matches("foo"));
|
assertEquals(true,ie.test("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -102,13 +102,13 @@ public class IncludeExcludeTest
|
||||||
ie.include("b((ar)|(oo))");
|
ie.include("b((ar)|(oo))");
|
||||||
|
|
||||||
assertEquals(2,ie.size());
|
assertEquals(2,ie.size());
|
||||||
assertEquals(false,ie.matches(""));
|
assertEquals(false,ie.test(""));
|
||||||
assertEquals(true,ie.matches("foo"));
|
assertEquals(true,ie.test("foo"));
|
||||||
assertEquals(true,ie.matches("far"));
|
assertEquals(true,ie.test("far"));
|
||||||
assertEquals(true,ie.matches("bar"));
|
assertEquals(true,ie.test("bar"));
|
||||||
assertEquals(true,ie.matches("boo"));
|
assertEquals(true,ie.test("boo"));
|
||||||
assertEquals(false,ie.matches("foobar"));
|
assertEquals(false,ie.test("foobar"));
|
||||||
assertEquals(false,ie.matches("xxx"));
|
assertEquals(false,ie.test("xxx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -120,13 +120,13 @@ public class IncludeExcludeTest
|
||||||
|
|
||||||
assertEquals(2,ie.size());
|
assertEquals(2,ie.size());
|
||||||
|
|
||||||
assertEquals(false,ie.matches("foo"));
|
assertEquals(false,ie.test("foo"));
|
||||||
assertEquals(false,ie.matches("far"));
|
assertEquals(false,ie.test("far"));
|
||||||
assertEquals(false,ie.matches("bar"));
|
assertEquals(false,ie.test("bar"));
|
||||||
assertEquals(false,ie.matches("boo"));
|
assertEquals(false,ie.test("boo"));
|
||||||
assertEquals(true,ie.matches(""));
|
assertEquals(true,ie.test(""));
|
||||||
assertEquals(true,ie.matches("foobar"));
|
assertEquals(true,ie.test("foobar"));
|
||||||
assertEquals(true,ie.matches("xxx"));
|
assertEquals(true,ie.test("xxx"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -139,14 +139,14 @@ public class IncludeExcludeTest
|
||||||
ie.exclude("b((ar)|(oo))");
|
ie.exclude("b((ar)|(oo))");
|
||||||
|
|
||||||
assertEquals(4,ie.size());
|
assertEquals(4,ie.size());
|
||||||
assertEquals(false,ie.matches("foo"));
|
assertEquals(false,ie.test("foo"));
|
||||||
assertEquals(false,ie.matches("far"));
|
assertEquals(false,ie.test("far"));
|
||||||
assertEquals(false,ie.matches("bar"));
|
assertEquals(false,ie.test("bar"));
|
||||||
assertEquals(false,ie.matches("boo"));
|
assertEquals(false,ie.test("boo"));
|
||||||
assertEquals(false,ie.matches(""));
|
assertEquals(false,ie.test(""));
|
||||||
assertEquals(false,ie.matches("xxx"));
|
assertEquals(false,ie.test("xxx"));
|
||||||
|
|
||||||
assertEquals(true,ie.matches("foobar"));
|
assertEquals(true,ie.test("foobar"));
|
||||||
assertEquals(true,ie.matches("Ant"));
|
assertEquals(true,ie.test("Ant"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -119,4 +120,12 @@ public class TypeUtilTest
|
||||||
Assert.assertFalse(TypeUtil.isFalse("blargle"));
|
Assert.assertFalse(TypeUtil.isFalse("blargle"));
|
||||||
Assert.assertFalse(TypeUtil.isFalse(new Object(){@Override public String toString(){return "true";}}));
|
Assert.assertFalse(TypeUtil.isFalse(new Object(){@Override public String toString(){return "true";}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadedFrom() throws Exception
|
||||||
|
{
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(String.class).toString(),Matchers.containsString("/rt.jar"));
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(Assert.class).toString(),Matchers.containsString(".jar"));
|
||||||
|
Assert.assertThat(TypeUtil.getLoadedFrom(TypeUtil.class).toString(),Matchers.containsString("/classes/"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,17 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util;
|
package org.eclipse.jetty.util;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,4 +291,15 @@ public class URIUtilTest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Test
|
||||||
|
public void testJarSource() throws Exception
|
||||||
|
{
|
||||||
|
assertThat(URIUtil.getJarSource("file:///tmp/"),is("file:///tmp/"));
|
||||||
|
assertThat(URIUtil.getJarSource("jar:file:///tmp/foo.jar"),is("file:///tmp/foo.jar"));
|
||||||
|
assertThat(URIUtil.getJarSource("jar:file:///tmp/foo.jar!/some/path"),is("file:///tmp/foo.jar"));
|
||||||
|
assertThat(URIUtil.getJarSource(new URI("file:///tmp/")),is(new URI("file:///tmp/")));
|
||||||
|
assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar")),is(new URI("file:///tmp/foo.jar")));
|
||||||
|
assertThat(URIUtil.getJarSource(new URI("jar:file:///tmp/foo.jar!/some/path")),is(new URI("file:///tmp/foo.jar")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||||
|
|
||||||
|
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||||
|
<Call class="org.eclipse.jetty.webapp.WebAppContext" name="addSystemClasses">
|
||||||
|
<Arg><Ref refid="Server"/></Arg>
|
||||||
|
<Arg>
|
||||||
|
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||||
|
<Arg><Property name="jetty.webapp.addSystemClasses"/></Arg>
|
||||||
|
</Call>
|
||||||
|
</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
<Call class="org.eclipse.jetty.webapp.WebAppContext" name="addServerClasses">
|
||||||
|
<Arg><Ref refid="Server"/></Arg>
|
||||||
|
<Arg>
|
||||||
|
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
|
||||||
|
<Arg><Property name="jetty.webapp.addServerClasses"/></Arg>
|
||||||
|
</Call>
|
||||||
|
</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
</Configure>
|
|
@ -6,5 +6,23 @@ classpath. Without this, only Jetty specific handlers may be deployed.
|
||||||
servlet
|
servlet
|
||||||
security
|
security
|
||||||
|
|
||||||
|
[xml]
|
||||||
|
etc/jetty-webapp.xml
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
lib/jetty-webapp-${jetty.version}.jar
|
lib/jetty-webapp-${jetty.version}.jar
|
||||||
|
|
||||||
|
|
||||||
|
[ini-template]
|
||||||
|
## Add to the server wide default jars and packages protected or hidden from webapps.
|
||||||
|
## System classes are protected and cannot be overridden by a webapp.
|
||||||
|
## Server classes are hidden and cannot be seen by a webapp
|
||||||
|
## Lists of patterns are comma separated and may be either:
|
||||||
|
## + a qualified classname e.g. 'com.acme.Foo'
|
||||||
|
## + a package name e.g. 'net.example.'
|
||||||
|
## + a jar file e.g. 'file:${jetty.base}/lib/dependency.jar'
|
||||||
|
## + a directory of jars,resource or classes e.g. 'file:${jetty.base}/resources'
|
||||||
|
## + A pattern preceeded with a '-' is an exclusion, all other patterns are inclusions
|
||||||
|
##
|
||||||
|
#jetty.webapp.addSystemClasses=
|
||||||
|
#jetty.webapp.addServerClasses=
|
||||||
|
|
|
@ -19,13 +19,30 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.webapp;
|
package org.eclipse.jetty.webapp;
|
||||||
|
|
||||||
import java.util.AbstractList;
|
import static java.lang.Boolean.FALSE;
|
||||||
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.AbstractSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||||
|
import org.eclipse.jetty.util.IncludeExcludeSet;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -45,21 +62,59 @@ import org.eclipse.jetty.util.StringUtil;
|
||||||
* in this string should be separated by ':' (semicolon) or ',' (comma).
|
* in this string should be separated by ':' (semicolon) or ',' (comma).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ClasspathPattern extends AbstractList<String>
|
public class ClasspathPattern extends AbstractSet<String>
|
||||||
{
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(ClasspathPattern.class);
|
||||||
|
|
||||||
|
enum Type { PACKAGE, CLASSNAME, LOCATION }
|
||||||
|
|
||||||
private static class Entry
|
private static class Entry
|
||||||
{
|
{
|
||||||
public final String _pattern;
|
private final String _pattern;
|
||||||
public final String _name;
|
private final String _name;
|
||||||
public final boolean _inclusive;
|
private final boolean _inclusive;
|
||||||
public final boolean _package;
|
private final Type _type;
|
||||||
|
|
||||||
Entry(String pattern)
|
Entry(String pattern)
|
||||||
{
|
{
|
||||||
_pattern=pattern;
|
_pattern=pattern;
|
||||||
_inclusive = !pattern.startsWith("-");
|
_inclusive = !pattern.startsWith("-");
|
||||||
_package = pattern.endsWith(".");
|
|
||||||
_name = _inclusive ? pattern : pattern.substring(1).trim();
|
_name = _inclusive ? pattern : pattern.substring(1).trim();
|
||||||
|
_type = (_name.startsWith("file:"))?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry(String name, boolean include)
|
||||||
|
{
|
||||||
|
_pattern=include?name:("-"+name);
|
||||||
|
_inclusive = include;
|
||||||
|
_name = name;
|
||||||
|
_type = (_name.startsWith("file:"))?Type.LOCATION:(_name.endsWith(".")?Type.PACKAGE:Type.CLASSNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getPattern()
|
||||||
|
{
|
||||||
|
return _pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPackage()
|
||||||
|
{
|
||||||
|
return _type==Type.PACKAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClassName()
|
||||||
|
{
|
||||||
|
return _type==Type.CLASSNAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocation()
|
||||||
|
{
|
||||||
|
return _type==Type.LOCATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,86 +122,356 @@ public class ClasspathPattern extends AbstractList<String>
|
||||||
{
|
{
|
||||||
return _pattern;
|
return _pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return _pattern.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
return (o instanceof Entry)
|
||||||
|
&& _pattern.equals(((Entry)o)._pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInclusive()
|
||||||
|
{
|
||||||
|
return _inclusive;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final private List<Entry> _entries = new ArrayList<Entry>();
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public static class ByPackage extends AbstractSet<Entry> implements Predicate<String>
|
||||||
|
{
|
||||||
|
private final ArrayTernaryTrie.Growing<Entry> _entries = new ArrayTernaryTrie.Growing<>(false,512,512);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(String name)
|
||||||
|
{
|
||||||
|
return _entries.getBest(name)!=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Entry> iterator()
|
||||||
|
{
|
||||||
|
return _entries.keySet().stream().map(k->_entries.get(k)).iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return _entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return _entries.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Entry entry)
|
||||||
|
{
|
||||||
|
String name = entry.getName();
|
||||||
|
if (entry.isClassName())
|
||||||
|
name+="$";
|
||||||
|
else if (entry.isLocation())
|
||||||
|
throw new IllegalArgumentException(entry.toString());
|
||||||
|
else if (".".equals(name))
|
||||||
|
name="";
|
||||||
|
|
||||||
|
if (_entries.get(name)!=null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_entries.put(name,entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object entry)
|
||||||
|
{
|
||||||
|
if (!(entry instanceof Entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _entries.remove(((Entry)entry).getName())!=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
_entries.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public static class ByName extends HashSet<Entry> implements Predicate<String>
|
||||||
|
{
|
||||||
|
private final Map<String,Entry> _entries = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(String name)
|
||||||
|
{
|
||||||
|
return _entries.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Entry> iterator()
|
||||||
|
{
|
||||||
|
return _entries.values().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return _entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Entry entry)
|
||||||
|
{
|
||||||
|
if (!entry.isClassName())
|
||||||
|
throw new IllegalArgumentException(entry.toString());
|
||||||
|
return _entries.put(entry.getName(),entry)==null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object entry)
|
||||||
|
{
|
||||||
|
if (!(entry instanceof Entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _entries.remove(((Entry)entry).getName())!=null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ByPackageOrName extends AbstractSet<Entry> implements Predicate<String>
|
||||||
|
{
|
||||||
|
private final ByName _byName = new ByName();
|
||||||
|
private final ByPackage _byPackage = new ByPackage();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(String name)
|
||||||
|
{
|
||||||
|
return _byPackage.test(name)
|
||||||
|
|| _byName.test(name) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Entry> iterator()
|
||||||
|
{
|
||||||
|
// by package contains all entries (classes are also $ packages).
|
||||||
|
return _byPackage.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return _byPackage.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Entry e)
|
||||||
|
{
|
||||||
|
if (e.isLocation())
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
if (e.isPackage())
|
||||||
|
return _byPackage.add(e);
|
||||||
|
|
||||||
|
// Add class name to packages also as classes act
|
||||||
|
// as packages for nested classes.
|
||||||
|
boolean added = _byPackage.add(e);
|
||||||
|
added = _byName.add(e) || added;
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof Entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean removed = _byPackage.remove(o);
|
||||||
|
|
||||||
|
if (!((Entry)o).isPackage())
|
||||||
|
removed = _byName.remove(o) || removed;
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
_byPackage.clear();
|
||||||
|
_byName.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public static class ByLocation extends HashSet<File> implements Predicate<Path>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean test(Path path)
|
||||||
|
{
|
||||||
|
for (File file: this)
|
||||||
|
{
|
||||||
|
if (file.isDirectory())
|
||||||
|
{
|
||||||
|
if (path.startsWith(file.toPath()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (path.equals(file.toPath()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Map<String,Entry> _entries = new HashMap<>();
|
||||||
|
Set<String> _classes = new HashSet<>();
|
||||||
|
|
||||||
|
IncludeExcludeSet<Entry,String> _patterns = new IncludeExcludeSet<>(ByPackageOrName.class);
|
||||||
|
IncludeExcludeSet<File,Path> _locations = new IncludeExcludeSet<>(ByLocation.class);
|
||||||
|
|
||||||
public ClasspathPattern()
|
public ClasspathPattern()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public ClasspathPattern(String[] patterns)
|
public ClasspathPattern(String[] patterns)
|
||||||
{
|
{
|
||||||
setAll(patterns);
|
setAll(patterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public ClasspathPattern(String pattern)
|
public ClasspathPattern(String pattern)
|
||||||
{
|
{
|
||||||
add(pattern);
|
add(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public boolean include(String name)
|
||||||
@Override
|
|
||||||
public String get(int index)
|
|
||||||
{
|
{
|
||||||
return _entries.get(index)._pattern;
|
if (name==null)
|
||||||
}
|
return false;
|
||||||
|
return add(new Entry(name,true));
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public boolean include(String... name)
|
||||||
@Override
|
|
||||||
public String remove(int index)
|
|
||||||
{
|
{
|
||||||
Entry e = _entries.remove(index);
|
boolean added = false;
|
||||||
return e==null?null:e._pattern;
|
for (String n:name)
|
||||||
|
if (n!=null)
|
||||||
|
added = add(new Entry(n,true)) || added;
|
||||||
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public boolean exclude(String name)
|
||||||
public boolean remove(String pattern)
|
|
||||||
{
|
{
|
||||||
for (int i=_entries.size();i-->0;)
|
if (name==null)
|
||||||
|
return false;
|
||||||
|
return add(new Entry(name,false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean exclude(String... name)
|
||||||
|
{
|
||||||
|
boolean added = false;
|
||||||
|
for (String n:name)
|
||||||
|
if (n!=null)
|
||||||
|
added = add(new Entry(n,false)) || added;
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(String pattern)
|
||||||
|
{
|
||||||
|
if (pattern==null)
|
||||||
|
return false;
|
||||||
|
return add(new Entry(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(String... pattern)
|
||||||
|
{
|
||||||
|
boolean added = false;
|
||||||
|
for (String p:pattern)
|
||||||
|
if (p!=null)
|
||||||
|
added = add(new Entry(p)) || added;
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean add(Entry entry)
|
||||||
|
{
|
||||||
|
if (_entries.containsKey(entry.getPattern()))
|
||||||
|
return false;
|
||||||
|
_entries.put(entry.getPattern(),entry);
|
||||||
|
|
||||||
|
if (entry.isLocation())
|
||||||
{
|
{
|
||||||
if (pattern.equals(_entries.get(i)._pattern))
|
try
|
||||||
{
|
{
|
||||||
_entries.remove(i);
|
File file = Resource.newResource(entry.getName()).getFile().getAbsoluteFile().getCanonicalFile();
|
||||||
return true;
|
if (entry.isInclusive())
|
||||||
|
_locations.include(file);
|
||||||
|
else
|
||||||
|
_locations.exclude(file);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
|
{
|
||||||
|
if (entry.isInclusive())
|
||||||
|
_patterns.include(entry);
|
||||||
|
else
|
||||||
|
_patterns.exclude(entry);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof String))
|
||||||
|
return false;
|
||||||
|
String pattern = (String)o;
|
||||||
|
|
||||||
|
Entry entry = _entries.remove(pattern);
|
||||||
|
if (entry==null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
List<Entry> saved = new ArrayList<>(_entries.values());
|
||||||
|
clear();
|
||||||
|
for (Entry e:saved)
|
||||||
|
add(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
_entries.clear();
|
||||||
|
_patterns.clear();
|
||||||
|
_locations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<String> iterator()
|
||||||
|
{
|
||||||
|
return _entries.keySet().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
@Override
|
||||||
public int size()
|
public int size()
|
||||||
{
|
{
|
||||||
return _entries.size();
|
return _entries.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* Initialize the matcher by parsing each classpath pattern in an array
|
* Initialize the matcher by parsing each classpath pattern in an array
|
||||||
*
|
*
|
||||||
|
@ -158,7 +483,6 @@ public class ClasspathPattern extends AbstractList<String>
|
||||||
addAll(classes);
|
addAll(classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @param classes array of classpath patterns
|
* @param classes array of classpath patterns
|
||||||
*/
|
*/
|
||||||
|
@ -168,30 +492,6 @@ public class ClasspathPattern extends AbstractList<String>
|
||||||
addAll(Arrays.asList(classes));
|
addAll(Arrays.asList(classes));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @param classes array of classpath patterns
|
|
||||||
*/
|
|
||||||
public void prepend(String[] classes)
|
|
||||||
{
|
|
||||||
if (classes != null)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
for (String c : classes)
|
|
||||||
{
|
|
||||||
add(i,c);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void prependPattern(String pattern)
|
|
||||||
{
|
|
||||||
add(0,pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return array of classpath patterns
|
* @return array of classpath patterns
|
||||||
*/
|
*/
|
||||||
|
@ -200,22 +500,7 @@ public class ClasspathPattern extends AbstractList<String>
|
||||||
return toArray(new String[_entries.size()]);
|
return toArray(new String[_entries.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @return List of classes excluded class exclusions and package patterns
|
|
||||||
*/
|
|
||||||
public List<String> getClasses()
|
|
||||||
{
|
|
||||||
List<String> list = new ArrayList<>();
|
|
||||||
for (Entry e:_entries)
|
|
||||||
{
|
|
||||||
if (e._inclusive && !e._package)
|
|
||||||
list.add(e._name);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* Match the class name against the pattern
|
* Match the class name against the pattern
|
||||||
*
|
*
|
||||||
|
@ -224,65 +509,66 @@ public class ClasspathPattern extends AbstractList<String>
|
||||||
*/
|
*/
|
||||||
public boolean match(String name)
|
public boolean match(String name)
|
||||||
{
|
{
|
||||||
name = name.replace('/','.');
|
return _patterns.test(name);
|
||||||
|
}
|
||||||
for (Entry entry : _entries)
|
|
||||||
|
/**
|
||||||
|
* Match the class name against the pattern
|
||||||
|
*
|
||||||
|
* @param clazz A class to try to match
|
||||||
|
* @return true if class matches the pattern
|
||||||
|
*/
|
||||||
|
public boolean match(Class<?> clazz)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (entry==null)
|
Resource resource = TypeUtil.getLoadedFrom(clazz);
|
||||||
continue;
|
Path path = resource.getFile().toPath();
|
||||||
if (entry._package)
|
|
||||||
{
|
Boolean byName = _patterns.isIncludedAndNotExcluded(clazz.getName());
|
||||||
if (name.startsWith(entry._name) || ".".equals(entry._pattern))
|
Boolean byLocation = _locations.isIncludedAndNotExcluded(path);
|
||||||
return entry._inclusive;
|
|
||||||
}
|
// Combine the tri-state match of both IncludeExclude Sets
|
||||||
else
|
boolean included = byName==TRUE || byLocation==TRUE
|
||||||
{
|
|| (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes());
|
||||||
if (name.equals(entry._name))
|
boolean excluded = byName==FALSE || byLocation==FALSE;
|
||||||
return entry._inclusive;
|
return included && !excluded;
|
||||||
|
}
|
||||||
if (name.length()>entry._name.length() && '$'==name.charAt(entry._name.length()) && name.startsWith(entry._name))
|
catch (Exception e)
|
||||||
return entry._inclusive;
|
{
|
||||||
}
|
LOG.warn(e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAfter(String afterPattern,String... patterns)
|
public boolean match(String name, URL url)
|
||||||
{
|
{
|
||||||
if (patterns!=null && afterPattern!=null)
|
// Strip class suffix for name matching
|
||||||
{
|
if (name.endsWith(".class"))
|
||||||
ListIterator<String> iter = listIterator();
|
name=name.substring(0,name.length()-6);
|
||||||
while (iter.hasNext())
|
|
||||||
{
|
// Treat path elements as packages for name matching
|
||||||
String cc=iter.next();
|
name=name.replace("/",".");
|
||||||
if (afterPattern.equals(cc))
|
|
||||||
{
|
|
||||||
for (int i=0;i<patterns.length;i++)
|
|
||||||
iter.add(patterns[i]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("after '"+afterPattern+"' not found in "+this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addBefore(String beforePattern,String... patterns)
|
Boolean byName = _patterns.isIncludedAndNotExcluded(name);
|
||||||
{
|
|
||||||
if (patterns!=null && beforePattern!=null)
|
// Try to find a file path for location matching
|
||||||
|
Boolean byLocation = null;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ListIterator<String> iter = listIterator();
|
Resource resource = Resource.newResource(URIUtil.getJarSource(url.toURI()));
|
||||||
while (iter.hasNext())
|
File file = resource.getFile();
|
||||||
{
|
byLocation = _locations.isIncludedAndNotExcluded(file.toPath());
|
||||||
String cc=iter.next();
|
|
||||||
if (beforePattern.equals(cc))
|
|
||||||
{
|
|
||||||
iter.previous();
|
|
||||||
for (int i=0;i<patterns.length;i++)
|
|
||||||
iter.add(patterns[i]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("before '"+beforePattern+"' not found in "+this);
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.ignore(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine the tri-state match of both IncludeExclude Sets
|
||||||
|
boolean included = byName==TRUE || byLocation==TRUE
|
||||||
|
|| (byName==null && !_patterns.hasIncludes() && byLocation==null && !_locations.hasIncludes());
|
||||||
|
boolean excluded = byName==FALSE || byLocation==FALSE;
|
||||||
|
return included && !excluded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
@ -102,7 +101,7 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
* @return Returns the permissions.
|
* @return Returns the permissions.
|
||||||
*/
|
*/
|
||||||
PermissionCollection getPermissions();
|
PermissionCollection getPermissions();
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Is the class a System Class.
|
/** Is the class a System Class.
|
||||||
* A System class is a class that is visible to a webapplication,
|
* A System class is a class that is visible to a webapplication,
|
||||||
|
@ -111,7 +110,7 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
* @param clazz The fully qualified name of the class.
|
* @param clazz The fully qualified name of the class.
|
||||||
* @return True if the class is a system class.
|
* @return True if the class is a system class.
|
||||||
*/
|
*/
|
||||||
boolean isSystemClass(String clazz);
|
boolean isSystemClass(Class<?> clazz);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Is the class a Server Class.
|
/** Is the class a Server Class.
|
||||||
|
@ -122,7 +121,7 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
* @param clazz The fully qualified name of the class.
|
* @param clazz The fully qualified name of the class.
|
||||||
* @return True if the class is a server class.
|
* @return True if the class is a server class.
|
||||||
*/
|
*/
|
||||||
boolean isServerClass(String clazz);
|
boolean isServerClass(Class<?> clazz);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -135,6 +134,10 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
String getExtraClasspath();
|
String getExtraClasspath();
|
||||||
|
|
||||||
|
boolean isServerResource(String name, URL parent_url);
|
||||||
|
|
||||||
|
boolean isSystemResource(String name, URL webapp_url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +145,10 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
/** Run an action with access to ServerClasses
|
/** Run an action with access to ServerClasses
|
||||||
* <p>Run the passed {@link PrivilegedExceptionAction} with the classloader
|
* <p>Run the passed {@link PrivilegedExceptionAction} with the classloader
|
||||||
* configured so as to allow server classes to be visible</p>
|
* configured so as to allow server classes to be visible</p>
|
||||||
|
* @param <T> The type returned by the action
|
||||||
* @param action The action to run
|
* @param action The action to run
|
||||||
* @return The return from the action
|
* @return The return from the action
|
||||||
* @throws Exception
|
* @throws Exception if thrown by the action
|
||||||
*/
|
*/
|
||||||
public static <T> T runWithServerClassAccess(PrivilegedExceptionAction<T> action) throws Exception
|
public static <T> T runWithServerClassAccess(PrivilegedExceptionAction<T> action) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -361,27 +365,42 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
@Override
|
@Override
|
||||||
public Enumeration<URL> getResources(String name) throws IOException
|
public Enumeration<URL> getResources(String name) throws IOException
|
||||||
{
|
{
|
||||||
boolean system_class=_context.isSystemClass(name);
|
List<URL> from_parent = new ArrayList<>();
|
||||||
boolean server_class=_context.isServerClass(name) && !Boolean.TRUE.equals(__loadServerClasses.get());
|
List<URL> from_webapp = new ArrayList<>();
|
||||||
|
|
||||||
|
Enumeration<URL> urls = _parent.getResources(name);
|
||||||
|
while (urls!=null && urls.hasMoreElements())
|
||||||
|
{
|
||||||
|
URL url = urls.nextElement();
|
||||||
|
if (Boolean.TRUE.equals(__loadServerClasses.get()) || !_context.isServerResource(name,url))
|
||||||
|
from_parent.add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
urls = this.findResources(name);
|
||||||
|
while (urls!=null && urls.hasMoreElements())
|
||||||
|
{
|
||||||
|
URL url = urls.nextElement();
|
||||||
|
if (!_context.isSystemResource(name,url) || from_parent.isEmpty())
|
||||||
|
from_webapp.add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<URL> resources;
|
||||||
|
|
||||||
List<URL> from_parent = toList(server_class?null:_parent.getResources(name));
|
|
||||||
List<URL> from_webapp = toList((system_class&&!from_parent.isEmpty())?null:this.findResources(name));
|
|
||||||
|
|
||||||
if (_context.isParentLoaderPriority())
|
if (_context.isParentLoaderPriority())
|
||||||
{
|
{
|
||||||
from_parent.addAll(from_webapp);
|
from_parent.addAll(from_webapp);
|
||||||
return Collections.enumeration(from_parent);
|
resources = from_parent;
|
||||||
}
|
}
|
||||||
from_webapp.addAll(from_parent);
|
else
|
||||||
return Collections.enumeration(from_webapp);
|
{
|
||||||
}
|
from_webapp.addAll(from_parent);
|
||||||
|
resources = from_webapp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("getResources {} {}",name,resources);
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
return Collections.enumeration(resources);
|
||||||
private List<URL> toList(Enumeration<URL> e)
|
|
||||||
{
|
|
||||||
if (e==null)
|
|
||||||
return new ArrayList<URL>();
|
|
||||||
return Collections.list(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -395,138 +414,180 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
@Override
|
@Override
|
||||||
public URL getResource(String name)
|
public URL getResource(String name)
|
||||||
{
|
{
|
||||||
URL url= null;
|
URL resource=null;
|
||||||
boolean tried_parent= false;
|
if (_context.isParentLoaderPriority())
|
||||||
|
|
||||||
//If the resource is a class name with .class suffix, strip it off before comparison
|
|
||||||
//as the server and system patterns are specified without a .class suffix
|
|
||||||
String tmp = name;
|
|
||||||
if (tmp != null && tmp.endsWith(".class"))
|
|
||||||
tmp = tmp.substring(0, tmp.length()-6);
|
|
||||||
|
|
||||||
boolean system_class=_context.isSystemClass(tmp);
|
|
||||||
boolean server_class=_context.isServerClass(tmp) && !Boolean.TRUE.equals(__loadServerClasses.get());
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("getResource({}) system={} server={} cl={}",name,system_class,server_class,this);
|
|
||||||
|
|
||||||
if (system_class && server_class)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ClassLoader source=null;
|
|
||||||
|
|
||||||
if (_parent!=null &&(_context.isParentLoaderPriority() || system_class ) && !server_class)
|
|
||||||
{
|
{
|
||||||
tried_parent= true;
|
URL parent_url=_parent.getResource(name);
|
||||||
|
|
||||||
if (_parent!=null)
|
// return if we have a url the webapp is allowed to see
|
||||||
|
if (parent_url!=null
|
||||||
|
&& (Boolean.TRUE.equals(__loadServerClasses.get())
|
||||||
|
|| !_context.isServerResource(name,parent_url)))
|
||||||
|
resource = parent_url;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
source=_parent;
|
URL webapp_url = this.findResource(name);
|
||||||
url=_parent.getResource(name);
|
|
||||||
|
// If found here then OK to use regardless of system or server classes
|
||||||
|
// If it is a system resource, we've already tried to load from parent, so
|
||||||
|
// would have returned it.
|
||||||
|
// If it is a server resource, doesn't matter as we have loaded it from the
|
||||||
|
// webapp
|
||||||
|
if (webapp_url!=null)
|
||||||
|
resource = webapp_url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (url == null)
|
|
||||||
{
|
{
|
||||||
url= this.findResource(name);
|
URL webapp_url = this.findResource(name);
|
||||||
source=this;
|
|
||||||
if (url == null && name.startsWith("/"))
|
|
||||||
url= this.findResource(name.substring(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url == null && !tried_parent && !server_class )
|
if (webapp_url!=null && !_context.isSystemResource(name,webapp_url))
|
||||||
{
|
resource = webapp_url;
|
||||||
if (_parent!=null)
|
else
|
||||||
{
|
{
|
||||||
tried_parent=true;
|
|
||||||
source=_parent;
|
// Couldn't find or see a webapp resource, so try a parent
|
||||||
url= _parent.getResource(name);
|
URL parent_url=_parent.getResource(name);
|
||||||
|
if (parent_url!=null
|
||||||
|
&& (Boolean.TRUE.equals(__loadServerClasses.get())
|
||||||
|
|| !_context.isServerResource(name,parent_url)))
|
||||||
|
resource = parent_url;
|
||||||
|
// We couldn't find a parent resource, so OK to return a webapp one if it exists
|
||||||
|
// and we just couldn't see it before
|
||||||
|
else if (webapp_url!=null)
|
||||||
|
resource = webapp_url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perhaps this failed due to leading /
|
||||||
|
if (resource==null && name.startsWith("/"))
|
||||||
|
resource = getResource(name.substring(1));
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("gotResource({})=={} from={} tried_parent={}",name,url,source,tried_parent);
|
LOG.debug("getResource {} {}",name,resource);
|
||||||
|
|
||||||
return url;
|
return resource;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
|
LOG.setDebugEnabled(true);
|
||||||
|
WebAppContext.LOG.setDebugEnabled(true);
|
||||||
|
|
||||||
synchronized (getClassLoadingLock(name))
|
synchronized (getClassLoadingLock(name))
|
||||||
{
|
{
|
||||||
Class<?> c= findLoadedClass(name);
|
|
||||||
ClassNotFoundException ex= null;
|
ClassNotFoundException ex= null;
|
||||||
boolean tried_parent= false;
|
Class<?> parent_class = null;
|
||||||
|
Class<?> webapp_class = null;
|
||||||
boolean system_class=_context.isSystemClass(name);
|
|
||||||
boolean server_class=_context.isServerClass(name) && !Boolean.TRUE.equals(__loadServerClasses.get());
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("loadClass({}) system={} server={} cl={}",name,system_class,server_class,this);
|
|
||||||
|
|
||||||
ClassLoader source=null;
|
// Has this loader loaded the class already?
|
||||||
|
webapp_class = findLoadedClass(name);
|
||||||
if (system_class && server_class)
|
if (webapp_class != null)
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == null && _parent!=null && (_context.isParentLoaderPriority() || system_class) && !server_class)
|
|
||||||
{
|
|
||||||
tried_parent= true;
|
|
||||||
source=_parent;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
c= _parent.loadClass(name);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("loaded " + c);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
ex= e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
source=this;
|
|
||||||
c= this.findClass(name);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
ex= e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == null && _parent!=null && !tried_parent && !server_class )
|
|
||||||
{
|
|
||||||
tried_parent=true;
|
|
||||||
source=_parent;
|
|
||||||
c= _parent.loadClass(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == null && ex!=null)
|
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("!loadedClass({}) from={} tried_parent={}",name,this,tried_parent);
|
LOG.debug("found webapp loaded {}",webapp_class);
|
||||||
|
return webapp_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should we try the parent loader first?
|
||||||
|
if (_context.isParentLoaderPriority())
|
||||||
|
{
|
||||||
|
// Try the parent loader
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parent_class = _parent.loadClass(name);
|
||||||
|
|
||||||
|
// If the webapp is allowed to see this class
|
||||||
|
if (Boolean.TRUE.equals(__loadServerClasses.get()) || !_context.isServerClass(parent_class))
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("PLP parent loaded {}",parent_class);
|
||||||
|
return parent_class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
// Save it for later
|
||||||
|
ex = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try the webapp loader
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If found here then OK to use regardless of system or server classes
|
||||||
|
// If it is a system class, we've already tried to load from parent, so
|
||||||
|
// would have returned it.
|
||||||
|
// If it is a server class, doesn't matter as we have loaded it from the
|
||||||
|
// webapp
|
||||||
|
webapp_class = this.findClass(name);
|
||||||
|
resolveClass(webapp_class);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("PLP webapp loaded {}",webapp_class);
|
||||||
|
return webapp_class;
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
if (ex==null)
|
||||||
|
ex = e;
|
||||||
|
else
|
||||||
|
ex.addSuppressed(e);
|
||||||
|
}
|
||||||
|
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("loadedClass({})=={} from={} tried_parent={}",name,c,source,tried_parent);
|
|
||||||
|
|
||||||
if (resolve)
|
|
||||||
{
|
{
|
||||||
resolveClass(c);
|
// Not parent loader priority, so...
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("resolved({})=={} from={} tried_parent={}",name,c,source,tried_parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
// Try the webapp classloader first
|
||||||
|
// Look in the webapp classloader as a resource, to avoid
|
||||||
|
// loading a system class.
|
||||||
|
String path = name.replace('.', '/').concat(".class");
|
||||||
|
URL webapp_url = findResource(path);
|
||||||
|
|
||||||
|
if (webapp_url!=null && !_context.isSystemResource(name,webapp_url))
|
||||||
|
{
|
||||||
|
webapp_class = this.foundClass(name,webapp_url);
|
||||||
|
resolveClass(webapp_class);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("WAP webapp loaded {}",webapp_class);
|
||||||
|
return webapp_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try the parent loader
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parent_class = _parent.loadClass(name);
|
||||||
|
|
||||||
|
// If the webapp is allowed to see this class
|
||||||
|
if (Boolean.TRUE.equals(__loadServerClasses.get()) || !_context.isServerClass(parent_class))
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("WAP parent loaded {}",parent_class);
|
||||||
|
return parent_class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
ex=e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We couldn't find a parent class, so OK to return a webapp one if it exists
|
||||||
|
// and we just couldn't see it before
|
||||||
|
if (webapp_url!=null)
|
||||||
|
{
|
||||||
|
webapp_class = this.foundClass(name,webapp_url);
|
||||||
|
resolveClass(webapp_class);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("WAP !server webapp loaded {}",webapp_class);
|
||||||
|
return webapp_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw ex==null?new ClassNotFoundException(name):ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,69 +625,71 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
{
|
{
|
||||||
return _transformers.remove(transformer);
|
return _transformers.remove(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> findClass(final String name) throws ClassNotFoundException
|
protected Class<?> findClass(final String name) throws ClassNotFoundException
|
||||||
{
|
{
|
||||||
Class<?> clazz=null;
|
|
||||||
|
|
||||||
if (_transformers.isEmpty())
|
if (_transformers.isEmpty())
|
||||||
clazz = super.findClass(name);
|
return super.findClass(name);
|
||||||
else
|
|
||||||
|
String path = name.replace('.', '/').concat(".class");
|
||||||
|
URL url = findResource(path);
|
||||||
|
if (url==null)
|
||||||
|
throw new ClassNotFoundException(name);
|
||||||
|
return foundClass(name,url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected Class<?> foundClass(final String name, URL url) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
if (_transformers.isEmpty())
|
||||||
|
return super.findClass(name);
|
||||||
|
|
||||||
|
InputStream content=null;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
String path = name.replace('.', '/').concat(".class");
|
content = url.openStream();
|
||||||
URL url = getResource(path);
|
byte[] bytes = IO.readBytes(content);
|
||||||
if (url==null)
|
|
||||||
throw new ClassNotFoundException(name);
|
|
||||||
|
|
||||||
InputStream content=null;
|
if (LOG.isDebugEnabled())
|
||||||
try
|
LOG.debug("foundClass({}) url={} cl={}",name,url,this);
|
||||||
|
|
||||||
|
for (ClassFileTransformer transformer : _transformers)
|
||||||
{
|
{
|
||||||
content = url.openStream();
|
byte[] tmp = transformer.transform(this,name,null,null,bytes);
|
||||||
byte[] bytes = IO.readBytes(content);
|
if (tmp != null)
|
||||||
|
bytes = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
return defineClass(name,bytes,0,bytes.length);
|
||||||
LOG.debug("foundClass({}) url={} cl={}",name,url,this);
|
}
|
||||||
|
catch (IOException e)
|
||||||
for (ClassFileTransformer transformer : _transformers)
|
{
|
||||||
|
throw new ClassNotFoundException(name,e);
|
||||||
|
}
|
||||||
|
catch (IllegalClassFormatException e)
|
||||||
|
{
|
||||||
|
throw new ClassNotFoundException(name,e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (content!=null)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
byte[] tmp = transformer.transform(this,name,null,null,bytes);
|
content.close();
|
||||||
if (tmp != null)
|
|
||||||
bytes = tmp;
|
|
||||||
}
|
}
|
||||||
|
catch (IOException e)
|
||||||
clazz=defineClass(name,bytes,0,bytes.length);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new ClassNotFoundException(name,e);
|
|
||||||
}
|
|
||||||
catch (IllegalClassFormatException e)
|
|
||||||
{
|
|
||||||
throw new ClassNotFoundException(name,e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (content!=null)
|
|
||||||
{
|
{
|
||||||
try
|
throw new ClassNotFoundException(name,e);
|
||||||
{
|
|
||||||
content.close();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new ClassNotFoundException(name,e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clazz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
|
@ -639,4 +702,5 @@ public class WebAppClassLoader extends URLClassLoader
|
||||||
{
|
{
|
||||||
return "WebAppClassLoader=" + _name+"@"+Long.toHexString(hashCode());
|
return "WebAppClassLoader=" + _name+"@"+Long.toHexString(hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.security.PermissionCollection;
|
import java.security.PermissionCollection;
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -35,7 +34,6 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletRegistration.Dynamic;
|
import javax.servlet.ServletRegistration.Dynamic;
|
||||||
|
@ -63,6 +61,7 @@ import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.util.AttributesMap;
|
import org.eclipse.jetty.util.AttributesMap;
|
||||||
import org.eclipse.jetty.util.Loader;
|
import org.eclipse.jetty.util.Loader;
|
||||||
import org.eclipse.jetty.util.MultiException;
|
import org.eclipse.jetty.util.MultiException;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.URIUtil;
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
|
@ -87,7 +86,7 @@ import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
@ManagedObject("Web Application ContextHandler")
|
@ManagedObject("Web Application ContextHandler")
|
||||||
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
|
public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(WebAppContext.class);
|
static final Logger LOG = Log.getLogger(WebAppContext.class);
|
||||||
|
|
||||||
public static final String TEMPDIR = "javax.servlet.context.tempdir";
|
public static final String TEMPDIR = "javax.servlet.context.tempdir";
|
||||||
public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
|
public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
|
||||||
|
@ -131,12 +130,30 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
"org.eclipse.jetty.servlets.PushSessionCacheFilter" //must be loaded by container classpath
|
"org.eclipse.jetty.servlets.PushSessionCacheFilter" //must be loaded by container classpath
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
// Find the location of the JVM lib directory
|
||||||
|
public final static String __jvmlib;
|
||||||
|
static
|
||||||
|
{
|
||||||
|
String lib=null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lib=TypeUtil.getLoadedFrom(System.class).getFile().getParentFile().toURI().toString();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
LOG.warn(e);
|
||||||
|
lib=null;
|
||||||
|
}
|
||||||
|
__jvmlib=lib;
|
||||||
|
}
|
||||||
|
|
||||||
// Server classes are classes that are hidden from being
|
// Server classes are classes that are hidden from being
|
||||||
// loaded by the web application using system classloader,
|
// loaded by the web application using system classloader,
|
||||||
// so if web application needs to load any of such classes,
|
// so if web application needs to load any of such classes,
|
||||||
// it has to include them in its distribution.
|
// it has to include them in its distribution.
|
||||||
// TODO This centrally managed list of features that are exposed/hidden needs to be replaced
|
// TODO This centrally managed list of features that are exposed/hidden needs to be replaced
|
||||||
// with a more automatic distributed mechanism
|
// with a more automatic distributed mechanism
|
||||||
|
// TODO should be white list rather than black list
|
||||||
public final static String[] __dftServerClasses =
|
public final static String[] __dftServerClasses =
|
||||||
{
|
{
|
||||||
"-org.eclipse.jetty.server.session.SessionData", //don't hide SessionData for de/serialization purposes
|
"-org.eclipse.jetty.server.session.SessionData", //don't hide SessionData for de/serialization purposes
|
||||||
|
@ -666,21 +683,25 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Add to the list of Server classes.
|
/**
|
||||||
* @param classOrPackage A fully qualified class name (eg com.foo.MyClass)
|
* @return The ClasspathPattern used to match Server (hidden) classes
|
||||||
* or a qualified package name ending with '.' (eg com.foo.). If the class
|
|
||||||
* or package has '-' it is excluded from the server classes and order is thus
|
|
||||||
* important when added system class patterns. This argument may also be a comma
|
|
||||||
* separated list of classOrPackage patterns.
|
|
||||||
* @see #setServerClasses(String[])
|
|
||||||
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
|
||||||
*/
|
*/
|
||||||
public void addServerClass(String classOrPackage)
|
public ClasspathPattern getServerClasspathPattern()
|
||||||
{
|
{
|
||||||
if (_serverClasses == null)
|
if (_serverClasses == null)
|
||||||
loadServerClasses();
|
loadServerClasses();
|
||||||
|
|
||||||
_serverClasses.add(classOrPackage);
|
return _serverClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Deprecated
|
||||||
|
public void addServerClass(String classOrPackageOrLocation)
|
||||||
|
{
|
||||||
|
if (_serverClasses == null)
|
||||||
|
loadServerClasses();
|
||||||
|
|
||||||
|
_serverClasses.add(classOrPackageOrLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -693,12 +714,13 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
* @see #setServerClasses(String[])
|
* @see #setServerClasses(String[])
|
||||||
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void prependServerClass(String classOrPackage)
|
public void prependServerClass(String classOrPackage)
|
||||||
{
|
{
|
||||||
if (_serverClasses == null)
|
if (_serverClasses == null)
|
||||||
loadServerClasses();
|
loadServerClasses();
|
||||||
|
|
||||||
_serverClasses.prependPattern(classOrPackage);
|
_serverClasses.add(classOrPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -714,17 +736,21 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
|
|
||||||
return _systemClasses.getPatterns();
|
return _systemClasses.getPatterns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @return The ClasspathPattern used to match System (protected) classes
|
||||||
|
*/
|
||||||
|
public ClasspathPattern getSystemClasspathPattern()
|
||||||
|
{
|
||||||
|
if (_systemClasses == null)
|
||||||
|
loadSystemClasses();
|
||||||
|
|
||||||
|
return _systemClasses;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** Add to the list of System classes.
|
@Deprecated
|
||||||
* @param classOrPackage A fully qualified class name (eg com.foo.MyClass)
|
|
||||||
* or a qualified package name ending with '.' (eg com.foo.). If the class
|
|
||||||
* or package has '-' it is excluded from the system classes and order is thus
|
|
||||||
* important when added system class patterns. This argument may also be a comma
|
|
||||||
* separated list of classOrPackage patterns.
|
|
||||||
* @see #setSystemClasses(String[])
|
|
||||||
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
|
||||||
*/
|
|
||||||
public void addSystemClass(String classOrPackage)
|
public void addSystemClass(String classOrPackage)
|
||||||
{
|
{
|
||||||
if (_systemClasses == null)
|
if (_systemClasses == null)
|
||||||
|
@ -744,16 +770,17 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
* @see #setSystemClasses(String[])
|
* @see #setSystemClasses(String[])
|
||||||
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
* @see <a href="http://www.eclipse.org/jetty/documentation/current/jetty-classloading.html">Jetty Documentation: Classloading</a>
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void prependSystemClass(String classOrPackage)
|
public void prependSystemClass(String classOrPackage)
|
||||||
{
|
{
|
||||||
if (_systemClasses == null)
|
if (_systemClasses == null)
|
||||||
loadSystemClasses();
|
loadSystemClasses();
|
||||||
|
|
||||||
_systemClasses.prependPattern(classOrPackage);
|
_systemClasses.add(classOrPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Deprecated
|
||||||
public boolean isServerClass(String name)
|
public boolean isServerClass(String name)
|
||||||
{
|
{
|
||||||
if (_serverClasses == null)
|
if (_serverClasses == null)
|
||||||
|
@ -763,7 +790,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Deprecated
|
||||||
public boolean isSystemClass(String name)
|
public boolean isSystemClass(String name)
|
||||||
{
|
{
|
||||||
if (_systemClasses == null)
|
if (_systemClasses == null)
|
||||||
|
@ -771,6 +798,58 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
|
|
||||||
return _systemClasses.match(name);
|
return _systemClasses.match(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public boolean isServerClass(Class<?> clazz)
|
||||||
|
{
|
||||||
|
if (_serverClasses == null)
|
||||||
|
loadServerClasses();
|
||||||
|
|
||||||
|
boolean result = _serverClasses.match(clazz);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("isServerClass=={} {}",result,clazz);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public boolean isSystemClass(Class<?> clazz)
|
||||||
|
{
|
||||||
|
if (_systemClasses == null)
|
||||||
|
loadSystemClasses();
|
||||||
|
|
||||||
|
boolean result = _systemClasses.match(clazz);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("isSystemClass=={} {}",result,clazz);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public boolean isServerResource(String name, URL url)
|
||||||
|
{
|
||||||
|
if (_serverClasses == null)
|
||||||
|
loadServerClasses();
|
||||||
|
|
||||||
|
boolean result = _serverClasses.match(name,url);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("isServerResource=={} {} {}",result,name,url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public boolean isSystemResource(String name, URL url)
|
||||||
|
{
|
||||||
|
if (_systemClasses == null)
|
||||||
|
loadSystemClasses();
|
||||||
|
|
||||||
|
boolean result = _systemClasses.match(name,url);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("isSystemResource=={} {} {}",result,name,url);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
protected void loadSystemClasses()
|
protected void loadSystemClasses()
|
||||||
|
@ -784,8 +863,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
|
Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
|
||||||
if (systemClasses != null && systemClasses instanceof String[])
|
if (systemClasses instanceof String[])
|
||||||
_systemClasses = new ClasspathPattern((String[])systemClasses);
|
_systemClasses = new ClasspathPattern((String[])systemClasses);
|
||||||
|
else if (systemClasses instanceof ClasspathPattern)
|
||||||
|
_systemClasses = new ClasspathPattern(((ClasspathPattern)systemClasses).getPatterns());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_systemClasses == null)
|
if (_systemClasses == null)
|
||||||
|
@ -793,7 +874,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
private void loadServerClasses()
|
protected void loadServerClasses()
|
||||||
{
|
{
|
||||||
if (_serverClasses != null)
|
if (_serverClasses != null)
|
||||||
{
|
{
|
||||||
|
@ -806,10 +887,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
|
Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
|
||||||
if (serverClasses != null && serverClasses instanceof String[])
|
if (serverClasses instanceof String[])
|
||||||
{
|
|
||||||
_serverClasses = new ClasspathPattern((String[])serverClasses);
|
_serverClasses = new ClasspathPattern((String[])serverClasses);
|
||||||
}
|
else if (serverClasses instanceof ClasspathPattern)
|
||||||
|
_serverClasses = new ClasspathPattern(((ClasspathPattern)serverClasses).getPatterns());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_serverClasses == null)
|
if (_serverClasses == null)
|
||||||
|
@ -949,10 +1030,24 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
public void dump(Appendable out, String indent) throws IOException
|
||||||
{
|
{
|
||||||
|
List<String> system_classes=null;
|
||||||
|
if (_systemClasses!=null)
|
||||||
|
{
|
||||||
|
system_classes=new ArrayList<>(_systemClasses);
|
||||||
|
Collections.sort(system_classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> server_classes=null;
|
||||||
|
if (_serverClasses!=null)
|
||||||
|
{
|
||||||
|
server_classes=new ArrayList<>(_serverClasses);
|
||||||
|
Collections.sort(server_classes);
|
||||||
|
}
|
||||||
|
|
||||||
dumpBeans(out,indent,
|
dumpBeans(out,indent,
|
||||||
Collections.singletonList(new ClassLoaderDump(getClassLoader())),
|
Collections.singletonList(new ClassLoaderDump(getClassLoader())),
|
||||||
Collections.singletonList(new DumpableCollection("Systemclasses "+this,_systemClasses)),
|
Collections.singletonList(new DumpableCollection("Systemclasses "+this,system_classes)),
|
||||||
Collections.singletonList(new DumpableCollection("Serverclasses "+this,_serverClasses)),
|
Collections.singletonList(new DumpableCollection("Serverclasses "+this,server_classes)),
|
||||||
Collections.singletonList(new DumpableCollection("Configurations "+this,_configurations)),
|
Collections.singletonList(new DumpableCollection("Configurations "+this,_configurations)),
|
||||||
Collections.singletonList(new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
|
Collections.singletonList(new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
|
||||||
Collections.singletonList(new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet())),
|
Collections.singletonList(new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet())),
|
||||||
|
@ -1478,7 +1573,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
{
|
{
|
||||||
//not one of the standard servlet listeners, check our extended session listener types
|
//not one of the standard servlet listeners, check our extended session listener types
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
for (Class l:SessionHandler.SESSION_LISTENER_TYPES)
|
for (Class<?> l:SessionHandler.SESSION_LISTENER_TYPES)
|
||||||
{
|
{
|
||||||
if (l.isAssignableFrom(listener))
|
if (l.isAssignableFrom(listener))
|
||||||
{
|
{
|
||||||
|
@ -1506,11 +1601,11 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
for (int i=resources.length;i-->0;)
|
for (int i=resources.length;i-->0;)
|
||||||
{
|
{
|
||||||
if (resources[i].getName().startsWith("jar:file"))
|
if (resources[i].getName().startsWith("jar:file"))
|
||||||
return resources[i].getURL();
|
return resources[i].getURI().toURL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resource.getURL();
|
return resource.getURI().toURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -1536,7 +1631,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
return servletContext;
|
return servletContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -1544,4 +1638,53 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
{
|
{
|
||||||
return _metadata;
|
return _metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public static void addServerClasses(Server server,String... pattern )
|
||||||
|
{
|
||||||
|
// look for a Server attribute with the list of Server classes
|
||||||
|
// to apply to every web application. If not present, use our defaults.
|
||||||
|
Object o = server.getAttribute(SERVER_SRV_CLASSES);
|
||||||
|
|
||||||
|
if (o instanceof ClasspathPattern)
|
||||||
|
{
|
||||||
|
((ClasspathPattern)o).add(pattern);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] server_classes;
|
||||||
|
if (o instanceof String[])
|
||||||
|
server_classes = (String[])o;
|
||||||
|
else
|
||||||
|
server_classes = __dftServerClasses;
|
||||||
|
int l = server_classes.length;
|
||||||
|
server_classes = Arrays.copyOf(server_classes,l+pattern.length);
|
||||||
|
System.arraycopy(pattern,0,server_classes,l,pattern.length);
|
||||||
|
server.setAttribute(SERVER_SRV_CLASSES,server_classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public static void addSystemClasses(Server server,String... pattern )
|
||||||
|
{
|
||||||
|
// look for a Server attribute with the list of System classes
|
||||||
|
// to apply to every web application. If not present, use our defaults.
|
||||||
|
Object o = server.getAttribute(SERVER_SYS_CLASSES);
|
||||||
|
|
||||||
|
if (o instanceof ClasspathPattern)
|
||||||
|
{
|
||||||
|
((ClasspathPattern)o).add(pattern);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] system_classes;
|
||||||
|
if (o instanceof String[])
|
||||||
|
system_classes = (String[])o;
|
||||||
|
else
|
||||||
|
system_classes = __dftSystemClasses;
|
||||||
|
int l = system_classes.length;
|
||||||
|
system_classes = Arrays.copyOf(system_classes,l+pattern.length);
|
||||||
|
System.arraycopy(pattern,0,system_classes,l,pattern.length);
|
||||||
|
server.setAttribute(SERVER_SYS_CLASSES,system_classes);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,101 +18,214 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.webapp;
|
package org.eclipse.jetty.webapp;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.toolchain.test.JDK;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import sun.security.provider.Sun;
|
||||||
|
|
||||||
public class ClasspathPatternTest
|
public class ClasspathPatternTest
|
||||||
{
|
{
|
||||||
private final ClasspathPattern pattern = new ClasspathPattern();
|
private final ClasspathPattern _pattern = new ClasspathPattern();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before()
|
public void before()
|
||||||
{
|
{
|
||||||
pattern.clear();
|
_pattern.clear();
|
||||||
pattern.add("org.package.");
|
_pattern.add("org.package.");
|
||||||
pattern.add("-org.excluded.");
|
_pattern.add("-org.excluded.");
|
||||||
pattern.add("org.example.FooBar");
|
_pattern.add("org.example.FooBar");
|
||||||
pattern.add("-org.example.Excluded");
|
_pattern.add("-org.example.Excluded");
|
||||||
pattern.addAll(Arrays.asList(new String[]{"-org.example.Nested$Minus","org.example.Nested","org.example.Nested$Something"}));
|
_pattern.addAll(Arrays.asList(new String[]{
|
||||||
|
"-org.example.Nested$Minus",
|
||||||
|
"org.example.Nested",
|
||||||
|
"org.example.Nested$Something"}));
|
||||||
|
|
||||||
|
|
||||||
|
assertThat(_pattern,containsInAnyOrder(
|
||||||
|
"org.package.",
|
||||||
|
"-org.excluded.",
|
||||||
|
"org.example.FooBar",
|
||||||
|
"-org.example.Excluded",
|
||||||
|
"-org.example.Nested$Minus",
|
||||||
|
"org.example.Nested",
|
||||||
|
"org.example.Nested$Something"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClassMatch()
|
public void testClassMatch()
|
||||||
{
|
{
|
||||||
assertTrue(pattern.match("org.example.FooBar"));
|
assertTrue(_pattern.match("org.example.FooBar"));
|
||||||
assertTrue(pattern.match("org.example.Nested"));
|
assertTrue(_pattern.match("org.example.Nested"));
|
||||||
|
|
||||||
assertFalse(pattern.match("org.example.Unknown"));
|
assertFalse(_pattern.match("org.example.Unknown"));
|
||||||
assertFalse(pattern.match("org.example.FooBar.Unknown"));
|
assertFalse(_pattern.match("org.example.FooBar.Unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPackageMatch()
|
public void testPackageMatch()
|
||||||
{
|
{
|
||||||
assertTrue(pattern.match("org.package.Something"));
|
assertTrue(_pattern.match("org.package.Something"));
|
||||||
assertTrue(pattern.match("org.package.other.Something"));
|
assertTrue(_pattern.match("org.package.other.Something"));
|
||||||
|
|
||||||
assertFalse(pattern.match("org.example.Unknown"));
|
assertFalse(_pattern.match("org.example.Unknown"));
|
||||||
assertFalse(pattern.match("org.example.FooBar.Unknown"));
|
assertFalse(_pattern.match("org.example.FooBar.Unknown"));
|
||||||
assertFalse(pattern.match("org.example.FooBarElse"));
|
assertFalse(_pattern.match("org.example.FooBarElse"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExplicitNestedMatch()
|
public void testExplicitNestedMatch()
|
||||||
{
|
{
|
||||||
assertTrue(pattern.match("org.example.Nested$Something"));
|
assertTrue(_pattern.match("org.example.Nested$Something"));
|
||||||
assertFalse(pattern.match("org.example.Nested$Minus"));
|
assertFalse(_pattern.match("org.example.Nested$Minus"));
|
||||||
assertTrue(pattern.match("org.example.Nested$Other"));
|
assertTrue(_pattern.match("org.example.Nested$Other"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImplicitNestedMatch()
|
public void testImplicitNestedMatch()
|
||||||
{
|
{
|
||||||
assertTrue(pattern.match("org.example.FooBar$Other"));
|
assertTrue(_pattern.match("org.example.FooBar$Other"));
|
||||||
assertTrue(pattern.match("org.example.Nested$Other"));
|
assertTrue(_pattern.match("org.example.Nested$Other"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddBefore()
|
|
||||||
{
|
|
||||||
pattern.addBefore("-org.excluded.","org.excluded.ExceptionOne","org.excluded.ExceptionTwo");
|
|
||||||
|
|
||||||
assertTrue(pattern.match("org.excluded.ExceptionOne"));
|
|
||||||
assertTrue(pattern.match("org.excluded.ExceptionTwo"));
|
|
||||||
|
|
||||||
assertFalse(pattern.match("org.example.Unknown"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddAfter()
|
|
||||||
{
|
|
||||||
pattern.addAfter("org.package.","org.excluded.ExceptionOne","org.excluded.ExceptionTwo");
|
|
||||||
|
|
||||||
assertTrue(pattern.match("org.excluded.ExceptionOne"));
|
|
||||||
assertTrue(pattern.match("org.excluded.ExceptionTwo"));
|
|
||||||
|
|
||||||
assertFalse(pattern.match("org.example.Unknown"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDoubledNested()
|
public void testDoubledNested()
|
||||||
{
|
{
|
||||||
assertTrue(pattern.match("org.example.Nested$Something$Else"));
|
assertTrue(_pattern.match("org.example.Nested$Something$Else"));
|
||||||
|
|
||||||
assertFalse(pattern.match("org.example.Nested$Minus$Else"));
|
assertFalse(_pattern.match("org.example.Nested$Minus$Else"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatchAll()
|
public void testMatchAll()
|
||||||
{
|
{
|
||||||
pattern.clear();
|
_pattern.clear();
|
||||||
pattern.add(".");
|
_pattern.add(".");
|
||||||
assertTrue(pattern.match("org.example.Anything"));
|
assertTrue(_pattern.match("org.example.Anything"));
|
||||||
assertTrue(pattern.match("org.example.Anything$Else"));
|
assertTrue(_pattern.match("org.example.Anything$Else"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("restriction")
|
||||||
|
@Test
|
||||||
|
public void testiIncludedLocations() throws Exception
|
||||||
|
{
|
||||||
|
// jar from JVM classloader
|
||||||
|
Resource loc_string = TypeUtil.getLoadedFrom(String.class);
|
||||||
|
// System.err.println(loc_string);
|
||||||
|
|
||||||
|
// another jar from JVM classloader
|
||||||
|
Resource loc_jsse = TypeUtil.getLoadedFrom(Sun.class);
|
||||||
|
// System.err.println(loc_jsse);
|
||||||
|
|
||||||
|
// a jar from maven repo jar
|
||||||
|
Resource loc_junit = TypeUtil.getLoadedFrom(Test.class);
|
||||||
|
// System.err.println(loc_junit);
|
||||||
|
|
||||||
|
// a jar from another maven repo jar
|
||||||
|
Resource loc_tool = TypeUtil.getLoadedFrom(JDK.class);
|
||||||
|
// System.err.println(loc_tool);
|
||||||
|
|
||||||
|
// class file
|
||||||
|
Resource loc_test = TypeUtil.getLoadedFrom(ClasspathPatternTest.class);
|
||||||
|
// System.err.println(loc_test);
|
||||||
|
|
||||||
|
ClasspathPattern pattern = new ClasspathPattern();
|
||||||
|
pattern.include("something");
|
||||||
|
assertThat(pattern.match(String.class),is(false));
|
||||||
|
assertThat(pattern.match(Sun.class),is(false));
|
||||||
|
assertThat(pattern.match(Test.class),is(false));
|
||||||
|
assertThat(pattern.match(JDK.class),is(false));
|
||||||
|
assertThat(pattern.match(ClasspathPatternTest.class),is(false));
|
||||||
|
|
||||||
|
// Add directory for both JVM classes
|
||||||
|
pattern.include(loc_string.getFile().getParentFile().toURI().toString());
|
||||||
|
|
||||||
|
// Add jar for individual class and classes directory
|
||||||
|
pattern.include(loc_junit.toString(),loc_test.toString());
|
||||||
|
|
||||||
|
assertThat(pattern.match(String.class),is(true));
|
||||||
|
assertThat(pattern.match(Sun.class),is(true));
|
||||||
|
assertThat(pattern.match(Test.class),is(true));
|
||||||
|
assertThat(pattern.match(JDK.class),is(false));
|
||||||
|
assertThat(pattern.match(ClasspathPatternTest.class),is(true));
|
||||||
|
|
||||||
|
// exclude by package name still works
|
||||||
|
pattern.add("-sun.security.provider.Sun");
|
||||||
|
assertThat(pattern.match(String.class),is(true));
|
||||||
|
assertThat(pattern.match(Sun.class),is(false));
|
||||||
|
assertThat(pattern.match(Test.class),is(true));
|
||||||
|
assertThat(pattern.match(JDK.class),is(false));
|
||||||
|
assertThat(pattern.match(ClasspathPatternTest.class),is(true));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("restriction")
|
||||||
|
@Test
|
||||||
|
public void testExcludeLocations() throws Exception
|
||||||
|
{
|
||||||
|
// jar from JVM classloader
|
||||||
|
Resource loc_string = TypeUtil.getLoadedFrom(String.class);
|
||||||
|
// System.err.println(loc_string);
|
||||||
|
|
||||||
|
// another jar from JVM classloader
|
||||||
|
Resource loc_jsse = TypeUtil.getLoadedFrom(Sun.class);
|
||||||
|
// System.err.println(loc_jsse);
|
||||||
|
|
||||||
|
// a jar from maven repo jar
|
||||||
|
Resource loc_junit = TypeUtil.getLoadedFrom(Test.class);
|
||||||
|
// System.err.println(loc_junit);
|
||||||
|
|
||||||
|
// a jar from another maven repo jar
|
||||||
|
Resource loc_tool = TypeUtil.getLoadedFrom(JDK.class);
|
||||||
|
// System.err.println(loc_tool);
|
||||||
|
|
||||||
|
// class file
|
||||||
|
Resource loc_test = TypeUtil.getLoadedFrom(ClasspathPatternTest.class);
|
||||||
|
// System.err.println(loc_test);
|
||||||
|
|
||||||
|
ClasspathPattern pattern = new ClasspathPattern();
|
||||||
|
|
||||||
|
// include everything
|
||||||
|
pattern.include(".");
|
||||||
|
|
||||||
|
assertThat(pattern.match(String.class),is(true));
|
||||||
|
assertThat(pattern.match(Sun.class),is(true));
|
||||||
|
assertThat(pattern.match(Test.class),is(true));
|
||||||
|
assertThat(pattern.match(JDK.class),is(true));
|
||||||
|
assertThat(pattern.match(ClasspathPatternTest.class),is(true));
|
||||||
|
|
||||||
|
// Add directory for both JVM classes
|
||||||
|
pattern.exclude(loc_string.getFile().getParentFile().toURI().toString());
|
||||||
|
|
||||||
|
// Add jar for individual class and classes directory
|
||||||
|
pattern.exclude(loc_junit.toString(),loc_test.toString());
|
||||||
|
|
||||||
|
assertThat(pattern.match(String.class),is(false));
|
||||||
|
assertThat(pattern.match(Sun.class),is(false));
|
||||||
|
assertThat(pattern.match(Test.class),is(false));
|
||||||
|
assertThat(pattern.match(JDK.class),is(true));
|
||||||
|
assertThat(pattern.match(ClasspathPatternTest.class),is(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,6 @@ public class WebAppClassLoaderTest
|
||||||
this.testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
|
this.testWebappDir = MavenTestingUtils.getProjectDirPath("src/test/webapp");
|
||||||
Resource webapp = new PathResource(testWebappDir);
|
Resource webapp = new PathResource(testWebappDir);
|
||||||
|
|
||||||
System.err.printf("testWebappDir = %s%n", testWebappDir);
|
|
||||||
|
|
||||||
_context = new WebAppContext();
|
_context = new WebAppContext();
|
||||||
_context.setBaseResource(webapp);
|
_context.setBaseResource(webapp);
|
||||||
_context.setContextPath("/test");
|
_context.setContextPath("/test");
|
||||||
|
@ -66,6 +64,9 @@ public class WebAppClassLoaderTest
|
||||||
_loader.addJars(webapp.addPath("WEB-INF/lib"));
|
_loader.addJars(webapp.addPath("WEB-INF/lib"));
|
||||||
_loader.addClassPath(webapp.addPath("WEB-INF/classes"));
|
_loader.addClassPath(webapp.addPath("WEB-INF/classes"));
|
||||||
_loader.setName("test");
|
_loader.setName("test");
|
||||||
|
|
||||||
|
_context.loadSystemClasses();
|
||||||
|
_context.loadServerClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertCanLoadClass(String clazz) throws ClassNotFoundException
|
public void assertCanLoadClass(String clazz) throws ClassNotFoundException
|
||||||
|
@ -250,7 +251,7 @@ public class WebAppClassLoaderTest
|
||||||
URL targetTestClasses = this.getClass().getClassLoader().getResource("org/acme/resource.txt");
|
URL targetTestClasses = this.getClass().getClassLoader().getResource("org/acme/resource.txt");
|
||||||
|
|
||||||
_context.setParentLoaderPriority(false);
|
_context.setParentLoaderPriority(false);
|
||||||
dump(_context);
|
|
||||||
resources =Collections.list(_loader.getResources("org/acme/resource.txt"));
|
resources =Collections.list(_loader.getResources("org/acme/resource.txt"));
|
||||||
|
|
||||||
expected.clear();
|
expected.clear();
|
||||||
|
@ -260,12 +261,6 @@ public class WebAppClassLoaderTest
|
||||||
|
|
||||||
assertThat("Resources Found (Parent Loader Priority == false)",resources,ordered(expected));
|
assertThat("Resources Found (Parent Loader Priority == false)",resources,ordered(expected));
|
||||||
|
|
||||||
// dump(resources);
|
|
||||||
// assertEquals(3,resources.size());
|
|
||||||
// assertEquals(0,resources.get(0).toString().indexOf("jar:file:"));
|
|
||||||
// assertEquals(-1,resources.get(1).toString().indexOf("test-classes"));
|
|
||||||
// assertEquals(0,resources.get(2).toString().indexOf("file:"));
|
|
||||||
|
|
||||||
_context.setParentLoaderPriority(true);
|
_context.setParentLoaderPriority(true);
|
||||||
// dump(_context);
|
// dump(_context);
|
||||||
resources =Collections.list(_loader.getResources("org/acme/resource.txt"));
|
resources =Collections.list(_loader.getResources("org/acme/resource.txt"));
|
||||||
|
@ -320,49 +315,6 @@ public class WebAppClassLoaderTest
|
||||||
|
|
||||||
assertThat("Resources Found (Parent Loader Priority == true) (with systemClasses filtering)",resources,ordered(expected));
|
assertThat("Resources Found (Parent Loader Priority == true) (with systemClasses filtering)",resources,ordered(expected));
|
||||||
|
|
||||||
// dump(resources);
|
|
||||||
// assertEquals(1,resources.size());
|
|
||||||
// assertEquals(0,resources.get(0).toString().indexOf("file:"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dump(WebAppContext wac)
|
|
||||||
{
|
|
||||||
System.err.println("--Dump WebAppContext - " + wac);
|
|
||||||
System.err.printf(" context.getClass().getClassLoader() = %s%n",wac.getClass().getClassLoader());
|
|
||||||
dumpClassLoaderHierarchy(" ",wac.getClass().getClassLoader());
|
|
||||||
System.err.printf(" context.getClassLoader() = %s%n",wac.getClassLoader());
|
|
||||||
dumpClassLoaderHierarchy(" ",wac.getClassLoader());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dumpClassLoaderHierarchy(String indent, ClassLoader classLoader)
|
|
||||||
{
|
|
||||||
if (classLoader != null)
|
|
||||||
{
|
|
||||||
if(classLoader instanceof URLClassLoader)
|
|
||||||
{
|
|
||||||
URLClassLoader urlCL = (URLClassLoader)classLoader;
|
|
||||||
URL urls[] = urlCL.getURLs();
|
|
||||||
for (URL url : urls)
|
|
||||||
{
|
|
||||||
System.err.printf("%s url[] = %s%n",indent,url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassLoader parent = classLoader.getParent();
|
|
||||||
if (parent != null)
|
|
||||||
{
|
|
||||||
System.err.printf("%s .parent = %s%n",indent,parent);
|
|
||||||
dumpClassLoaderHierarchy(indent + " ",parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dump(List<URL> resources)
|
|
||||||
{
|
|
||||||
System.err.println("--Dump--");
|
|
||||||
for(URL url: resources)
|
|
||||||
{
|
|
||||||
System.err.printf(" \"%s\"%n",url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue