Uploaded image for project: 'Wicket'
  1. Wicket
  2. WICKET-6607

NoSuchMethodError when using Spring-Beans with constructor injection in an AjaxLink#onClick

    XMLWordPrintableJSON

Details

    Description

      We are currently building a SpringBoot application with Wicket 8.1.0 and using Constructor injection in the service layer. If a service that follows this approach is injected into a Wicket component, the already known issue, reported on stackoverflow, occurs:

      java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:931) ~[cglib-3.2.6.jar:na] at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:631) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:329) ~[cglib-3.2.6.jar:na] at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:93) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:91) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54) ~[cglib-3.2.6.jar:na] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_131] at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:116) ~[cglib-3.2.6.jar:na] at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:291) ~[cglib-3.2.6.jar:na] at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480) ~[cglib-3.2.6.jar:na] at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305) ~[cglib-3.2.6.jar:na] at org.apache.wicket.proxy.LazyInitProxyFactory.createProxy(LazyInitProxyFactory.java:192) ~[wicket-ioc-8.1.0.jar:8.1.0] at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:166) ~[wicket-spring-8.1.0.jar:8.1.0] at org.apache.wicket.injection.Injector.inject(Injector.java:111) ~[wicket-ioc-8.1.0.jar:8.1.0]
      

      The workaround for that issue is to use Objenesis.

      But now another error occurs as soon as the spring-bean is used in a listener, e.g. in an onClick method of an AjaxLink.

      Exception in thread "Wicket-AsyncPageStore-PageSavingThread" java.lang.NoSuchMethodError: de.korten.wicket.examples.helloworld.FooBarService.writeReplace()Ljava/lang/Object;
       at de.korten.wicket.examples.helloworld.Wicket_Proxy_FooBarService$$EnhancerByCGLIB$$5b8fb826.writeReplace(<generated>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at java.io.ObjectStreamClass.invokeWriteReplace(ObjectStreamClass.java:1118)
       at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1136)
       at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
       at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
       at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
       at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
       at org.apache.wicket.serialize.java.JavaSerializer$SerializationCheckerObjectOutputStream.writeObjectOverride(JavaSerializer.java:368)
       at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
       at org.apache.wicket.serialize.java.JavaSerializer.serialize(JavaSerializer.java:82)
       at org.apache.wicket.pageStore.AbstractPageStore.serializePage(AbstractPageStore.java:133)
       at org.apache.wicket.pageStore.DefaultPageStore.createSerializedPage(DefaultPageStore.java:281)
       at org.apache.wicket.pageStore.DefaultPageStore.storePage(DefaultPageStore.java:61)
       at org.apache.wicket.pageStore.AsynchronousPageStore$PageSavingRunnable.run(AsynchronousPageStore.java:225)
       at java.lang.Thread.run(Thread.java:748)
      

      The Spring-Bean itself can be resolved in the onClick, but not its dependencies, these are then null.

      I have attached a simple example project to reproduce the problem.

      The attached application can be started with the command "gradlew bootrun". After that the HomePage can be reached under localhost:8080. This page contains a single link in whose onClick method the described Spring-Bean is used. When you click on this link, then a NullpointerException will be thrown. This depends on the point that the dependencies of the bean can no longer be resolved and are therefore null.

      Attachments

        1. wicket-di.zip
          69 kB
          Lukas Korten
        2. wicket-constructor-injection.zip
          30 kB
          Lukas Korten

        Issue Links

          Activity

            People

              svenmeier Sven Meier
              lukaskorten Lukas Korten
              Votes:
              4 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: