opened
astefanutti
username_0
…I Weld
[PAXCDI-216] ClassNotFoundException for Weld client proxies in PAX CD…
issue
created
hwellmann
username_1
Can you please isolate the issue and provide a self-contained test (without Camel or other external dependencies) that demonstrates it?
comment
created
astefanutti
username_0
Yes, I'll try to write a minimal test.

The issue is very well described in http://blog.osgi.org/2008/08/classy-solutions-to-tricky-proxies.html. The proposed solution is only applicable to JDK proxies and as Weld (and other CDI implementations) use subclass proxying, not JDK proxies, this make things more complicated.

Indeed, we can use a delegating class loader that have access to the proxy types closure (Weld mixin classes, parent classes, ...) but that doesn't work for classes being proxied that either inherit from parent class with default visibility modifier or have proxied methods whose return type has the default visibility modifier. This is actually the issue you faced at https://github.com/ops4j/org.ops4j.pax.cdi/commit/5c1c8e2ed5eb774f52769cd35dbdeb66ccd9b3ba#diff-17ac1db282a6026cc8e7c0f9ce20226fR40. In that case, the only solution, apparently is to use the same defining class loader for the proxy class as that of the bean type, otherwise `IllegalAccessError` is thrown. This what caused the `org.ops4j.pax.cdi.test.SecurityTest` test to fail as DeltaSpike security extension is having a method whose return type is _package-private_.

The former solution, that is using a delegating class loader that have access to the proxy types closure, was previously approximated by using a class loader with a delegating bundle containing the CDI extensions and Weld bundles: https://github.com/ops4j/org.ops4j.pax.cdi/blob/85ab25d9d4a6758f8beb96992ef1f56635cc687f/pax-cdi-weld/src/main/java/org/ops4j/pax/cdi/weld/impl/WeldCdiContainer.java#L82-L83. However, that does not cover the use case of proxying a class whose parent class is in another bundle as described in http://blog.osgi.org/2008/08/classy-solutions-to-tricky-proxies.html (which happen to be the case of a lot of Camel components, hence the Camel test cases). Ideally, that solution should enable to avoid using a `WeavingHook` to add dynamic imports on Weld mixin classes.

So the proposed PR is a solution to that general problem, mixing both approach using an heuristic to determine what class loader to use. It could be refined by iterating over all the proxiable methods of the bean types closure to identify methods whose return type has the default visibility modifier. But that'd be costly and still would not resolve the case where the bean type being proxied inherit from a class in a different bundle and that has methods with _package-private_ return types.

Let me know what you think.
comment