Applied patch (FELIX-95).
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@423869 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
index f87aaa7..70ba2af 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/Activator.java
@@ -80,7 +80,7 @@
*/
public void addComponentFactory(Element cm) {
// Create the factory :
- ComponentManagerFactory factory = new ComponentManagerFactory(this, cm);
+ ComponentManagerFactory factory = new ComponentManagerFactory(m_bundleContext, cm);
// If the factory array is not empty add the new factory at the end
if (m_factories.length != 0) {
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
index d979220..3a3feae 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManager.java
@@ -132,7 +132,6 @@
// It is not an internal handler, try to load it
try {
Class c = m_context.getBundle().loadClass(cm.getNamespaces()[i]);
- //Class c = Class.forName(cm.getNamespaces()[i]);
Handler h = (Handler) c.newInstance();
h.configure(this, cm);
} catch (ClassNotFoundException e) {
@@ -241,8 +240,8 @@
*/
private void load() {
try {
- m_clazz = m_factory.getBundleContext().getBundle().loadClass(m_metadata.getClassName());
- } catch (Exception e) {
+ m_clazz = m_factory.loadClass(m_metadata.getClassName());
+ } catch (ClassNotFoundException e) {
Activator.getLogger().log(Level.SEVERE, "[" + m_metadata.getClassName() + "] Class not found during the loading phase : " + e.getMessage());
return;
}
diff --git a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java
index 646db1d..bf8eade 100644
--- a/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java
+++ b/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/ComponentManagerFactory.java
@@ -16,6 +16,10 @@
*/
package org.apache.felix.ipojo;
+import java.io.IOException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
import java.util.logging.Level;
import org.apache.felix.ipojo.metadata.Element;
@@ -38,8 +42,77 @@
*/
private BundleContext m_bundleContext = null;
+ /**
+ * Component class.
+ */
+ private byte[] m_clazz = null;
+
+ /**
+ * Component Class Name.
+ */
+ private String m_componentClassName = null;
+
+ /**
+ * Classloader to delegate loading.
+ */
+ private FactoryClassloader m_classLoader = null;
+
//End field
+ /**
+ * FactoryClassloader.
+ */
+ private class FactoryClassloader extends ClassLoader {
+
+ /**
+ * load the class.
+ * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+ * @param name : the name of the class
+ * @param resolve : should be the class resolve now ?
+ * @return : the loaded class
+ * @throws ClassNotFoundException : the class to load is not found
+ */
+ protected synchronized Class loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
+ return m_bundleContext.getBundle().loadClass(name);
+ }
+
+
+ /**
+ * Return the URL of the asked ressource.
+ * @param arg : the name of the resource to find.
+ * @return the URL of the resource.
+ * @see java.lang.ClassLoader#getResource(java.lang.String)
+ */
+ public URL getResource(String arg) {
+ return m_bundleContext.getBundle().getResource(arg);
+ }
+
+ /**
+ * .
+ * @param arg : resource to find
+ * @return : the enumeration found
+ * @throws IOException : if the lookup failed.
+ * @see java.lang.ClassLoader#getResources(java.lang.String)
+ */
+ public Enumeration getRessources(String arg) throws IOException {
+ return m_bundleContext.getBundle().getResources(arg);
+ }
+
+ /**
+ * The defineClass method.
+ * @param name : name of the class
+ * @param b : the byte array of the class
+ * @param domain : the protection domain
+ * @return : the defined class.
+ * @throws Exception : if a problem is detected during the loading
+ */
+ public Class defineClass(String name, byte[] b,
+ ProtectionDomain domain) throws Exception {
+ return super.defineClass(name, b, 0, b.length, domain);
+ }
+ }
+
// Field accessors
/**
@@ -93,16 +166,6 @@
// End field accessors
/**
- * Constructor of a ComponentManagerFactory from a component metadata.
- * This contructor is use when the iPOJO Activator is used.
- * @param cm : Component Metadata for the component factory
- */
- protected ComponentManagerFactory(Activator activator, Element cm) {
- m_bundleContext = activator.getBundleContext();
- createComponentManager(cm);
- }
-
- /**
* Create a component manager factory and create a component manager with the given medatada.
* @param bc : bundle context
* @param cm : metadata of the component to create
@@ -110,6 +173,20 @@
public ComponentManagerFactory(BundleContext bc, Element cm) {
m_bundleContext = bc;
createComponentManager(cm);
+ m_componentClassName = cm.getAttribute("className");
+ }
+
+ /**
+ * Create a component manager factory and create a component manager with the given medatada.
+ * @param bc : bundle context
+ * @param clazz : the component class
+ * @param cm : metadata of the component
+ */
+ public ComponentManagerFactory(BundleContext bc, byte[] clazz, Element cm) {
+ m_bundleContext = bc;
+ m_clazz = clazz;
+ m_componentClassName = cm.getAttribute("className");
+ createComponentManager(cm);
}
/**
@@ -156,4 +233,38 @@
}
}
+ /**
+ * Load a class.
+ * @param className : name of the class to load
+ * @return the resulting Class object
+ * @throws ClassNotFoundException : happen when the class is not found
+ */
+ public Class loadClass(String className) throws ClassNotFoundException {
+ Activator.getLogger().log(Level.INFO, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] In load for : " + className);
+ if (m_clazz != null && className.equals(m_componentClassName)) {
+ if (m_classLoader == null) {
+ Activator.getLogger().log(Level.INFO, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] Create the FactoryClassLoader for : " + className);
+ m_classLoader = new FactoryClassloader();
+ }
+ try {
+ Class c = m_classLoader.defineClass(m_componentClassName, m_clazz, null);
+ Activator.getLogger().log(Level.INFO, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] Return " + c + " for " + className);
+ return c;
+ } catch (Exception e) {
+ Activator.getLogger().log(Level.SEVERE, "[Bundle " + m_bundleContext.getBundle().getBundleId() + "] Cannot define the class : " + className);
+ return null;
+ }
+ }
+ return m_bundleContext.getBundle().loadClass(className);
+ }
+
+ /**
+ * Return the URL of a resource.
+ * @param resName : resource name
+ * @return the URL of the resource
+ */
+ public URL getResource(String resName) {
+ return m_bundleContext.getBundle().getResource(resName);
+ }
+
}