Tobias Gierke created WICKET-7168:
-------------------------------------
Summary: ByteBuddy proxy crashes in constructor when proxied class
invokes a non-private member method
Key: WICKET-7168
URL: https://issues.apache.org/jira/browse/WICKET-7168
Project: Wicket
Issue Type: Bug
Components: wicket-ioc
Affects Versions: 10.7.0
Reporter: Tobias Gierke
Hi,
In our Spring context / application we have a Spring bean that looks like this:
{code:java}
public class ConditionFactory {
public ConditionFactory() {
registerDefaultHandlers();
}
// package-level visibility for unit testing
void registerDefaultHandlers() {
....
}{code}
that code used to work flawlessly until we upgraded from Wicket 9 on JDK 21 to
Wicket 10.0.7 on JDK 25 (so either one of those changes may be the culprit).
The exception we're now getting when Wicket is trying to instantiate a proxy
for this class is this:
{code:java}
Caused by: org.apache.wicket.WicketRuntimeException:
java.lang.reflect.InvocationTargetException
at
org.apache.wicket.proxy.bytebuddy.ByteBuddyProxyFactory.createProxy(ByteBuddyProxyFactory.java:91)
at
org.apache.wicket.proxy.LazyInitProxyFactory.createProxy(LazyInitProxyFactory.java:133)
at
org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:166)
at org.apache.wicket.injection.Injector.inject(Injector.java:111)
at
org.apache.wicket.spring.injection.annot.SpringComponentInjector.inject(SpringComponentInjector.java:124)
at
org.apache.wicket.spring.injection.annot.SpringComponentInjector.onInstantiation(SpringComponentInjector.java:130)
at
org.apache.wicket.application.ComponentInstantiationListenerCollection$1.notify(ComponentInstantiationListenerCollection.java:38)
at
org.apache.wicket.application.ComponentInstantiationListenerCollection$1.notify(ComponentInstantiationListenerCollection.java:34)
at
org.apache.wicket.util.listener.ListenerCollection.notify(ListenerCollection.java:81)
at
org.apache.wicket.application.ComponentInstantiationListenerCollection.onInstantiation(ComponentInstantiationListenerCollection.java:33)
at org.apache.wicket.Component.<init>(Component.java:691)
at org.apache.wicket.MarkupContainer.<init>(MarkupContainer.java:181)
at org.apache.wicket.Page.<init>(Page.java:171)
at org.apache.wicket.Page.<init>(Page.java:135)
at org.apache.wicket.markup.html.WebPage.<init>(WebPage.java:74)
at
com.vodecc.voipmng.boundary.wicket.login.PageWithLoginScreenLayout.<init>(PageWithLoginScreenLayout.java:21)
at
com.vodecc.voipmng.boundary.wicket.login.WicketLoginPage.<init>(WicketLoginPage.java:483)
at
java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
... 51 more
Caused by: java.lang.reflect.InvocationTargetException
at
java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:72)
at
java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
at
org.apache.wicket.proxy.bytebuddy.ByteBuddyProxyFactory.createProxy(ByteBuddyProxyFactory.java:87)
... 68 more
Caused by: java.lang.NullPointerException: Cannot invoke
"org.apache.wicket.proxy.bytebuddy.ByteBuddyInterceptor.intercept(java.lang.reflect.Method,
Object[], java.util.function.Function)" because "this.interceptor" is null
at
com.vodecc.voipmng.boundary.wicket.alarming.conditions.WicketProxy_ConditionFactory.registerDefaultHandlers(Unknown
Source)
at
com.vodecc.voipmng.boundary.wicket.alarming.conditions.ConditionFactory.<init>(ConditionFactory.java:64)
at
com.vodecc.voipmng.boundary.wicket.alarming.conditions.WicketProxy_ConditionFactory.<init>(Unknown
Source)
at
java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
... 71 more {code}
It looks like the registerDefaultHandlers() method call in the super class
constructor either did not get intercepted before or did not get executed at
all.
The crash happens inside the
`org.apache.wicket.proxy.bytebuddy.ByteBuddyProxyFactory#createProxy` method:
{code:java}
public <T> T createProxy(final Class<T> type, final IProxyTargetLocator locator)
{
Class<T> proxyClass = createOrGetProxyClass(type);
T instance;
if (!hasNoArgConstructor(type))
{
instance = INSTANTIATOR.newInstance(proxyClass);
}
else
{
try
{
instance = proxyClass.getDeclaredConstructor().newInstance(); // <<<<
failing constructor invocatoin
}
catch (InstantiationException | IllegalAccessException |
InvocationTargetException | NoSuchMethodException e)
{
throw new WicketRuntimeException(e);
}
}
ByteBuddyInterceptor interceptor = new ByteBuddyInterceptor(type, locator);
((InterceptorMutator) instance).setInterceptor(interceptor); // interceptor
is being set too late
return instance;
} {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)