![JAR search and dependency download from the Maven repository](/logo.png)
jadex.platform.service.library.DelegationURLClassLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-platform Show documentation
Show all versions of jadex-platform Show documentation
The Jadex platform package contains implementations of platform services as well as the platform component itself.
package jadex.platform.service.library;
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.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import jadex.bridge.IResourceIdentifier;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
/**
* The delegation url classloader is responsible for managing
* a own resource plus a set of fixed delegate loaders.
*/
public class DelegationURLClassLoader extends URLClassLoader
{
//-------- attributes --------
/** The resource identifier. */
protected IResourceIdentifier rid;
/** The base class loader. */
protected ClassLoader basecl;
/** The delegation classloader. */
protected List delegates;
/** The parent classloaders (i.e. the support). */
protected List parents;
/** The flattened transitive dependencies without duplicates
(created lazy from delegates list). */
protected volatile Set dependencies;
//-------- constructors --------
/**
* Create a new classloader.
*/
public DelegationURLClassLoader(ClassLoader basecl, DelegationURLClassLoader[] delegates)
{
this(null, null, basecl, delegates);
}
/**
* Create a new classloader.
*/
public DelegationURLClassLoader(IResourceIdentifier rid, URL url, ClassLoader basecl, DelegationURLClassLoader[] delegates)
{
super(url!=null? new URL[]{url}: new URL[0],
// No parent class loader to avoid multiple lookups of unavailable classes (not supported on android)
SReflect.isAndroid()? basecl : null);
this.rid = rid;
this.basecl = basecl;
this.delegates = delegates==null? new ArrayList(): SUtil.arrayToList(delegates);
this.parents = new ArrayList();
// addParentClassLoader(parent);
// if(rid!=null && rid.getLocalIdentifier()!=null)
// System.out.println("delclassloader : "+rid.getLocalIdentifier().getUrl()+" "+SUtil.arrayToString(delegates)+" "+hashCode());
}
//-------- methods --------
/**
* Get the delegates.
* @return The delegates.
*/
public List getDelegateResourceIdentifiers()
{
List ret = new ArrayList();
for(int i=0; i getParentClassLoaders()
{
return (List)(((ArrayList)parents).clone());
}
/**
* Get transitive dependencies as flattened set (without duplicates).
*/
public Set getFlattenedDependencies()
{
if(dependencies==null)
{
synchronized(this)
{
if(dependencies==null)
{
dependencies = computeFlattenedDependencies(getDelegates());
}
}
}
return dependencies;
}
/**
* Get transitive dependencies as flattened set (without duplicates).
*/
public static Set computeFlattenedDependencies(List deps)
{
Set ret = new LinkedHashSet();
for(int i=0; i getDelegates()
{
return delegates;
}
/**
* Get the own url.
*/
public URL getURL()
{
URL[] urls = getURLs();
return urls!=null && urls.length>0? urls[0]: null;
}
/**
* Get the resource identifier.
* @return The resource identifier.
*/
public IResourceIdentifier getResourceIdentifier()
{
return rid;
}
/**
* Set the rid.
* @param rid The rid to set.
*/
public void setResourceIdentifier(IResourceIdentifier rid)
{
this.rid = rid;
}
/**
* Get all managed resource identifiers inlcuding all subdependencies.
* @return The resource identifiers.
*/
public Set getAllResourceIdentifiers()
{
Set ret = new LinkedHashSet();
if(delegates!=null)
{
for(int i=0; i findClass(String name) throws ClassNotFoundException
// {
// System.out.println("find: "+name);
// return super.findClass(name);
// }
/**
* Load a class directly, without delegation to dependencies or base class loader
*/
protected Class> loadDirectClass(String name, boolean resolve) throws ClassNotFoundException
{
// System.out.println("loadClass: "+name+", "+rid);
return super.loadClass(name, resolve);
}
/**
* Load class.
* Overridden to delegate to dependencies, if not found.
*/
protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
Class> ret = null;
if(basecl!=null)
{
try
{
ret = basecl.loadClass(name);
if(resolve)
{
// Todo: should resolve in other class loader?
resolveClass(ret);
}
}
catch(Exception e)
{
// e.printStackTrace();
}
}
if(ret==null)
{
try
{
ret = super.loadClass(name, resolve);
}
catch(ClassNotFoundException e)
{
for(DelegationURLClassLoader dep: getFlattenedDependencies())
{
// System.out.println("findClass: "+name+", "+dep);
try
{
ret = dep.loadDirectClass(name, resolve);
break;
}
catch (ClassNotFoundException ex)
{
}
}
}
}
if(ret==null)
throw new ClassNotFoundException(name);
return ret;
}
/**
* Find the resource.
* @param name The name.
* @return The url.
*/
protected URL findDirectResource(String name)
{
return super.findResource(name);
}
/**
* Find the resource.
* @param name The name.
* @return The url.
*/
public URL findResource(String name)
{
URL ret = null;
if(basecl!=null)
{
ret = basecl.getResource(name);
}
if(ret==null)
{
ret = super.findResource(name);
}
if(ret==null)
{
for(DelegationURLClassLoader dep: getFlattenedDependencies())
{
ret = dep.findDirectResource(name);
if(ret!=null)
break;
}
}
return ret;
}
/**
*
*/
protected ClassLoader getBaseClassLoader()
{
return basecl;
}
/**
* Find the resource.
* @param name The name.
* @return The url.
*/
protected Enumeration findDirectResources(String name) throws IOException
{
return super.findResources(name);
}
/**
* Find the resource.
* @param name The name.
* @return The url.
*/
public Enumeration findResources(String name) throws IOException
{
Set res = new HashSet();
if(basecl!=null)
{
res.addAll(Collections.list(basecl.getResources(name)));
}
res.addAll(Collections.list(super.findResources(name)));
for(DelegationURLClassLoader dep: getFlattenedDependencies())
{
res.addAll(Collections.list(dep.findDirectResources(name)));
}
return Collections.enumeration(res);
}
/**
*
*/
public boolean isClassLoaderCompatible(Class> clazz)
{
ClassLoader clcl = clazz.getClassLoader();
boolean ret = clcl.equals(this);
if(!ret)
{
Set res = new HashSet();
getAllParentLoaders(this, res);
ret = res.contains(clcl);
}
return ret;
}
/**
*
*/
public static void getAllParentLoaders(ClassLoader cl, Set cls)
{
cls.add(cl);
if(cl.getParent()!=null && !cls.contains(cl.getParent()))
{
cls.add(cl.getParent());
getAllParentLoaders(cl.getParent(), cls);
}
if(cl instanceof DelegationURLClassLoader)
{
DelegationURLClassLoader dcl = (DelegationURLClassLoader)cl;
ClassLoader bcl = dcl.getBaseClassLoader();
if(bcl!=null && !cls.contains(bcl))
{
cls.add(bcl);
getAllParentLoaders(bcl, cls);
}
for(DelegationURLClassLoader tst: dcl.getParentClassLoaders())
{
if(!cls.contains(tst))
{
cls.add(tst);
getAllParentLoaders(tst, cls);
}
}
}
}
/**
* Get a string representation.
*/
public String toString()
{
// return SReflect.getInnerClassName(getClass())+"("+rid+", "+SUtil.arrayToString(delegates)+")";
return SReflect.getInnerClassName(getClass())+"("+rid+", "+delegates.size()+", "+basecl+")";
}
// /**
// * Get a string representation.
// */
// public String toString()
// {
// int num = 0;
// try
// {
// Field f = ClassLoader.class.getDeclaredField("classes");
// f.setAccessible(true);
// Vector classes = (Vector)f.get(this);
// num = classes.size();
// }
// catch(Exception e)
// {
// e.printStackTrace();
// }
// return SReflect.getInnerClassName(getClass())+"("+rid+", loaded classes="+num;
// }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy