akka/akka-core

akka dies with a java.lang.UnsatisfiedLinkError when run GraalVM native-image

Open

#25,090 opened on May 13, 2018

View on GitHub
 (27 comments) (8 reactions) (0 assignees)Scala (3,547 forks)batch import
1 - triagedhelp wantedt:graal

Repository metrics

Stars
 (13,277 stars)
PR merge metrics
 (Avg merge 8d 19h) (10 merged PRs in 30d)

Description

I've been trying to very a (very) small native akka-http prototype with native-image from graalvm. The build is passing but there is an issue when running the resulting binary.

akka.util.Reflect contains the following code:

  val getCallerClass: Option[Int ⇒ Class[_]] = {
    try {
      val c = Class.forName("sun.reflect.Reflection")
      val m = c.getMethod("getCallerClass", Array(classOf[Int]): _*)
      Some((i: Int) ⇒ m.invoke(null, Array[AnyRef](i.asInstanceOf[java.lang.Integer]): _*).asInstanceOf[Class[_]])
    } catch {
      case NonFatal(e) ⇒ None
    }
  }

The selected method getCallerClass has been deprecated a while ago and is not suppoerted on Graalvm. This causes a java.lang.UnsatisifedLinkError, bubbling right up through the Try.

This is the resulting stacktrace:

Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.lang.Throwable.<init>(Throwable.java:310)
	at java.lang.Exception.<init>(Exception.java:102)
	at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
	at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
	at com.oracle.svm.reflect.proxies.Proxy_11_QuickstartServer_main.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:199)
	at Lcom/oracle/svm/core/code/CEntryPointCallStubs;.com_002eoracle_002esvm_002ecore_002eJavaMainWrapper_002erun_0028int_002corg_002egraalvm_002enativeimage_002ec_002etype_002eCCharPointerPointer_0029(generated:0)
Caused by: java.lang.reflect.InvocationTargetException
	at java.lang.Throwable.<init>(Throwable.java:310)
	at java.lang.Exception.<init>(Exception.java:102)
	at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
	at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
	at com.oracle.svm.reflect.proxies.Proxy_12_Reflection_getCallerClass.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at akka.util.Reflect$.$anonfun$getCallerClass$1(Reflect.scala:34)
	at akka.util.Reflect$.$anonfun$getCallerClass$1$adapted(Reflect.scala:34)
	at akka.util.Reflect$$$Lambda$2807/203574664.apply(Unknown Source)
	at scala.collection.Iterator$$anon$10.next(Iterator.scala:457)
	at scala.collection.Iterator$$anon$17.hasNext(Iterator.scala:816)
	at scala.collection.Iterator$$anon$17.next(Iterator.scala:827)
	at akka.util.Reflect$.findCaller$1(Reflect.scala:164)
	at akka.util.Reflect$.$anonfun$findClassLoader$3(Reflect.scala:176)
	at akka.util.Reflect$$$Lambda$3146/578795602.apply(Unknown Source)
	at scala.Option.map(Option.scala:146)
	at akka.util.Reflect$.$anonfun$findClassLoader$2(Reflect.scala:176)
	at akka.util.Reflect$$$Lambda$3007/1594164979.apply(Unknown Source)
	at scala.Option.orElse(Option.scala:289)
	at akka.util.Reflect$.findClassLoader(Reflect.scala:176)
	at akka.actor.ActorSystem$.findClassLoader(ActorSystem.scala:382)
	at akka.actor.ActorSystem$.$anonfun$apply$2(ActorSystem.scala:242)
	at akka.actor.ActorSystem$$$Lambda$2792/1909573877.apply(Unknown Source)
	at scala.Option.getOrElse(Option.scala:121)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:242)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:289)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:234)
	at de.codepitbull.graalvm.QuickstartServer$.main(QuickstartServer.scala:16)
	at de.codepitbull.graalvm.QuickstartServer.main(QuickstartServer.scala)
	... 4 more
Caused by: java.lang.UnsatisfiedLinkError: sun.reflect.Reflection.getCallerClass(I)Ljava/lang/Class; [symbol: Java_sun_reflect_Reflection_getCallerClass or Java_sun_reflect_Reflection_getCallerClass__I]
	at java.lang.Throwable.<init>(Throwable.java:265)
	at java.lang.Error.<init>(Error.java:70)
	at java.lang.LinkageError.<init>(LinkageError.java:55)
	at java.lang.UnsatisfiedLinkError.<init>(UnsatisfiedLinkError.java:54)
	at com.oracle.svm.jni.access.JNINativeLinkage.getOrFindEntryPoint(JNINativeLinkage.java:123)
	at com.oracle.svm.jni.JNIGeneratedMethodSupport.nativeCallAddress(JNIGeneratedMethodSupport.java:52)
	at sun.reflect.Reflection.getCallerClass(Reflection.java)
	... 29 more

This happens on:

akka: 2.5.12 scala: 2.12.5 akka-http: 10.1.1

I checked the current master and the code is also there.

This is the Main-method I used (please note that using App with Graalvm doesn't work currently because of this https://github.com/oracle/graal/issues/370 ):

object QuickstartServer {
  def main(args: Array[String]): Unit = {
    implicit val system: ActorSystem = ActorSystem("helloAkkaHttpServer")
    implicit val materializer: ActorMaterializer = ActorMaterializer()

    val routes: Route = pathPrefix("hello") {
      get {
        complete("World!")
      }
    }
    Http().bindAndHandle(routes, "localhost", 8080)

    println(s"Server online at http://localhost:8080/")

    Await.result(system.whenTerminated, Duration.Inf)
  }
}

And the contents of build.sbt:

lazy val akkaHttpVersion = "10.1.1"
lazy val akkaVersion    = "2.5.12"
retrieveManaged := true
lazy val root = (project in file(".")).
  settings(
    inThisBuild(List(
      organization    := "de.codepitbull.graalvm",
      scalaVersion    := "2.12.5"
    )),
    name := "graalvm-akka-http",
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http"            % akkaHttpVersion,
      "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
      "com.typesafe.akka" %% "akka-http-xml"        % akkaHttpVersion,
      "com.typesafe.akka" %% "akka-stream"          % akkaVersion,

      "com.typesafe.akka" %% "akka-http-testkit"    % akkaHttpVersion % Test,
      "com.typesafe.akka" %% "akka-testkit"         % akkaVersion     % Test,
      "com.typesafe.akka" %% "akka-stream-testkit"  % akkaVersion     % Test,
      "org.scalatest"     %% "scalatest"            % "3.0.1"         % Test
    )
  )

Contributor guide