480904 - jetty-util Loader simplification

The Loader has been simplified to now just be a switch between loading from the context loader,
the same loader as another class or the system loader.    Multiple loaders will never be tried.

A new runWithServerClassAccess(PriviledgedAction) method has been added to WebAppClassLoader, that
is now used during configuration for actions that need access to both the WEB-INF/lib classes and
the server classes (eg jetty-web.xml and env.xml).

The JMX MBean mechanism has also been modified to look for an MBean class in the same loader that
object came from before attempting the context loader (only if different).
This commit is contained in:
Greg Wilkins 2015-11-19 12:10:36 +11:00
parent 65d33f8b49
commit a311c8bde1
35 changed files with 157 additions and 166 deletions

View File

@ -52,9 +52,8 @@ public class OneWebApp
WebAppContext webapp = new WebAppContext(); WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/"); webapp.setContextPath("/");
File warFile = new File( File warFile = new File(
"../../jetty-distribution/target/distribution/test/webapps/test/"); "../../tests/test-jmx/jmx-webapp/target/jmx-webapp");
webapp.setWar(warFile.getAbsolutePath()); webapp.setWar(warFile.getAbsolutePath());
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
// A WebAppContext is a ContextHandler as well so it needs to be set to // A WebAppContext is a ContextHandler as well so it needs to be set to
// the server so it is aware of where to send the appropriate requests. // the server so it is aware of where to send the appropriate requests.

View File

@ -558,7 +558,7 @@ public class AnnotationParser
if (!isParsed(className) || resolver.shouldOverride(className)) if (!isParsed(className) || resolver.shouldOverride(className))
{ {
className = className.replace('.', '/')+".class"; className = className.replace('.', '/')+".class";
URL resource = Loader.getResource(this.getClass(), className); URL resource = Loader.getResource(className);
if (resource!= null) if (resource!= null)
{ {
Resource r = Resource.newResource(resource); Resource r = Resource.newResource(resource);
@ -593,7 +593,7 @@ public class AnnotationParser
if (!isParsed(cz.getName()) || resolver.shouldOverride(cz.getName())) if (!isParsed(cz.getName()) || resolver.shouldOverride(cz.getName()))
{ {
String nameAsResource = cz.getName().replace('.', '/')+".class"; String nameAsResource = cz.getName().replace('.', '/')+".class";
URL resource = Loader.getResource(this.getClass(), nameAsResource); URL resource = Loader.getResource(nameAsResource);
if (resource!= null) if (resource!= null)
{ {
Resource r = Resource.newResource(resource); Resource r = Resource.newResource(resource);
@ -652,7 +652,7 @@ public class AnnotationParser
if ((resolver == null) || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s)))) if ((resolver == null) || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s))))
{ {
s = s.replace('.', '/')+".class"; s = s.replace('.', '/')+".class";
URL resource = Loader.getResource(this.getClass(), s); URL resource = Loader.getResource(s);
if (resource!= null) if (resource!= null)
{ {
Resource r = Resource.newResource(resource); Resource r = Resource.newResource(resource);

View File

@ -201,7 +201,7 @@ public class Util
} }
case Type.OBJECT: case Type.OBJECT:
{ {
return (Loader.loadClass(null, t.getClassName())); return (Loader.loadClass(t.getClassName()));
} }
case Type.SHORT: case Type.SHORT:
{ {

View File

@ -222,7 +222,7 @@ public class JAASLoginService extends AbstractLifeCycle implements LoginService
} }
else else
{ {
Class<?> clazz = Loader.loadClass(getClass(), _callbackHandlerClass); Class<?> clazz = Loader.loadClass(_callbackHandlerClass);
callbackHandler = (CallbackHandler)clazz.newInstance(); callbackHandler = (CallbackHandler)clazz.newInstance();
} }
//set up the login context //set up the login context

View File

@ -103,7 +103,7 @@ public class JDBCLoginModule extends AbstractDatabaseLoginModule
dbPassword = ""; dbPassword = "";
if (dbDriver != null) if (dbDriver != null)
Loader.loadClass(this.getClass(), dbDriver).newInstance(); Loader.loadClass(dbDriver).newInstance();
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {

View File

@ -129,8 +129,21 @@ public class ObjectMBean implements DynamicMBean
String mName = pName + ".jmx." + cName + "MBean"; String mName = pName + ".jmx." + cName + "MBean";
try try
{ {
Class<?> mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName); Class<?> mClass;
try
{
// Look for an MBean class from the same loader that loaded the original class
mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName);
}
catch (ClassNotFoundException e)
{
// Not found, so if not the same as the thread context loader, try that.
if (Thread.currentThread().getContextClassLoader()==oClass.getClassLoader())
throw e;
LOG.ignore(e);
mClass=Loader.loadClass(oClass,mName);
}
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("ObjectMbean: mbeanFor {} mClass={}", o, mClass); LOG.debug("ObjectMbean: mbeanFor {} mClass={}", o, mClass);

View File

@ -127,7 +127,7 @@ public class ContainerInitializer
try try
{ {
for (String s : _applicableTypeNames) for (String s : _applicableTypeNames)
classes.add(Loader.loadClass(context.getClass(), s)); classes.add(Loader.loadClass(s));
context.getServletContext().setExtendedListenerTypes(true); context.getServletContext().setExtendedListenerTypes(true);
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())

View File

@ -106,7 +106,7 @@ public abstract class LifeCycleCallback
if (_target == null) if (_target == null)
{ {
if (_targetClass == null) if (_targetClass == null)
_targetClass = Loader.loadClass(null, _className); _targetClass = Loader.loadClass(_className);
_target = _targetClass.getDeclaredMethod(_methodName, TypeUtil.NO_ARGS); _target = _targetClass.getDeclaredMethod(_methodName, TypeUtil.NO_ARGS);
} }

View File

@ -41,6 +41,7 @@ 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.webapp.AbstractConfiguration; import org.eclipse.jetty.webapp.AbstractConfiguration;
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;
@ -113,7 +114,7 @@ public class EnvConfiguration extends AbstractConfiguration
{ {
localContextRoot.getRoot().addListener(listener); localContextRoot.getRoot().addListener(listener);
XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl); XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl);
configuration.configure(context); WebAppClassLoader.runWithServerClassAccess(()->{configuration.configure(context);return null;});
} }
finally finally
{ {

View File

@ -164,7 +164,7 @@ public class JDBCLoginService extends MappedLoginService
+ " = u." + " = u."
+ _userRoleTableRoleKey; + _userRoleTableRoleKey;
Loader.loadClass(this.getClass(), _jdbcDriver).newInstance(); Loader.loadClass(_jdbcDriver).newInstance();
super.doStart(); super.doStart();
} }

View File

@ -1673,7 +1673,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
return null; return null;
if (_classLoader == null) if (_classLoader == null)
return Loader.loadClass(this.getClass(),className); return Loader.loadClass(className);
return _classLoader.loadClass(className); return _classLoader.loadClass(className);
} }
@ -2317,7 +2317,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
try try
{ {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
Class<? extends EventListener> clazz = _classLoader==null?Loader.loadClass(ContextHandler.class,className):(Class)_classLoader.loadClass(className); Class<? extends EventListener> clazz = _classLoader==null?Loader.loadClass(className):(Class)_classLoader.loadClass(className);
addListener(clazz); addListener(clazz);
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
@ -2410,7 +2410,7 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
//classloader, or a parent of it //classloader, or a parent of it
try try
{ {
Class<?> reflect = Loader.loadClass(getClass(), "sun.reflect.Reflection"); Class<?> reflect = Loader.loadClass("sun.reflect.Reflection");
Method getCallerClass = reflect.getMethod("getCallerClass", Integer.TYPE); Method getCallerClass = reflect.getMethod("getCallerClass", Integer.TYPE);
Class<?> caller = (Class<?>)getCallerClass.invoke(null, 2); Class<?> caller = (Class<?>)getCallerClass.invoke(null, 2);

View File

@ -92,7 +92,7 @@ public abstract class BaseHolder<T> extends AbstractLifeCycle implements Dumpabl
{ {
try try
{ {
_class=Loader.loadClass(Holder.class, _className); _class=Loader.loadClass(_className);
if(LOG.isDebugEnabled()) if(LOG.isDebugEnabled())
LOG.debug("Holding {} from {}",_class,_class.getClassLoader()); LOG.debug("Holding {} from {}",_class,_class.getClassLoader());
} }

View File

@ -421,7 +421,7 @@ public class ServletContextHandler extends ContextHandler
*/ */
public ServletHolder addServlet(Class<? extends Servlet> servlet,String pathSpec) public ServletHolder addServlet(Class<? extends Servlet> servlet,String pathSpec)
{ {
return getServletHandler().addServletWithMapping(servlet.getName(), pathSpec); return getServletHandler().addServletWithMapping(servlet,pathSpec);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -875,7 +875,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
try try
{ {
//check for apache //check for apache
Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS); Loader.loadClass(APACHE_SENTINEL_CLASS);
if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected"); if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
_jspContainer = JspContainer.APACHE; _jspContainer = JspContainer.APACHE;
} }
@ -897,7 +897,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
jsp = jsp.substring(i); jsp = jsp.substring(i);
try try
{ {
Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil"); Class<?> jspUtil = Loader.loadClass("org.apache.jasper.compiler.JspUtil");
Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class); Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
return (String)makeJavaIdentifier.invoke(null, jsp); return (String)makeJavaIdentifier.invoke(null, jsp);
} }
@ -923,7 +923,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
return ""; return "";
try try
{ {
Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil"); Class<?> jspUtil = Loader.loadClass("org.apache.jasper.compiler.JspUtil");
Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class); Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
return (String)makeJavaPackage.invoke(null, jsp.substring(0,i)); return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
} }

View File

@ -52,7 +52,7 @@ public class ELContextCleaner implements ServletContextListener
try try
{ {
//Check that the BeanELResolver class is on the classpath //Check that the BeanELResolver class is on the classpath
Class<?> beanELResolver = Loader.loadClass(this.getClass(), "javax.el.BeanELResolver"); Class<?> beanELResolver = Loader.loadClass("javax.el.BeanELResolver");
//Get a reference via reflection to the properties field which is holding class references //Get a reference via reflection to the properties field which is holding class references
Field field = getField(beanELResolver); Field field = getField(beanELResolver);

View File

@ -935,7 +935,7 @@ public class JSON
{ {
try try
{ {
Class c = Loader.loadClass(JSON.class,classname); Class c = Loader.loadClass(classname);
return convertTo(c,map); return convertTo(c,map);
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)

View File

@ -36,7 +36,7 @@ public class JSONCollectionConvertor implements JSON.Convertor
{ {
try try
{ {
Collection result = (Collection)Loader.loadClass(getClass(), (String)object.get("class")).newInstance(); Collection result = (Collection)Loader.loadClass((String)object.get("class")).newInstance();
Collections.addAll(result, (Object[])object.get("list")); Collections.addAll(result, (Object[])object.get("list"));
return result; return result;
} }

View File

@ -43,7 +43,7 @@ public class JSONEnumConvertor implements JSON.Convertor
{ {
try try
{ {
Class<?> e = Loader.loadClass(getClass(),"java.lang.Enum"); Class<?> e = Loader.loadClass("java.lang.Enum");
_valueOf=e.getMethod("valueOf",Class.class,String.class); _valueOf=e.getMethod("valueOf",Class.class,String.class);
} }
catch(Exception e) catch(Exception e)
@ -68,7 +68,7 @@ public class JSONEnumConvertor implements JSON.Convertor
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
try try
{ {
Class c=Loader.loadClass(getClass(),(String)map.get("class")); Class c=Loader.loadClass((String)map.get("class"));
return _valueOf.invoke(null,c,map.get("value")); return _valueOf.invoke(null,c,map.get("value"));
} }
catch(Exception e) catch(Exception e)

View File

@ -65,7 +65,7 @@ public class JSONPojoConvertorFactory implements JSON.Convertor
{ {
try try
{ {
Class cls=Loader.loadClass(JSON.class,clsName); Class cls=Loader.loadClass(clsName);
convertor=new JSONPojoConvertor(cls,_fromJson); convertor=new JSONPojoConvertor(cls,_fromJson);
_json.addConvertorFor(clsName, convertor); _json.addConvertorFor(clsName, convertor);
} }
@ -91,7 +91,7 @@ public class JSONPojoConvertorFactory implements JSON.Convertor
{ {
try try
{ {
Class cls=Loader.loadClass(JSON.class,clsName); Class cls=Loader.loadClass(clsName);
convertor=new JSONPojoConvertor(cls,_fromJson); convertor=new JSONPojoConvertor(cls,_fromJson);
_json.addConvertorFor(clsName, convertor); _json.addConvertorFor(clsName, convertor);
} }

View File

@ -46,107 +46,55 @@ import org.eclipse.jetty.util.resource.Resource;
public class Loader public class Loader
{ {
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static URL getResource(Class<?> loadClass,String name) public static URL getResource(String name)
{ {
URL url =null; ClassLoader loader=Thread.currentThread().getContextClassLoader();
ClassLoader context_loader=Thread.currentThread().getContextClassLoader(); return loader==null?ClassLoader.getSystemResource(name):loader.getResource(name);
if (context_loader!=null)
url=context_loader.getResource(name);
if (url==null && loadClass!=null)
{
ClassLoader load_loader=loadClass.getClassLoader();
if (load_loader!=null && load_loader!=context_loader)
url=load_loader.getResource(name);
}
if (url==null)
url=ClassLoader.getSystemResource(name);
return url;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Load a class. /** Load a class.
* <p>Load a class either from the thread context classloader or if none, the system
* loader</p>
* @param name the name of the new class to load
* *
* @param loadClass the class to use for the ClassLoader that was used
* @param name the name of the new class to load, using the same ClassLoader as the <code>loadClass</code>
* @return Class * @return Class
* @throws ClassNotFoundException if not able to find the class * @throws ClassNotFoundException if not able to find the class
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static Class loadClass(Class loadClass,String name) public static Class loadClass(String name)
throws ClassNotFoundException throws ClassNotFoundException
{ {
ClassNotFoundException ex=null; ClassLoader loader=Thread.currentThread().getContextClassLoader();
Class<?> c =null; return (loader==null ) ? Class.forName(name) : loader.loadClass(name);
ClassLoader context_loader=Thread.currentThread().getContextClassLoader(); }
if (context_loader!=null )
{
try { c=context_loader.loadClass(name); }
catch (ClassNotFoundException e) {ex=e;}
}
if (c==null && loadClass!=null)
{
ClassLoader load_loader=loadClass.getClassLoader();
if (load_loader!=null && load_loader!=context_loader)
{
try { c=load_loader.loadClass(name); }
catch (ClassNotFoundException e) {if(ex==null)ex=e;}
}
}
if (c==null) /* ------------------------------------------------------------ */
{ /** Load a class.
try { c=Class.forName(name); } * Load a class from the same classloader as the passed <code>loadClass</code>, or if none
catch (ClassNotFoundException e) * then use {@link #loadClass(String)}
{ *
if(ex!=null) * @return Class
throw ex; * @throws ClassNotFoundException if not able to find the class
throw e; */
} @SuppressWarnings("rawtypes")
} public static Class loadClass(Class loaderClass, String name)
throws ClassNotFoundException
return c; {
if (loaderClass!=null && loaderClass.getClassLoader()!=null)
return loaderClass.getClassLoader().loadClass(name);
return loadClass(name);
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public static ResourceBundle getResourceBundle(Class<?> loadClass,String name,boolean checkParents, Locale locale) public static ResourceBundle getResourceBundle(String name,boolean checkParents,Locale locale)
throws MissingResourceException throws MissingResourceException
{ {
MissingResourceException ex=null;
ResourceBundle bundle =null;
ClassLoader loader=Thread.currentThread().getContextClassLoader(); ClassLoader loader=Thread.currentThread().getContextClassLoader();
while (bundle==null && loader!=null ) return loader==null ? ResourceBundle.getBundle(name, locale) : ResourceBundle.getBundle(name, locale, loader);
{
try { bundle=ResourceBundle.getBundle(name, locale, loader); }
catch (MissingResourceException e) {if(ex==null)ex=e;}
loader=(bundle==null&&checkParents)?loader.getParent():null;
}
loader=loadClass==null?null:loadClass.getClassLoader();
while (bundle==null && loader!=null )
{
try { bundle=ResourceBundle.getBundle(name, locale, loader); }
catch (MissingResourceException e) {if(ex==null)ex=e;}
loader=(bundle==null&&checkParents)?loader.getParent():null;
}
if (bundle==null)
{
try { bundle=ResourceBundle.getBundle(name, locale); }
catch (MissingResourceException e) {if(ex==null)ex=e;}
}
if (bundle!=null)
return bundle;
throw ex;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Generate the classpath (as a string) of all classloaders * Generate the classpath (as a string) of all classloaders

View File

@ -95,7 +95,7 @@ public class JavaUtilLog extends AbstractLogger
{ {
try try
{ {
URL props = Loader.getResource(JavaUtilLog.class,properties); URL props = Loader.getResource(properties);
if (props != null) if (props != null)
LogManager.getLogManager().readConfiguration(props.openStream()); LogManager.getLogManager().readConfiguration(props.openStream());
} }

View File

@ -132,7 +132,7 @@ public class Log
static void loadProperties(String resourceName, Properties props) static void loadProperties(String resourceName, Properties props)
{ {
URL testProps = Loader.getResource(Log.class,resourceName); URL testProps = Loader.getResource(resourceName);
if (testProps != null) if (testProps != null)
{ {
try (InputStream in = testProps.openStream()) try (InputStream in = testProps.openStream())
@ -169,7 +169,7 @@ public class Log
try try
{ {
Class<?> log_class = __logClass==null?null:Loader.loadClass(Log.class, __logClass); Class<?> log_class = __logClass==null?null:Loader.loadClass(__logClass);
if (LOG == null || (log_class!=null && !LOG.getClass().equals(log_class))) if (LOG == null || (log_class!=null && !LOG.getClass().equals(log_class)))
{ {
LOG = (Logger)log_class.newInstance(); LOG = (Logger)log_class.newInstance();

View File

@ -269,7 +269,7 @@ public abstract class Resource implements ResourceFactory, Closeable
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Find a classpath resource. /** Find a classpath resource.
* The {@link java.lang.Class#getResource(String)} method is used to lookup the resource. If it is not * The {@link java.lang.Class#getResource(String)} method is used to lookup the resource. If it is not
* found, then the {@link Loader#getResource(Class, String)} method is used. * found, then the {@link Loader#getResource(String)} method is used.
* If it is still not found, then {@link ClassLoader#getSystemResource(String)} is used. * If it is still not found, then {@link ClassLoader#getSystemResource(String)} is used.
* Unlike {@link ClassLoader#getSystemResource(String)} this method does not check for normal resources. * Unlike {@link ClassLoader#getSystemResource(String)} this method does not check for normal resources.
* @param name The relative name of the resource * @param name The relative name of the resource
@ -283,7 +283,7 @@ public abstract class Resource implements ResourceFactory, Closeable
URL url=Resource.class.getResource(name); URL url=Resource.class.getResource(name);
if (url==null) if (url==null)
url=Loader.getResource(Resource.class,name); url=Loader.getResource(name);
if (url==null) if (url==null)
return null; return null;
return newResource(url,useCaches); return newResource(url,useCaches);

View File

@ -83,7 +83,7 @@ public interface ExecutionStrategy
{ {
try try
{ {
Class<? extends ExecutionStrategy> c = Loader.loadClass(producer.getClass(),strategy); Class<? extends ExecutionStrategy> c = Loader.loadClass(strategy);
Constructor<? extends ExecutionStrategy> m = c.getConstructor(Producer.class,Executor.class); Constructor<? extends ExecutionStrategy> m = c.getConstructor(Producer.class,Executor.class);
LOG.info("Use {} for {}",c.getSimpleName(),producer.getClass().getName()); LOG.info("Use {} for {}",c.getSimpleName(),producer.getClass().getName());
return m.newInstance(producer,executor); return m.newInstance(producer,executor);

View File

@ -79,7 +79,7 @@ public abstract class DiscoveredAnnotation
try try
{ {
_clazz = Loader.loadClass(null, _className); _clazz = Loader.loadClass(_className);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -90,7 +90,7 @@ public class JettyWebXmlConfiguration extends AbstractConfiguration
if (jetty_config==null) if (jetty_config==null)
{ {
jetty_config=new XmlConfiguration(jetty.getURL()); jetty_config=new XmlConfiguration(jetty.getURI().toURL());
} }
else else
{ {
@ -99,7 +99,8 @@ public class JettyWebXmlConfiguration extends AbstractConfiguration
setupXmlConfiguration(jetty_config, web_inf); setupXmlConfiguration(jetty_config, web_inf);
try try
{ {
jetty_config.configure(context); XmlConfiguration config=jetty_config;
WebAppClassLoader.runWithServerClassAccess(()->{config.configure(context);return null;});
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {
@ -125,6 +126,6 @@ public class JettyWebXmlConfiguration extends AbstractConfiguration
{ {
Map<String,String> props = jetty_config.getProperties(); Map<String,String> props = jetty_config.getProperties();
// TODO - should this be an id rather than a property? // TODO - should this be an id rather than a property?
props.put(PROPERTY_THIS_WEB_INF_URL, String.valueOf(web_inf.getURL())); props.put(PROPERTY_THIS_WEB_INF_URL, String.valueOf(web_inf.getURI()));
} }
} }

View File

@ -273,7 +273,7 @@ public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
{ {
try try
{ {
Loader.loadClass(this.getClass(), servlet_class); Loader.loadClass(servlet_class);
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {

View File

@ -27,6 +27,7 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.security.CodeSource; import java.security.CodeSource;
import java.security.PermissionCollection; import java.security.PermissionCollection;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
@ -35,6 +36,7 @@ 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;
@ -71,13 +73,15 @@ public class WebAppClassLoader extends URLClassLoader
} }
private static final Logger LOG = Log.getLogger(WebAppClassLoader.class); private static final Logger LOG = Log.getLogger(WebAppClassLoader.class);
private static final ThreadLocal<Boolean> __loadServerClasses = new ThreadLocal<>();
private final Context _context; private final Context _context;
private final ClassLoader _parent; private final ClassLoader _parent;
private final Set<String> _extensions=new HashSet<String>(); private final Set<String> _extensions=new HashSet<String>();
private String _name=String.valueOf(hashCode()); private String _name=String.valueOf(hashCode());
private final List<ClassFileTransformer> _transformers = new CopyOnWriteArrayList<>(); private final List<ClassFileTransformer> _transformers = new CopyOnWriteArrayList<>();
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** The Context in which the classloader operates. /** The Context in which the classloader operates.
*/ */
@ -133,6 +137,31 @@ public class WebAppClassLoader extends URLClassLoader
String getExtraClasspath(); String getExtraClasspath();
} }
/* ------------------------------------------------------------ */
/** Run an action with access to ServerClasses
* <p>Run the passed {@link PrivilegedExceptionAction} with the classloader
* configured so as to allow server classes to be visible</p>
* @param action The action to run
* @return The return from the action
* @throws Exception
*/
public static <T> T runWithServerClassAccess(PrivilegedExceptionAction<T> action) throws Exception
{
Boolean lsc=__loadServerClasses.get();
try
{
__loadServerClasses.set(true);
return action.run();
}
finally
{
if (lsc==null)
__loadServerClasses.remove();
else
__loadServerClasses.set(lsc);
}
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -333,7 +362,7 @@ public class WebAppClassLoader extends URLClassLoader
public Enumeration<URL> getResources(String name) throws IOException public Enumeration<URL> getResources(String name) throws IOException
{ {
boolean system_class=_context.isSystemClass(name); boolean system_class=_context.isSystemClass(name);
boolean server_class=_context.isServerClass(name); boolean server_class=_context.isServerClass(name) && !Boolean.TRUE.equals(__loadServerClasses.get());
List<URL> from_parent = toList(server_class?null:_parent.getResources(name)); 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)); List<URL> from_webapp = toList((system_class&&!from_parent.isEmpty())?null:this.findResources(name));
@ -376,7 +405,7 @@ public class WebAppClassLoader extends URLClassLoader
tmp = tmp.substring(0, tmp.length()-6); tmp = tmp.substring(0, tmp.length()-6);
boolean system_class=_context.isSystemClass(tmp); boolean system_class=_context.isSystemClass(tmp);
boolean server_class=_context.isServerClass(tmp); boolean server_class=_context.isServerClass(tmp) && !Boolean.TRUE.equals(__loadServerClasses.get());
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("getResource({}) system={} server={} cl={}",name,system_class,server_class,this); LOG.debug("getResource({}) system={} server={} cl={}",name,system_class,server_class,this);
@ -439,7 +468,7 @@ public class WebAppClassLoader extends URLClassLoader
boolean tried_parent= false; boolean tried_parent= false;
boolean system_class=_context.isSystemClass(name); boolean system_class=_context.isSystemClass(name);
boolean server_class=_context.isServerClass(name); boolean server_class=_context.isServerClass(name) && !Boolean.TRUE.equals(__loadServerClasses.get());
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("loadClass({}) system={} server={} cl={}",name,system_class,server_class,this); LOG.debug("loadClass({}) system={} server={} cl={}",name,system_class,server_class,this);

View File

@ -144,6 +144,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
"-org.eclipse.jetty.jaas.", // don't hide jaas classes "-org.eclipse.jetty.jaas.", // don't hide jaas classes
"-org.eclipse.jetty.servlets.", // don't hide jetty servlets "-org.eclipse.jetty.servlets.", // don't hide jetty servlets
"-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet "-org.eclipse.jetty.servlet.DefaultServlet", // don't hide default servlet
"-org.eclipse.jetty.servlet.NoJspServlet", // don't hide noJspServlet servlet
"-org.eclipse.jetty.jsp.", //don't hide jsp servlet "-org.eclipse.jetty.jsp.", //don't hide jsp servlet
"-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners "-org.eclipse.jetty.servlet.listener.", // don't hide useful listeners
"-org.eclipse.jetty.websocket.", // don't hide websocket classes from webapps (allow webapp to use ones from system classloader) "-org.eclipse.jetty.websocket.", // don't hide websocket classes from webapps (allow webapp to use ones from system classloader)
@ -924,7 +925,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
if (_configurationClasses.size()==0) if (_configurationClasses.size()==0)
_configurationClasses.addAll(Configuration.ClassList.serverDefault(getServer())); _configurationClasses.addAll(Configuration.ClassList.serverDefault(getServer()));
for (String configClass : _configurationClasses) for (String configClass : _configurationClasses)
_configurations.add((Configuration)Loader.loadClass(this.getClass(), configClass).newInstance()); _configurations.add((Configuration)Loader.loadClass(configClass).newInstance());
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */

View File

@ -23,8 +23,6 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.servlet.Servlet;
import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.Loader;
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;
@ -89,31 +87,31 @@ public class WebDescriptor extends Descriptor
void mapResources() void mapResources()
{ {
//set up cache of DTDs and schemas locally //set up cache of DTDs and schemas locally
URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd"); URL dtd22=Loader.getResource("javax/servlet/resources/web-app_2_2.dtd");
URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd"); URL dtd23=Loader.getResource("javax/servlet/resources/web-app_2_3.dtd");
URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd"); URL j2ee14xsd=Loader.getResource("javax/servlet/resources/j2ee_1_4.xsd");
URL javaee5=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_5.xsd"); URL javaee5=Loader.getResource("javax/servlet/resources/javaee_5.xsd");
URL javaee6=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_6.xsd"); URL javaee6=Loader.getResource("javax/servlet/resources/javaee_6.xsd");
URL javaee7=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_7.xsd"); URL javaee7=Loader.getResource("javax/servlet/resources/javaee_7.xsd");
URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd"); URL webapp24xsd=Loader.getResource("javax/servlet/resources/web-app_2_4.xsd");
URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd"); URL webapp25xsd=Loader.getResource("javax/servlet/resources/web-app_2_5.xsd");
URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd"); URL webapp30xsd=Loader.getResource("javax/servlet/resources/web-app_3_0.xsd");
URL webapp31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_1.xsd"); URL webapp31xsd=Loader.getResource("javax/servlet/resources/web-app_3_1.xsd");
URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd"); URL webcommon30xsd=Loader.getResource("javax/servlet/resources/web-common_3_0.xsd");
URL webcommon31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_1.xsd"); URL webcommon31xsd=Loader.getResource("javax/servlet/resources/web-common_3_1.xsd");
URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd"); URL webfragment30xsd=Loader.getResource("javax/servlet/resources/web-fragment_3_0.xsd");
URL webfragment31xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_1.xsd"); URL webfragment31xsd=Loader.getResource("javax/servlet/resources/web-fragment_3_1.xsd");
URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd"); URL schemadtd=Loader.getResource("javax/servlet/resources/XMLSchema.dtd");
URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd"); URL xmlxsd=Loader.getResource("javax/servlet/resources/xml.xsd");
URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd"); URL webservice11xsd=Loader.getResource("javax/servlet/resources/j2ee_web_services_client_1_1.xsd");
URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd"); URL webservice12xsd=Loader.getResource("javax/servlet/resources/javaee_web_services_client_1_2.xsd");
URL webservice13xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_3.xsd"); URL webservice13xsd=Loader.getResource("javax/servlet/resources/javaee_web_services_client_1_3.xsd");
URL webservice14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_4.xsd"); URL webservice14xsd=Loader.getResource("javax/servlet/resources/javaee_web_services_client_1_4.xsd");
URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd"); URL datatypesdtd=Loader.getResource("javax/servlet/resources/datatypes.dtd");
URL jsp20xsd = null; URL jsp20xsd = null;
URL jsp21xsd = null; URL jsp21xsd = null;
@ -123,10 +121,10 @@ public class WebDescriptor extends Descriptor
try try
{ {
//try both javax/servlet/resources and javax/servlet/jsp/resources to load //try both javax/servlet/resources and javax/servlet/jsp/resources to load
jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd"); jsp20xsd = Loader.getResource("javax/servlet/resources/jsp_2_0.xsd");
jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd"); jsp21xsd = Loader.getResource("javax/servlet/resources/jsp_2_1.xsd");
jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_2.xsd"); jsp22xsd = Loader.getResource("javax/servlet/resources/jsp_2_2.xsd");
jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_3.xsd"); jsp23xsd = Loader.getResource("javax/servlet/resources/jsp_2_3.xsd");
} }
catch (Exception e) catch (Exception e)
{ {
@ -134,10 +132,10 @@ public class WebDescriptor extends Descriptor
} }
finally finally
{ {
if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_0.xsd"); if (jsp20xsd == null) jsp20xsd = Loader.getResource("javax/servlet/jsp/resources/jsp_2_0.xsd");
if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_1.xsd"); if (jsp21xsd == null) jsp21xsd = Loader.getResource("javax/servlet/jsp/resources/jsp_2_1.xsd");
if (jsp22xsd == null) jsp22xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_2.xsd"); if (jsp22xsd == null) jsp22xsd = Loader.getResource("javax/servlet/jsp/resources/jsp_2_2.xsd");
if (jsp23xsd == null) jsp23xsd = Loader.getResource(Servlet.class, "javax/servlet/jsp/resources/jsp_2_3.xsd"); if (jsp23xsd == null) jsp23xsd = Loader.getResource("javax/servlet/jsp/resources/jsp_2_3.xsd");
} }
redirectEntity("web-app_2_2.dtd",dtd22); redirectEntity("web-app_2_2.dtd",dtd22);

View File

@ -136,7 +136,7 @@ public class BrowserSocket
if (message.charAt(0) == '@') if (message.charAt(0) == '@')
{ {
String name = message.substring(1); String name = message.substring(1);
URL url = Loader.getResource(BrowserSocket.class,name); URL url = Loader.getResource(name);
if (url == null) if (url == null)
{ {
writeMessage("Unable to find resource: " + name); writeMessage("Unable to find resource: " + name);

View File

@ -90,10 +90,10 @@ public class XmlConfiguration
private static XmlParser initParser() private static XmlParser initParser()
{ {
XmlParser parser = new XmlParser(); XmlParser parser = new XmlParser();
URL config60 = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd"); URL config60 = Loader.getResource("org/eclipse/jetty/xml/configure_6_0.dtd");
URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd"); URL config76 = Loader.getResource("org/eclipse/jetty/xml/configure_7_6.dtd");
URL config90 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_0.dtd"); URL config90 = Loader.getResource("org/eclipse/jetty/xml/configure_9_0.dtd");
URL config93 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_9_3.dtd"); URL config93 = Loader.getResource("org/eclipse/jetty/xml/configure_9_3.dtd");
parser.redirectEntity("configure.dtd",config90); parser.redirectEntity("configure.dtd",config90);
parser.redirectEntity("configure_1_0.dtd",config60); parser.redirectEntity("configure_1_0.dtd",config60);
parser.redirectEntity("configure_1_1.dtd",config60); parser.redirectEntity("configure_1_1.dtd",config60);
@ -365,7 +365,7 @@ public class XmlConfiguration
if (className == null) if (className == null)
return null; return null;
return Loader.loadClass(XmlConfiguration.class,className); return Loader.loadClass(className);
} }
/** /**
@ -708,7 +708,7 @@ public class XmlConfiguration
if (clazz!=null) if (clazz!=null)
{ {
// static call // static call
oClass=Loader.loadClass(XmlConfiguration.class,clazz); oClass=Loader.loadClass(clazz);
obj=null; obj=null;
} }
else if (obj!=null) else if (obj!=null)
@ -755,7 +755,7 @@ public class XmlConfiguration
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("XML new " + clazz); LOG.debug("XML new " + clazz);
Class<?> oClass = Loader.loadClass(XmlConfiguration.class,clazz); Class<?> oClass = Loader.loadClass(clazz);
// Find the <Arg> elements // Find the <Arg> elements
Map<String, Object> namedArgMap = new HashMap<>(); Map<String, Object> namedArgMap = new HashMap<>();
@ -846,7 +846,7 @@ public class XmlConfiguration
aClass = InetAddress.class; aClass = InetAddress.class;
break; break;
default: default:
aClass = Loader.loadClass(XmlConfiguration.class, type); aClass = Loader.loadClass(type);
break; break;
} }
} }

View File

@ -172,7 +172,7 @@ public class DataSourceLoginServiceTest
protected void changePassword (String user, String newpwd) throws Exception protected void changePassword (String user, String newpwd) throws Exception
{ {
Loader.loadClass(this.getClass(), "org.apache.derby.jdbc.EmbeddedDriver").newInstance(); Loader.loadClass("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
try (Connection connection = DriverManager.getConnection(DatabaseLoginServiceTestServer.__dbURL, "", ""); try (Connection connection = DriverManager.getConnection(DatabaseLoginServiceTestServer.__dbURL, "", "");
Statement stmt = connection.createStatement()) Statement stmt = connection.createStatement())
{ {

View File

@ -92,7 +92,7 @@ public class DatabaseLoginServiceTestServer
//System.err.println("Running script:"+scriptFile.getAbsolutePath()); //System.err.println("Running script:"+scriptFile.getAbsolutePath());
try (FileInputStream fileStream = new FileInputStream(scriptFile)) try (FileInputStream fileStream = new FileInputStream(scriptFile))
{ {
Loader.loadClass(fileStream.getClass(), "org.apache.derby.jdbc.EmbeddedDriver").newInstance(); Loader.loadClass("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
Connection connection = DriverManager.getConnection(__dbURL, "", ""); Connection connection = DriverManager.getConnection(__dbURL, "", "");
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
return ij.runScript(connection, fileStream, "UTF-8", out, "UTF-8"); return ij.runScript(connection, fileStream, "UTF-8", out, "UTF-8");

View File

@ -52,6 +52,7 @@ public abstract class AbstractSessionRenewTest
int scavengePeriod = 3; int scavengePeriod = 3;
AbstractTestServer server = createServer(0, 1, scavengePeriod); AbstractTestServer server = createServer(0, 1, scavengePeriod);
WebAppContext context = server.addWebAppContext(".", contextPath); WebAppContext context = server.addWebAppContext(".", contextPath);
context.setParentLoaderPriority(true);
context.addServlet(TestServlet.class, servletMapping); context.addServlet(TestServlet.class, servletMapping);
TestHttpSessionIdListener testListener = new TestHttpSessionIdListener(); TestHttpSessionIdListener testListener = new TestHttpSessionIdListener();
context.addEventListener(testListener); context.addEventListener(testListener);