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

RequestScoped beans keeping property values from previous requests when using kotlin. #10290

Closed
leandrobortoli opened this issue Jun 26, 2020 · 9 comments · Fixed by #10497
Closed
Assignees
Labels
area/kotlin kind/bug Something isn't working
Milestone

Comments

@leandrobortoli
Copy link

Describe the bug
When using kotlin and injecting a RequestScoped bean, on each new request a new bean instance is initialized, but for some reason, the property values from the previous request bean are kept, this seems to be an issue only with the kotlin extension, because I couldn't reproduce the issue using Java.

Expected behavior
The new request bean should not contain previous property values

Actual behavior
A new bean instance is created on each request, but the same property values from previous requests are propagated.

To Reproduce
I've created a project to reproduce the issue here: https://github.com/leandrobortoli/quarkus-issue-request-scoped

On each request, it checks if the bean property has been initialized and if not initializes it with a random value, as a result, we can see that only the first request initializes the properties and the values are propagated in the subsequent requests.

@Path("/ping")
class PingController {

    @Inject
    lateinit var requestScopedBean: RequestScopedBean

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    fun ping(): String {
        if(requestScopedBean.myProperty == null) {
            println("Setting requestScopedBean.myProperty")
            requestScopedBean.myProperty = java.util.Random().nextInt()
        }
        if(requestScopedBean.myStringProperty == null) {
            println("Setting requestScopedBean.myStringProperty")
            requestScopedBean.myStringProperty = StringUtils.randomString()
        }
        println("requestScopedBean ref: $requestScopedBean")
        println("requestScopedBean.myProperty: ${requestScopedBean.myProperty}")
        println("requestScopedBean.myStringProperty: ${requestScopedBean.myStringProperty}")
        return "pong"
    }
}
@RequestScoped
open class RequestScopedBean {

    var myProperty: Int? = null
    var myStringProperty: String? = null

    init {
        println("Initializing RequestScopedBean")
    }
}

Screenshots
OUTPUT WITH 3 CONSECUTIVE REQUESTS:
image

Environment (please complete the following information):

  • Microsoft Windows [Version 10.0.18362.900]
    -Java version "1.8.0_162"
    Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
    Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
  • Quarkus version 1.5.2.Final
  • Gradle 6.4.1
@leandrobortoli leandrobortoli added the kind/bug Something isn't working label Jun 26, 2020
@gsmet
Copy link
Member

gsmet commented Jun 26, 2020

/cc @mkouba @evanchooly

@mkouba
Copy link
Contributor

mkouba commented Jun 26, 2020

It's very likely that you get/set the values from the client proxy and not the real bean instance. I'm no kotlin expert but I thought that kotlin generates getters/setters for properties automatically, i.e. if(requestScopedBean.myProperty == null) is translated to something like if(requestScopedBean.getMyProperty() == null). @geoand Any idea?

@geoand
Copy link
Contributor

geoand commented Jun 26, 2020

Sounds reasonable @mkouba although I don't know exactly why that would be happening - we would need to look at the bytecode.

@evanchooly do you plan to look at this or should I check it out when I have some time?

@evanchooly
Copy link
Member

I can dig in to it but wouldn't be bothered if you got there first. I have a bit of a back log but I'm about to take a big one off that list.

@geoand
Copy link
Contributor

geoand commented Jun 26, 2020

I'll see if I can squeze it in sometime next week. I'll update here in any case.

@leandrobortoli
Copy link
Author

When doing some more tests, I validated that when injecting a bean interface instead of the implementation, the problem does not seem to occur.

@youngplugins
Copy link

Hi there. Im new here, and use your wonderfull software.

I can verify the same problem also happens with @SessionScoped.

@leandrobortoli , may I ask, how do you inject a bean interface, instead of implementation?

@geoand geoand self-assigned this Jul 6, 2020
@geoand
Copy link
Contributor

geoand commented Jul 6, 2020

I am pretty sure I can come up with a fix for this one. Will let you know by tomorrow.

@mkouba this essentially comes down to us removing the final modifier from methods (currently we just skip these methods in Arc). We already do this for interceptors, so I propose we do it for the proxy target. WDYT?

geoand added a commit to geoand/quarkus that referenced this issue Jul 6, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
@geoand
Copy link
Contributor

geoand commented Jul 6, 2020

#10497 takes care of the issue (I tested it with the reproducer and it now works as expected)

geoand added a commit to geoand/quarkus that referenced this issue Jul 6, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
geoand added a commit to geoand/quarkus that referenced this issue Jul 7, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
geoand added a commit to geoand/quarkus that referenced this issue Jul 8, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
geoand added a commit to geoand/quarkus that referenced this issue Jul 8, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
geoand added a commit to geoand/quarkus that referenced this issue Jul 8, 2020
This is done in the same manner that is already present for
interceptors and is very useful for Kotlin code where methods
are final by default

Fixes: quarkusio#10290
geoand added a commit that referenced this issue Jul 8, 2020
Allow Arc to deal with final methods of beans that need to be proxied
@gsmet gsmet added this to the 1.7.0 - master milestone Jul 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kotlin kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants