ClassLoading issue involving java.lang.reflect.Proxy in OSGi
------------------------------------------------------------
Key: FELIX-2985
URL: https://issues.apache.org/jira/browse/FELIX-2985
Project: Felix
Issue Type: Bug
Components: Framework
Affects Versions: framework-3.0.8
Reporter: Sahoo
I am filing this bug after it was determined in the users forum
(http://markmail.org/thread/k33oiw3iazfdohj7) that this is a bug that we should
track. If there already exists a similar issue, we should merge them into one.
The fix may not necessarily be in our domain though.
JVM requires us to to import more classes than required to define a Proxy
class. A simple scenario is shown below:
module 1:
package p1;
public interface A1 extends javax.sql.PooledConnection {
}
Export-Package: p1
Import-Package: javax.sql
module 2:
package p2;
public interface A2 extends javax.naming.Context, p1.A1 {
}
Export-Package: p2
Import-Package: javax.naming, p1
module 3:
Bundle-Activator: p3.Activator
Import-Package: p2, org.osgi.framework
public class Activator implements BundleActivator {
public void start(BundleContext ctx) throws Exception {
for (ClassLoader cl : new ClassLoader[]{getClass().getClassLoader(),
p2.A2.class.getClassLoader()}) {
try {
System.out.println(cl);
Object obj = Proxy.newProxyInstance(cl, new Class[]{p2.A2.class},
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {return null;}
});
System.out.println(obj);
} catch(Throwable e) {
e.printStackTrace();
}
} // for
}
public void stop(BundleContext ctx) throws Exception {}
}
It fails like this:
3.0
java.lang.NoClassDefFoundError: javax.naming.Name not found by m3 [3]
at $Proxy0.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:588)
at p3.Activator.start(Activator.java:11)
at
org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:633)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:1822)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1739)
at
org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1143)
at
org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:264)
at java.lang.Thread.run(Thread.java:619)
2.0
java.lang.NoClassDefFoundError: javax.sql.StatementEventListener not
found by m2 [2]
at $Proxy1.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:588)
at p3.Activator.start(Activator.java:11)
at
org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:633)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:1822)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1739)
at
org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1143)
at
org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:264)
at java.lang.Thread.run(Thread.java:619)
It seems to me that JVM is assuming that the defining loader of the
proxy class can load every class that appear in the signature of methods
that can be invoked using the proxy class. Anybody interested to debug
can use the attached sample. Just unzip and run run.sh after editing
path to Felix.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira