Problems using Peaberry and Wicket

5 views
Skip to first unread message

Roman Roelofsen

unread,
May 29, 2008, 5:14:25 PM5/29/08
to Guice and OSGi

It seems that the Wicket-Guice module and Peaberry don't work together
very well. When I try to _access_ an OSGi service injected into a
Wicket page I get this exception:

java.lang.NoClassDefFoundError: [Lcom/google/inject/cglib/proxy/
Callback;
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2395)
at java.lang.Class.getDeclaredMethod(Class.java:1907)
at
com.google.inject.cglib.proxy.Enhancer.getCallbacksSetter(Enhancer.java:
630)
at
com.google.inject.cglib.proxy.Enhancer.setCallbacksHelper(Enhancer.java:
618)
at
com.google.inject.cglib.proxy.Enhancer.setThreadCallbacks(Enhancer.java:
612)
at
com.google.inject.cglib.proxy.Enhancer.createUsingReflection(Enhancer.java:
634)
at
com.google.inject.cglib.proxy.Enhancer.firstInstance(Enhancer.java:
538)
at
com.google.inject.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:
225)
at
com.google.inject.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at com.google.inject.cglib.proxy.Enhancer.create(Enhancer.java:
285)
at
org.ops4j.peaberry.internal.ServiceProxyFactory.getUnaryServiceProxy(ServiceProxyFactory.java:
70)
at org.ops4j.peaberry.internal.ServiceProviderFactory
$1.get(ServiceProviderFactory.java:115)
at
com.google.inject.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:
44)
at com.google.inject.InjectorImpl$11$1.call(InjectorImpl.java:
1123)
at
com.google.inject.InjectorImpl.callInContext(InjectorImpl.java:1175)
at com.google.inject.InjectorImpl$11.get(InjectorImpl.java:
1117)
at
com.google.inject.InjectorImpl.getInstance(InjectorImpl.java:1152)
at
org.apache.wicket.guice.GuiceProxyTargetLocator.locateProxyTarget(GuiceProxyTargetLocator.java:
67)
at org.apache.wicket.proxy.LazyInitProxyFactory
$JdkHandler.invoke(LazyInitProxyFactory.java:412)
at org.apache.wicket.proxy.$Proxy14.list(Unknown Source)
at eed.example.gui_wicket.HelloWorld$1.onClick(HelloWorld.java:
44)


Wicket-Guice puts a proxy "LazyInitProxyFactory" in front of
Peaberry's "Enhancer" object. Both libraries use cglib for this but
Peaberry uses Guice's "package name-changed" version
com.google.inject.cglib.proxy.Callback whereas Wicket-Guice uses the
normal cglib version. I have not tested it yet but maybe this causes
the problem.

I will try to change the method
ServiceProxyFactory.getUnaryServiceProxy to use plain Java Proxy to
test this. Any tips in advance? Other ideas what can cause this
problem?

Stuart McCulloch

unread,
May 29, 2008, 8:56:33 PM5/29/08
to guice...@googlegroups.com
2008/5/30 Roman Roelofsen <roman.r...@googlemail.com>:

it sounds more like an OSGi classloading issue - this happens
when you try to create a proxy that needs access to both the
client types and the internal guice types.

peaberry patches guice to add support for classloading hooks
and uses this to provide a custom classloader for proxies, etc.
that bridges between the two class spaces (where necessary)

this avoids client bundles from having to import guice internals,
but means threads need to call "nonDelegatingContainer()" to
set this hook - this is automatically done in the OSGi module
provided by peaberry, so the thread that creates the injector
should have this (and any threads it then forks)

but if you have other threads that were started independently
then you'll need to invoke "nonDelegatingContainer()" to setup
the classloader hook, and this should fix the above error

if it doesn't then please open an issue with a simple testcase
and/or the steps needed to recreate the NCDF exception.
 
I will try to change the method
ServiceProxyFactory.getUnaryServiceProxy to use plain Java Proxy to
test this. Any tips in advance? Other ideas what can cause this
problem?

changing it to use a plain Java proxy probably won't solve this
issue, as it probably still needs visibility of both class spaces.

try calling "nonDelegatingContainer()" before it creates the proxy,
as a quick test - ideally though, you wouldn't call this all the time,
just once in the appropriate thread...





--
Cheers, Stuart

Roman Roelofsen

unread,
May 31, 2008, 4:38:03 AM5/31/08
to Guice and OSGi
On May 30, 2:56 am, "Stuart McCulloch" <mccu...@gmail.com> wrote:
> 2008/5/30 Roman Roelofsen <roman.roelof...@googlemail.com>:
Thanks for the explanation.

You were right, it was yet another classloading problem in OSGi ;-)
But I wonder, since we patch Guice anyway, wouldn't it make more sense
to set the NonDelegatingClassLoaderHook as a default in GuiceCodeGen
instead of the DEFAULT_CLASSLOADER_HOOK?


Stuart McCulloch

unread,
May 31, 2008, 10:00:37 AM5/31/08
to guice...@googlegroups.com
2008/5/31 Roman Roelofsen <roman.r...@googlemail.com>:
You were right, it was yet another classloading problem in OSGi ;-)
But I wonder, since we patch Guice anyway, wouldn't it make more sense
to set the NonDelegatingClassLoaderHook as a default in GuiceCodeGen
instead of the DEFAULT_CLASSLOADER_HOOK?

possibly - at the moment the patch maintains the existing behaviour
(not much hook overhead) while allowing use of Guice inside OSGi
by providing this classloader hook to link the various class spaces.

I could certainly amend the patch to use our custom loader by default,
but I doubt this version would make it into the actual Guice codebase
(whereas hopefully the current patch would be accepted)

let me think about this - it mostly affects threads that were started
separately from the thread that created the injector, as that thread
and any child threads should inherit the correct hook.





--
Cheers, Stuart
Reply all
Reply to author
Forward
0 new messages