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

Using jvmTarget 11 and kotlin the postgreSQL usage fails #17253

Closed
MartinX3 opened this issue May 16, 2021 · 13 comments
Closed

Using jvmTarget 11 and kotlin the postgreSQL usage fails #17253

MartinX3 opened this issue May 16, 2021 · 13 comments
Labels

Comments

@MartinX3
Copy link

Describe the bug

Using the jvmTarget 11 and kotlin the query of objects from the database fails.
jvmTarget 1.8 works fine.

Expected behavior

A list of DB objects.

Actual behavior

Error

Error handling 05312b78-d264-453e-8db0-3734d4cdfd97-1, java.lang.IllegalAccessError: Update to non-static final field org.acme.resteasyjackson.model.Quark.version attempted from a different method ($$_hibernate_read_version) than the initializer method <init>

To Reproduce

quarkus-kotlin-java-11-db-error.tar.gz

Steps to reproduce the behavior:

  1. Execute container.sh
  2. ./gradlew quarkusDev
  3. POST http://localhost:8080/resteasy-jackson/quarks/ {"name": "test","description": "description"}
  4. GET http://localhost:8080/resteasy-jackson/quarks/

Configuration

# Add your application.properties here, if applicable.
quarkus:
  datasource:
    db-kind: postgresql
    jdbc:
      url: jdbc:postgresql://localhost:9999/TestDB
    password: user
    username: user
  hibernate-orm:
    database:
      generation: update
  http:
    port: 8080
  log:
    min-level: DEBUG
    console:
      enable: true
      format: "%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n"
      color: true
      darken: 1
      json:
        pretty-print: true

Screenshots

N/A

Environment (please complete the following information):

Output of uname -a or ver

Linux martind-linuxiator 5.12.3-zen1-1-zen #1 ZEN SMP PREEMPT Wed, 12 May 2021 17:54:20 +0000 x86_64 GNU/Linux

Output of java -version

openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9)
OpenJDK 64-Bit Server VM (build 11.0.11+9, mixed mode)

GraalVM version (if different from Java)

N/A

Quarkus version or git rev

1.13.4.Final

Build tool (ie. output of mvnw --version or gradlew --version)

------------------------------------------------------------
Gradle 7.0.2
------------------------------------------------------------

Build time:   2021-05-14 12:02:31 UTC
Revision:     1ef1b260d39daacbf9357f9d8594a8a743e2152e

Kotlin:       1.4.31
Groovy:       3.0.7
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          15.0.2 (Oracle Corporation 15.0.2+7)
OS:           Linux 5.12.3-zen1-1-zen amd64

Additional context

{
    "timestamp": "2021-05-16T16:54:58.683+02:00",
    "sequence": 1263,
    "loggerClassName": "org.jboss.logging.Logger",
    "loggerName": "io.quarkus.vertx.http.runtime.QuarkusErrorHandler",
    "level": "ERROR",
    "message": "HTTP Request to /resteasy-jackson/quarks/ failed, error id: 05312b78-d264-453e-8db0-3734d4cdfd97-1",
    "threadName": "executor-thread-1",
    "threadId": 73,
    "mdc": {
    },
    "ndc": "",
    "hostName": "martind-linuxiator",
    "processName": "quarkus-kotlin-java-11-db-error-dev.jar",
    "processId": 45679,
    "exception": {
        "refId": 1,
        "exceptionType": "java.lang.IllegalAccessError",
        "message": "Update to non-static final field org.acme.resteasyjackson.model.Quark.version attempted from a different method ($$_hibernate_read_version) than the initializer method <init> ",
        "frames": [
            {
                "class": "org.acme.resteasyjackson.model.Quark",
                "method": "$$_hibernate_read_version"
            },
            {
                "class": "org.acme.resteasyjackson.model.Quark",
                "method": "getVersion",
                "line": 19
            },
            {
                "class": "jdk.internal.reflect.NativeMethodAccessorImpl",
                "method": "invoke0"
            },
            {
                "class": "jdk.internal.reflect.NativeMethodAccessorImpl",
                "method": "invoke",
                "line": 62
            },
            {
                "class": "jdk.internal.reflect.DelegatingMethodAccessorImpl",
                "method": "invoke",
                "line": 43
            },
            {
                "class": "java.lang.reflect.Method",
                "method": "invoke",
                "line": 566
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.BeanPropertyWriter",
                "method": "serializeAsField",
                "line": 689
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.std.BeanSerializerBase",
                "method": "serializeFields",
                "line": 770
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.BeanSerializer",
                "method": "serialize",
                "line": 178
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.std.CollectionSerializer",
                "method": "serializeContents",
                "line": 145
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.std.CollectionSerializer",
                "method": "serialize",
                "line": 107
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.std.CollectionSerializer",
                "method": "serialize",
                "line": 25
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.DefaultSerializerProvider",
                "method": "_serialize",
                "line": 480
            },
            {
                "class": "com.fasterxml.jackson.databind.ser.DefaultSerializerProvider",
                "method": "serializeValue",
                "line": 400
            },
            {
                "class": "com.fasterxml.jackson.databind.ObjectWriter$Prefetch",
                "method": "serialize",
                "line": 1510
            },
            {
                "class": "com.fasterxml.jackson.databind.ObjectWriter",
                "method": "writeValue",
                "line": 1006
            },
            {
                "class": "org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider",
                "method": "writeTo",
                "line": 329
            },
            {
                "class": "org.jboss.resteasy.core.messagebody.AsyncBufferedMessageBodyWriter",
                "method": "asyncWriteTo",
                "line": 24
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext",
                "method": "writeTo",
                "line": 87
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext",
                "method": "asyncProceed",
                "line": 203
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext",
                "method": "getStarted",
                "line": 166
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext",
                "method": "lambda$getStarted$0",
                "line": 73
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext",
                "method": "aroundWriteTo",
                "line": 93
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext",
                "method": "getStarted",
                "line": 73
            },
            {
                "class": "org.jboss.resteasy.core.ServerResponseWriter",
                "method": "lambda$writeNomapResponse$3",
                "line": 163
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl",
                "method": "filter",
                "line": 404
            },
            {
                "class": "org.jboss.resteasy.core.ServerResponseWriter",
                "method": "executeFilters",
                "line": 252
            },
            {
                "class": "org.jboss.resteasy.core.ServerResponseWriter",
                "method": "writeNomapResponse",
                "line": 101
            },
            {
                "class": "org.jboss.resteasy.core.ServerResponseWriter",
                "method": "writeNomapResponse",
                "line": 74
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "writeResponse",
                "line": 594
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "invoke",
                "line": 524
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "lambda$invoke$4",
                "line": 261
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "lambda$preprocess$0",
                "line": 161
            },
            {
                "class": "org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext",
                "method": "filter",
                "line": 364
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "preprocess",
                "line": 164
            },
            {
                "class": "org.jboss.resteasy.core.SynchronousDispatcher",
                "method": "invoke",
                "line": 247
            },
            {
                "class": "io.quarkus.resteasy.runtime.standalone.RequestDispatcher",
                "method": "service",
                "line": 73
            },
            {
                "class": "io.quarkus.resteasy.runtime.standalone.VertxRequestHandler",
                "method": "dispatch",
                "line": 138
            },
            {
                "class": "io.quarkus.resteasy.runtime.standalone.VertxRequestHandler",
                "method": "access$000",
                "line": 41
            },
            {
                "class": "io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1",
                "method": "run",
                "line": 93
            },
            {
                "class": "io.quarkus.runtime.CleanableExecutor$CleaningRunnable",
                "method": "run",
                "line": 231
            },
            {
                "class": "java.util.concurrent.Executors$RunnableAdapter",
                "method": "call",
                "line": 515
            },
            {
                "class": "java.util.concurrent.FutureTask",
                "method": "run",
                "line": 264
            },
            {
                "class": "org.jboss.threads.EnhancedQueueExecutor$Task",
                "method": "run",
                "line": 2415
            },
            {
                "class": "org.jboss.threads.EnhancedQueueExecutor$ThreadBody",
                "method": "run",
                "line": 1452
            },
            {
                "class": "org.jboss.threads.DelegatingRunnable",
                "method": "run",
                "line": 29
            },
            {
                "class": "org.jboss.threads.ThreadLocalResettingRunnable",
                "method": "run",
                "line": 29
            },
            {
                "class": "java.lang.Thread",
                "method": "run",
                "line": 829
            },
            {
                "class": "org.jboss.threads.JBossThread",
                "method": "run",
                "line": 501
            }
        ]
    }
}
@MartinX3 MartinX3 added the kind/bug Something isn't working label May 16, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented May 16, 2021

/cc @evanchooly

@geoand
Copy link
Contributor

geoand commented May 17, 2021

@MartinX3 your code needs to use var instead of val for the field annotated with @Version, because that field cannot be final.

The thing is that on the Quarkus side, we should warn users about this (or even fail the build). @Sanne @yrodiere WDYT?

@Sanne
Copy link
Member

Sanne commented May 17, 2021

The thing is that on the Quarkus side, we should warn users about this (or even fail the build). @Sanne @yrodiere WDYT?

right, that would be nice. But is it doable? We only get to analyze the bytecode, so I guess we could check that such fields aren't marked as final and report about that - but such a message could also be confusing as it doesn't match the sources.

@geoand
Copy link
Contributor

geoand commented May 17, 2021

right, that would be nice. But is it doable? We only get to analyze the bytecode, so I guess we could check that such fields aren't marked as final and report about that - but such a message could also be confusing as it doesn't match the sources.

Yes exactly - it's easy to check in Quarkus if a field is final (and we actually do that in various other places) and produce an actionable error or warning message for users.
The other alternative (which is rather sneaky) is to remove the final modifier when we transform the entity.

In any case, what we do now (which is to not check at all) isn't optimal because it leads to this kind of runtime error message which can be surprising for users.

@Sanne
Copy link
Member

Sanne commented May 17, 2021

sure it can be done - but I'm not sure if it's super-helpful since we'll be complaining about a final modifier while the source code states val . All I'm saying is that this isn't a lot better than the error reported here, but ok we can explore this.

Needs to be done in ORM though, not in Quarkus: it's Hibernate ORM that is doing the enhancement.

@geoand
Copy link
Contributor

geoand commented May 17, 2021

I would assume (hope?) that most Kotlin users know the difference between val and var and could easily make the association with final.

Providing an actionable error message that doesn't highlight java.lang.IllegalAccessError would be very beneficial (as the existence of this issue I believe proves)

@Sanne
Copy link
Member

Sanne commented May 17, 2021

fine, I'm opening:

but I'm not going to jump on it :)

@geoand
Copy link
Contributor

geoand commented May 17, 2021

Thanks :)

@MartinX3
Copy link
Author

MartinX3 commented May 17, 2021

Thank you, switching to var fixed the problem, and it's weird, that it worked with java 8. :)

But of course I would prefer to use val in the future, since the version variable is, like the ID, changed by the database and not the application developer. :D

@evanchooly
Copy link
Member

@MartinX3 val is about reference mutability and not application semantics, though. It simply can't be val because the language won't allow for it. A version is, arguably, a mutable field even if your application treats it as carved in stone. You might try declaring a private set for that property so that at least your application can't change it even if hibernate uses dark wizardry to do so.

@geoand
Copy link
Contributor

geoand commented May 17, 2021

The fact that it worked in Java 8 was likely accidental.

Like @evanchooly describes, a val (or final) field is not meant to be updated outside of the constructor, which is what happens in the case of the version field

@MartinX3
Copy link
Author

Ah, thank you very much. :)
Let's see what they write in the hibernate ticket. :)

@geoand
Copy link
Contributor

geoand commented Feb 29, 2024

Closing this as we now require Java 17 as a minimum

@geoand geoand closed this as not planned Won't fix, can't repro, duplicate, stale Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants