Hello, I'm using a JAR compiled from Kotlin code i...
# spring
a
Hello, I'm using a JAR compiled from Kotlin code in a Java Spring Boot application. The class that I want to use as bean contains several fields that are marked private, some of which are vals. The vals have been initialize at the declaration level, but when I inspect the returned bean (@RequestScope), the vals are null. Is there something special that I have to do on the Spring Boot side of things to get Spring to initialize those fields? Thanks!
j
If it’s request-scoped, what you’re looking at is most probably not an actual instance of the bean. It’s a dynamically generated CGLIB proxy, which extends your class and delegate to an actual instance. Evaluate an expression on using your bean, and you should get the result you expect.
a
By "Evaluate an expression on using your bean, and you should get the result you expect." do you mean doing something like
MyObject result = new MyObject();
return result;
Something like that?
Currently, in the @Bean definition, I simply have
return new MyObject()
j
No. I mean that instead of inspecting the value of your bean in the debugger, evaluate an expression using your bean, like
myBean.foo
. Or just
println(myBean.foo)
.
a
Copy code
ic. What I also found out is that although I'm getting different instances of the bean, I'm getting the same instance of the underlying object.
So if MyObject has a HashMap() and I add object to that, when I request another MyObject the HashMap contains the previous bean's objects.
So what this is telling me is that Beans should not hold state. Would that be a correct statement? I'm not really a Spring Boot developer...
...just trying to instrument a Spring Boot app with my library
j
Your bean is request-scoped. It means that in a given request you have one instance of the actual bean instance everywhere (and thus one HashMap), and in another request, you have another bean instance (and thus another HashMap).
a
That's what I expected....
But that doesn't seem to be the case.
What constitutes a "request"?
Is it attached to a session?
j
I’d be happy to have a look if you provided a link to a minimal project reproducing the issue.
a
BTW, this app has no notion of a session
j
request = HTTP request.
a
Right, that's my understanding too.
Can I drop a zip file here?
I downloaded this project off the web. I added a MockTokenManager Kotlin class that mimics the implementation of the "real" one in our organization. I tested it and the behaviour is the same as what I explained above.
The README.md has instructions on how to run it.
Thanks
Hold...off, I have to fix something that broke when I removed my lib's reference....
Give me a sec
Here's the working project...
j
Sorry, but this is very gfar from being minimal, and it doesn’t compile and run. Here’s a complete example showing a request-scope bean working: you send a request to /demo?value=foo, and it returns “null - foo” every time, showing that a new HashMap is created for each request.
Copy code
package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.stereotype.Service
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.context.annotation.RequestScope

@SpringBootApplication
class DemoRequestScopeApplication

fun main(args: Array<String>) {
    runApplication<DemoRequestScopeApplication>(*args)
}

@RestController
@RequestMapping("/demo")
class DemoController(private val demoService: DemoService, private val otherService: OtherService) {
    @GetMapping
    fun demo(@RequestParam value: String): String? {
        val initialValue = otherService.demo()
        demoService.storeValue(value)
        val newValue = otherService.demo()
        return "$initialValue - $newValue"
    }
}

@Service
class OtherService(private val demoService: DemoService) {
    fun demo(): String? = demoService.extractValue()
}

@Service
@RequestScope
class DemoService {
    private val map = mutableMapOf<String, String>()

    fun storeValue(value: String) {
        map["value"] = value
    }

    fun extractValue(): String? = map["value"]
}
a
Thanks. Sorry it didn't compile. Not sure why.
I move the project to another folder and was able to compile it. In any case, thanks for the help. Let me check out your example.