javalin / javalin

A simple and modern Java and Kotlin web framework

Home Page:https://javalin.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Javalin 6.1.0: `java.lang.NoSuchMethodError: 'java.lang.Object java.util.List.removeFirst()'` when setting a cookie

Jerbell opened this issue · comments

Actual behavior (the bug)
When I set a cookie I get a java.lang.NoSuchMethodError: 'java.lang.Object java.util.List.removeFirst()'. I have confirmed with a minimal project.

Expected behavior
Should be able to set a cookie.

To Reproduce

import io.javalin.Javalin
import io.javalin.http.Cookie

fun main() {
    val app = Javalin.create(/*config*/)
            .get("/") { ctx ->
                val cookie = Cookie("name", "value")
                cookie.isHttpOnly = true
                ctx.cookie(cookie)
                ctx.result("Hello World")
            }
            .start(7070)
}

Click on the URL once the server has started.

Additional context
This only happens with Javalin 6.1.0. I'm not sure why this happens. It's not clear, because the code looks like it should all work. Could the Kotlin version have been changed accidentally on compile?

Thanks @Jerbell - These NoSuchMethodError issues are usually caused by conflicting dependencies. The cookie API is well tested, so I don't think this is an actual bug. How have you configured your project?

removeFirst was only added to java.util.List in JDK 21

removeFirst was only added to java.util.List in JDK 21

Would be very surprising if we were using it then 🤔

The removeFirst that we are using is this:

@SinceKotlin("1.4")
@WasExperimental(ExperimentalStdlibApi::class)
public fun <T> MutableList<T>.removeFirst(): T = if (isEmpty()) throw NoSuchElementException("List is empty.") else removeAt(0)

As a guess without the background (or seeing the actual stack trace), with the maven-compiler-plugin / configuration instead of using source and target it could use release:

https://github.com/javalin/javalin/blob/master/pom.xml#L306-L307

So change from:

<configuration>
    <source>${jdk.version}</source>
    <target>${jdk.version}</target>
</configuration>

To:

<configuration>
    <release>${jdk.version}</release>
</configuration>

Oh, this is not fun... It's picking a new Java method instead of the Kotlin extension we're using? I could update the POM, but maybe it's safer to do import kotlin.collections.removeFirst as removeFirstKt.

@dzikoysk have you ran into this before?

I could update the POM

We could do both. I'd suggest we really should be using release going forward (and not source and target).

We could do both. I'd suggest we really should be using release going forward (and not source and target).

Did both in 7799662.

@dzikoysk have you ran into this before?

Yes, this is caused by your setup - you've released Javalin that is targeted for JDK11 with JDK21.

Yes, this is caused by your setup - you've released Javalin that is targeted for JDK11 with JDK21.

It seems like a pretty serious issue that all the Kotlin extensions can be hijacked by Java versions though... how do we guard against that in general?

Releasing a build from the minimal required Java version is enough to avoid this kind of issues. For instance, I've set the jdk version on CI to 11, but it looks like zug bumped it 4 days ago, so snapshots builds are also affected now 😬

The last time I faced this issue I kinda forgot about this, but maybe this time it might be a good idea to report this on YouTrack. They already have a few similar issues, but maybe we can somehow push them to prioritize a fix at some point:

Thanks everyone.
The stack trace was basically the same as the issue @dzikoysk has reported - in that it gave the impression it was trying to use the Kotlin method, but then complaining it wasn't there.
I was using Java 17.

@Jerbell please try 6.1.1 now :)

Thanks - tis working now