scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

java.lang.IllegalAccessError: failed to access class com.linecorp.armeria.server.AbstractContextPathServicesBuilder

Open chungonn opened this issue 1 year ago • 11 comments

Compiler version

Scala version 3.3.3 and 3.5.1

Minimized code

The code below runs in Java. But in Scala, it throws an IllegalAccessError exception.

package experiment

import com.linecorp.armeria.common.HttpResponse
import com.linecorp.armeria.server.Server

@main def hello(): Unit =
  val server = Server.builder()
    .contextPath("/v1")
    .service("/", (ctx, req) => HttpResponse.of("Hello, world"))
    .and()
    .build()
    .start()

  println(s"server started = ${server}")

build.sbt

val scala3Version = "3.5.1"

lazy val root = project
  .in(file("."))
  .settings(
    name := "test-armeria",
    version := "0.1.0-SNAPSHOT",

    scalaVersion := scala3Version,

    libraryDependencies ++= Seq(
      "com.linecorp.armeria" % "armeria" % "1.30.1",
    )
  )

Output

Exception in thread "main" java.lang.IllegalAccessError: failed to access class com.linecorp.armeria.server.AbstractContextPathServicesBuilder from class experiment.Main$package$ (com.linecorp.armeria.server.AbstractContextPathServicesBuilder and experiment.Main$package$ are in unnamed module of loader 'app')
	at experiment.Main$package$.hello(Main.scala:9)
	at experiment.hello.main(Main.scala:6)

Expectation

The code should run without error.

chungonn avatar Oct 17 '24 06:10 chungonn

The same code works in Scala 2.12.13

package experiment

import com.linecorp.armeria.common.HttpResponse
import com.linecorp.armeria.server.Server
object Test {

  def main(args: Array[String]): Unit = {
    val server = Server.builder()
      .contextPath("/v1")
      .service("/", (ctx, req) => HttpResponse.of("Hello, world"))
      .and()
      .build()
      .start()

    println(s"server started = ${server}")
  }
}

val scala3Version = "2.12.13"

lazy val root = project
  .in(file("."))
  .settings(
    name := "test-armeria",
    version := "0.1.0-SNAPSHOT",

    scalaVersion := scala3Version,

    libraryDependencies ++= Seq(
      "com.linecorp.armeria" % "armeria" % "1.30.1",
    )
  )

chungonn avatar Oct 17 '24 06:10 chungonn

This seems to have been fixed in nightly ( 3.6.1-RC1-bin-20241016-2fc299b-NIGHTLY), but not in 3.5.2-RC2. We might need to bisect the fix and backport to the LTS. cc @prolativ

The following works:

//> using scala 3.6.1-RC1-bin-20241016-2fc299b-NIGHTLY
//> using dep com.linecorp.armeria:armeria:1.30.1
package experiment

import com.linecorp.armeria.common.HttpResponse
import com.linecorp.armeria.server.Server
object Test {

  def main(args: Array[String]): Unit = {
    val server = Server.builder()
      .contextPath("/v1")
      .service("/", (ctx, req) => HttpResponse.of("Hello, world"))
      .and()
      .build()
      .start()

    println(s"server started = ${server}")
  }
}

Gedochao avatar Oct 17 '24 07:10 Gedochao

@Gedochao I confirmed that 3.6.1-RC1-bin-20241016-2fc299b-NIGHTLY fixes the problem

chungonn avatar Oct 17 '24 08:10 chungonn

I would be grateful if this fixed can be backport to the next possible 3.5.x. Thanks in advance

chungonn avatar Oct 17 '24 08:10 chungonn

I would be grateful if this fixed can be backport to the next possible 3.5.x. Thanks in advance

It's likely too late for it to be backported to 3.5.2, unless we'd have another RC. which I'm hoping we won't as 3.5.2 (the last in the 3.5.x line) is being released as we speak. See:

  • https://github.com/scala/scala3/issues/21781

tagging @WojciechMazur just in case. Otherwise, I'm guessing the fix would be included in 3.6.0 or 3.6.1

Gedochao avatar Oct 17 '24 08:10 Gedochao

Noted with thanks!

chungonn avatar Oct 17 '24 08:10 chungonn

3.5.2 final has already been shipped. It will be backported to 3.6.0 or 3.6.1

WojciechMazur avatar Oct 17 '24 08:10 WojciechMazur

I needed to slightly modify the snippet to close the server so that it doesn't hang the bisecting tests. /tmp/bisect/ArmeriaServer.scala:

//> using dep com.linecorp.armeria:armeria:1.30.1

import com.linecorp.armeria.common.HttpResponse
import com.linecorp.armeria.server.Server
object Test {
  def main(args: Array[String]): Unit = {
    val server = Server.builder()
      .contextPath("/v1")
      .service("/", (ctx, req) => HttpResponse.of("Hello, world"))
      .and()
      .build()
    println(s"starting server")
    val started = server.start()
    started.get()
    println(s"server started")
    server.stop()
    println(s"server stopped")
  }
}

Bisected with

scala-cli project/scripts/bisect.scala -- --should-fail --releases 3.5.1-RC1-bin-20240628-1efbb92-NIGHTLY... run /tmp/bisect/ArmeriaServer.scala

The bisect points to https://github.com/scala/scala3/pull/21362

prolativ avatar Oct 17 '24 09:10 prolativ

Ah, I've just bisected it to the same commit, adding sys.exit(0) would do the job as well for bisect purpose. I'll start backporting this to 3.6.0-RC1. I propose to close it after backporting to 3.3.5 LTS

WojciechMazur avatar Oct 17 '24 09:10 WojciechMazur

@WojciechMazur as far as I can see the issue was fixed on 10.08, which was before the cut-off of release-3.6.0, so this shouldn't need any backporting for 3.6.x. Or did I miss something?

prolativ avatar Oct 17 '24 09:10 prolativ

That's correct, I've just checked to ensure it's included, so no work needed for Next release

WojciechMazur avatar Oct 17 '24 09:10 WojciechMazur

Works in 3.6.2

prolativ avatar Jan 02 '25 07:01 prolativ