Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bean could not be injected #220

Open
Evodam opened this issue Nov 12, 2024 · 6 comments
Open

Bean could not be injected #220

Evodam opened this issue Nov 12, 2024 · 6 comments

Comments

@Evodam
Copy link

Evodam commented Nov 12, 2024

This is my page:

@WicketHomePage
class LoginPage : EaznBaseLayoutPage(), IUnauthenticatedAccessablePage {

    @SpringBean
    private lateinit var loginAction: LoginAction

    override fun onInitialize() {
        super.onInitialize()

        val btnSubmit = object : Button("submit") {
            override fun onSubmit() {
                try {
                    loginAction.execute(values.getString(KEY_USERNAME), values.getString(KEY_PASSWORD))

                    continueToOriginalDestination()

                    HomePage.PageInfo().gotoPage()
                } catch (e: LoginAction.UserInvalid) {
                ...
                }

            }
        }
        form.add(btnSubmit)
    }

}

This is the class LoginAction:

@Component
open class LoginAction {

    @Autowired
    lateinit var authenticator: Authenticator

    fun execute(login: String, password: String) {
   }
}

When I inject authenticator to page itself it is present. But when I inject it to the LoginAction-class is stays null. What am I doing wrong?
I also tried annotating it with @jakarta.annotation.Resource but this doesn't work either.

I am using wicket-spring-boot-starter 4.0.0.

@Evodam
Copy link
Author

Evodam commented Nov 12, 2024

I tried to debug it. The values go missing in AnnotProxyFieldValueFactory, Line 164 when it is wrapped in a proxy:

	if (wrapInProxies) {
          target = LazyInitProxyFactory.createProxy(field.getType(), locator);
	}

As far as I understand this is done to ensure page stays serializable. But how am I supposed to inject beans that have other beans?

@MarcGiffing
Copy link
Owner

Does it work without the Starter? I haven't used Kotlin yet. Can you provide an example project?

@Evodam
Copy link
Author

Evodam commented Nov 14, 2024

I did not try to integrate spring without the starter because I don't really know how I would need to configure spring to work with wicket.

I setup a small project: https://github.com/Evodam/wicket-spring-showcase

Just run the main method in WicketApplication.kt and open localhost/8080.

In console this error occurs:

kotlin.UninitializedPropertyAccessException: lateinit property myRepository has not been initialized
	at de.evodam.wicketspringshowcase.MyService.getMyRepository(MyService.kt:10) ~[main/:na]
	at de.evodam.wicketspringshowcase.HomePage.onInitialize(HomePage.kt:17) ~[main/:na]
	at org.apache.wicket.Component.fireInitialize(Component.java:883) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.MarkupContainer.internalInitialize(MarkupContainer.java:1050) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.Page.isPageStateless(Page.java:460) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.getPageInfo(AbstractBookmarkableMapper.java:473) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.mapHandler(AbstractBookmarkableMapper.java:420) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.core.request.mapper.MountedMapper.mapHandler(MountedMapper.java:155) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.mapper.CompoundRequestMapper.mapHandler(CompoundRequestMapper.java:210) ~[wicket-request-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.cycle.RequestCycle.mapUrlFor(RequestCycle.java:465) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.handler.render.WebPageRenderer.respond(WebPageRenderer.java:233) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.core.request.handler.RenderPageRequestHandler.respond(RenderPageRequestHandler.java:202) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:910) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.RequestHandlerExecutor.execute(RequestHandlerExecutor.java:63) ~[wicket-request-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:294) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:255) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:277) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:208) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:307) ~[wicket-core-10.0.0.jar:10.0.0]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.5.jar:6.1.5]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.5.jar:6.1.5]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.5.jar:6.1.5]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.5.jar:6.1.5]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.5.jar:6.1.5]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.5.jar:6.1.5]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
	at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

@MarcGiffing
Copy link
Owner

Two Problems:

  1. Missing Constructor in MyService. ByteBuddy requires it.
  2. Add src/main/kotlin to resources to support html files. (Which are not located in the resource folder)
// MyService
package de.evodam.wicketspringshowcase

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component

@Component
open class MyService {

    @Autowired
    lateinit var myRepository: MyRepository

    // ByteBuddy needs an empty constructor
    constructor(
    ) {
    }
}
// WicketApplication
package de.evodam.wicketspringshowcase

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder


fun main() {
    SpringApplicationBuilder()
        .sources(WicketApplication::class.java)
        .run()
}

@SpringBootApplication
open class WicketApplication() {

}
// build.gradle.kts

// add
sourceSets {
    main {
        java {
            srcDir("src/main/kotlin")
        }
// Is needed to detect the html files
        resources {
            srcDir("src/main/kotlin")
        }
    }

    test {
        java {
            srcDir("src/main/kotlin")
        }
        resources {
            srcDir("src/main/kotlin")
        }
    }
}

@Evodam
Copy link
Author

Evodam commented Nov 20, 2024

@MarcGiffing
I added empty constructors to service and repository but this error still occurs.

@Evodam
Copy link
Author

Evodam commented Nov 22, 2024

@MarcGiffing
I also added the 'same' classes in java:

public class JavaHomePage extends WebPage {

    @SpringBean
    private MyJavaRepository myJavaRepository;

    @SpringBean
    private MyJavaService myJavaService;

    @Override
    protected void onInitialize() {
        super.onInitialize();

        System.out.println(myJavaRepository);

        System.out.println(myJavaService);
        System.out.println(myJavaService.myJavaRepository);
    }
}

And this is written in console:

org.apache.wicket.proxy.bytebuddy.ByteBuddyInterceptor@457f9677
org.apache.wicket.proxy.bytebuddy.ByteBuddyInterceptor@4715320f
null

I fiddled a little bit around and think I found something that seems to work although it still looks very verbose and I'm not quite happy with it:

@Component
public class MyJavaService {

    @SpringBean
    public MyJavaRepository myJavaRepository;

    public MyJavaService() {
        Injector.get().inject(this);
    }

    @Autowired
    public MyJavaService(MyJavaRepository myJavaRepository) {
        this.myJavaRepository = myJavaRepository;
    }
}

Everything is pushed to my github repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants