Skip to content

Commit

Permalink
Fixing Problems with ClassCast Exception - TRUNK-4053(cherry picked f…
Browse files Browse the repository at this point in the history
…rom commit 1850c17)
  • Loading branch information
dkayiwa committed Sep 2, 2013
1 parent 07e19c3 commit 5a15636
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion api/src/main/java/org/openmrs/module/ModuleClassLoader.java
Expand Up @@ -30,6 +30,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -67,6 +68,12 @@ public class ModuleClassLoader extends URLClassLoader {

private Set<String> additionalPackages = new LinkedHashSet<String>();

/**
* Holds a list of all classes for this classloader so that they can be cleaned up.
* This is also used to fix: https://tickets.openmrs.org/browse/TRUNK-4053
*/
private Map<String, Class<?>> loadedClasses = new HashMap<String, Class<?>>();

/**
* @param module Module
* @param urls resources "managed" by this class loader
Expand Down Expand Up @@ -387,6 +394,8 @@ public void dispose() {
requiredModules = null;
awareOfModules = null;
//resourceLoader = null;

loadedClasses.clear();
}

/**
Expand All @@ -405,6 +414,19 @@ public void setProbeParentLoaderLast(final boolean value) {
@Override
protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
Class<?> result = null;

//if this class was already loaded by some other class loader, do not load it again.
Collection<ModuleClassLoader> classLoaders = ModuleFactory.getModuleClassLoaders();
for (ModuleClassLoader classLoader : classLoaders) {
if (classLoader == this)
continue;

result = classLoader.getClassIfLoaded(name);
if (result != null) {
return result;
}
}

if (probeParentLoaderLast) {
try {
result = loadClass(name, resolve, this, null);
Expand All @@ -430,8 +452,14 @@ protected Class<?> loadClass(final String name, final boolean resolve) throws Cl
}
}

if (result != null)
if (result != null) {
//add only if this is its class loader
if (result.getClassLoader() == this) {
loadedClasses.put(name, result);
}

return result;
}

throw new ClassNotFoundException(name);
}
Expand Down Expand Up @@ -568,6 +596,16 @@ protected Class<?> loadClass(final String name, final boolean resolve, final Mod
return result;
}

/**
* Gets a class instance if it was already loaded by this class loader.
*
* @param name String path and name of the class to load.
* @return the class instance if it was already loaded, else null.
*/
public Class<?> getClassIfLoaded(final String name) {
return loadedClasses.get(name);
}

/**
* Checking the given class's visibility in this module
*
Expand Down

0 comments on commit 5a15636

Please sign in to comment.