Issue #2740 Ensure OSGiWebappClassLoader uses bundleloader for all loadClass methods. (#2804)

Signed-off-by: Jan Bartel <janb@webtide.com>
This commit is contained in:
Jan Bartel 2018-09-11 12:04:31 +10:00 committed by GitHub
parent 5056ac5895
commit 2dd5fec4f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 22 deletions

View File

@ -93,11 +93,10 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
_osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(contributor); _osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(contributor);
} }
/* ------------------------------------------------------------ */
@Override @Override
public Class<?> loadClass(String name) throws ClassNotFoundException protected Class<?> findClass(String name) throws ClassNotFoundException
{ {
try try
{ {
@ -107,7 +106,8 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
{ {
try try
{ {
return super.loadClass(name);
return super.findClass(name);
} }
catch (ClassNotFoundException cne2) catch (ClassNotFoundException cne2)
{ {
@ -147,6 +147,48 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
return url != null ? url : super.getResource(name); return url != null ? url : super.getResource(name);
} }
@Override
public URL findResource(String name)
{
URL url = _osgiBundleClassLoader.getResource(name);
return url != null ? url : super.findResource(name);
}
/**
* Try to load the class from the bundle classloader.
* We do NOT load it as a resource as the WebAppClassLoader does because the
* url that is returned is an osgi-special url that does not play
* properly with WebAppClassLoader's method of extracting the class
* from the resource. This implementation directly asks the osgi
* bundle classloader to load the given class name.
*
* @see org.eclipse.jetty.webapp.WebAppClassLoader#loadAsResource(java.lang.String, boolean)
*/
@Override
protected Class<?> loadAsResource(String name, boolean checkSystemResource) throws ClassNotFoundException
{
try
{
return _osgiBundleClassLoader.loadClass(name);
}
catch (ClassNotFoundException cne)
{
try
{
return super.loadAsResource(name, checkSystemResource);
}
catch (ClassNotFoundException cne2)
{
throw cne;
}
}
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2) private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
{ {

View File

@ -543,27 +543,17 @@ public class WebAppClassLoader extends URLClassLoader
else else
{ {
// Not parent loader priority, so... // Not parent loader priority, so...
webapp_class = loadAsResource(name, true);
// Try the webapp classloader first if (webapp_class != null)
// 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; return webapp_class;
} }
// Try the parent loader // Try the parent loader
try try
{ {
parent_class = _parent.loadClass(name); parent_class = _parent.loadClass(name);
// If the webapp is allowed to see this class // If the webapp is allowed to see this class
if (Boolean.TRUE.equals(__loadServerClasses.get()) || !_context.isServerClass(parent_class)) if (Boolean.TRUE.equals(__loadServerClasses.get()) || !_context.isServerClass(parent_class))
{ {
@ -579,12 +569,9 @@ public class WebAppClassLoader extends URLClassLoader
// We couldn't find a parent class, so OK to return a webapp one if it exists // 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 // and we just couldn't see it before
if (webapp_url!=null) webapp_class = loadAsResource(name, false);
if (webapp_class != 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; return webapp_class;
} }
@ -628,12 +615,47 @@ public class WebAppClassLoader extends URLClassLoader
return _transformers.remove(transformer); return _transformers.remove(transformer);
} }
/**
* Look for the classname as a resource to avoid loading a class that is
* potentially a system resource.
*
* @param name the name of the class to load
* @param checkSystemResource if true and the class isn't a system class we return it
* @return the loaded class
* @throws ClassNotFoundException
*/
protected Class<?> loadAsResource (final String name, boolean checkSystemResource) throws ClassNotFoundException
{
// Try the webapp classloader first
// Look in the webapp classloader as a resource, to avoid
// loading a system class.
Class<?> webapp_class = null;
String path = name.replace('.', '/').concat(".class");
URL webapp_url = findResource(path);
if (webapp_url!=null && (!checkSystemResource || !_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;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
protected Class<?> findClass(final String name) throws ClassNotFoundException protected Class<?> findClass(final String name) throws ClassNotFoundException
{ {
if (_transformers.isEmpty()) if (_transformers.isEmpty())
{
return super.findClass(name); return super.findClass(name);
}
String path = name.replace('.', '/').concat(".class"); String path = name.replace('.', '/').concat(".class");
URL url = findResource(path); URL url = findResource(path);