Merge branch 'cached-combined-classloader' of https://github.com/3cky/karaf-cellar
diff --git a/core/src/main/java/org/apache/karaf/cellar/core/utils/CombinedClassLoader.java b/core/src/main/java/org/apache/karaf/cellar/core/utils/CombinedClassLoader.java
index f31e479..13a2c2f 100644
--- a/core/src/main/java/org/apache/karaf/cellar/core/utils/CombinedClassLoader.java
+++ b/core/src/main/java/org/apache/karaf/cellar/core/utils/CombinedClassLoader.java
@@ -29,12 +29,16 @@
private final ConcurrentMap<Long, Bundle> bundles = new ConcurrentHashMap<Long, Bundle>();
+ private final ConcurrentMap<String, Bundle> classBundleCache = new ConcurrentHashMap<String, Bundle>();
+
public void init() {
bundles.clear();
+ classBundleCache.clear();
}
public void destroy() {
bundles.clear();
+ classBundleCache.clear();
}
public void addBundle(Bundle bundle) {
@@ -43,23 +47,48 @@
public void removeBundle(Bundle bundle) {
bundles.remove(bundle.getBundleId());
+ // Remove all bundle classes from class name to bundle cache
+ for (Map.Entry<String, Bundle> entry : classBundleCache.entrySet()) {
+ if (entry.getValue().getBundleId() == bundle.getBundleId()) {
+ classBundleCache.remove(entry.getKey());
+ }
+ }
}
@Override
- public Class findClass(String name) throws ClassNotFoundException {
+ public Class<?> findClass(String name) throws ClassNotFoundException {
+ // Trying to find class using class name to bundle cache first
+ Bundle bundle = classBundleCache.get(name);
+ if (bundle != null) {
+ Class<?> clazz = loadClassFromBundle(name, bundle);
+ if (clazz != null) {
+ return clazz;
+ }
+ // Remove stale cache entry
+ classBundleCache.remove(name);
+ }
+ // Class not found using class name to bundle cache, check all registered bundles
for (Map.Entry<Long, Bundle> entry : bundles.entrySet()) {
- try {
- Bundle bundle = entry.getValue();
- if (bundle.getState() == Bundle.ACTIVE || bundle.getState() == Bundle.STARTING) {
- return bundle.loadClass(name);
- }
- } catch (ClassNotFoundException cnfe) {
- // Try next
+ bundle = entry.getValue();
+ Class<?> clazz = loadClassFromBundle(name, bundle);
+ if (clazz != null) {
+ classBundleCache.put(name, bundle);
+ return clazz;
}
}
throw new ClassNotFoundException(name);
}
+ private Class<?> loadClassFromBundle(String name, Bundle bundle) {
+ try {
+ if (bundle.getState() == Bundle.ACTIVE || bundle.getState() == Bundle.STARTING) {
+ return bundle.loadClass(name);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ }
+ return null;
+ }
+
@Override
public URL getResource(String name) {
for (Map.Entry<Long, Bundle> entry : bundles.entrySet()) {