blob: 5029c43e52e8763d47eb50b94a4d494f86cfc13e [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.osgi.boot.utils;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
/**
* OSGiClassLoader
*
* Class loader that is aware of a bundle. Similar to WebAppClassLoader from Jetty
* and the OSGiWebAppClassLoader, but works without webapps.
*/
public class OSGiClassLoader extends URLClassLoader
{
private static final Logger LOG = Log.getLogger(OSGiClassLoader.class);
private Bundle _bundle;
private ClassLoader _osgiBundleClassLoader;
private boolean _lookInOsgiFirst = true;
private ClassLoader _parent;
/* ------------------------------------------------------------ */
public OSGiClassLoader(ClassLoader parent, Bundle bundle)
{
super(new URL[]{}, parent);
_parent = getParent();
_bundle = bundle;
_osgiBundleClassLoader = BundleClassLoaderHelperFactory.getFactory().getHelper().getBundleClassLoader(_bundle);
}
/* ------------------------------------------------------------ */
/**
* Get a resource from the classloader
*
* Copied from WebAppClassLoader
*/
public URL getResource(String name)
{
URL url= null;
boolean tried_parent= false;
if (_parent!=null && !_lookInOsgiFirst)
{
tried_parent= true;
if (_parent!=null)
url= _parent.getResource(name);
}
if (url == null)
{
url = _osgiBundleClassLoader.getResource(name);
if (url == null && name.startsWith("/"))
{
if (LOG.isDebugEnabled())
LOG.debug("HACK leading / off " + name);
url = _osgiBundleClassLoader.getResource(name.substring(1));
}
}
if (url == null && !tried_parent)
{
if (_parent!=null)
url= _parent.getResource(name);
}
if (url != null)
if (LOG.isDebugEnabled())
LOG.debug("getResource("+name+")=" + url);
return url;
}
/* ------------------------------------------------------------ */
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
return loadClass(name, false);
}
/* ------------------------------------------------------------ */
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
Class<?> c = findLoadedClass(name);
ClassNotFoundException ex= null;
boolean tried_parent= false;
if (c == null && _parent!=null && !_lookInOsgiFirst)
{
tried_parent= true;
try
{
c= _parent.loadClass(name);
if (LOG.isDebugEnabled())
LOG.debug("loaded " + c);
}
catch (ClassNotFoundException e)
{
ex= e;
}
}
if (c == null)
{
try
{
c= this.findClass(name);
}
catch (ClassNotFoundException e)
{
ex= e;
}
}
if (c == null && _parent!=null && !tried_parent)
c = _parent.loadClass(name);
if (c == null)
throw ex;
if (resolve)
resolveClass(c);
if (LOG.isDebugEnabled())
LOG.debug("loaded " + c+ " from "+c.getClassLoader());
return c;
}
/* ------------------------------------------------------------ */
@Override
public Enumeration<URL> getResources(String name) throws IOException
{
Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
Enumeration<URL> urls = super.getResources(name);
if (_lookInOsgiFirst)
{
return Collections.enumeration(toList(osgiUrls, urls));
}
else
{
return Collections.enumeration(toList(urls, osgiUrls));
}
}
/* ------------------------------------------------------------ */
@Override
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;
}
}
}
/* ------------------------------------------------------------ */
/**
* @param e
* @param e2
* @return
*/
private List<URL> toList(Enumeration<URL> e, Enumeration<URL> e2)
{
List<URL> list = new ArrayList<URL>();
while (e != null && e.hasMoreElements())
list.add(e.nextElement());
while (e2 != null && e2.hasMoreElements())
list.add(e2.nextElement());
return list;
}
}