scalameta / svm-subs

GraalVM native-image substitutions for Scala
25 stars 4 forks source link

com.oracle.svm.core.jdk.UnsupportedFeatureError still presented #3

Open atrianac opened 3 years ago

atrianac commented 3 years ago

Describe the bug

Build a Scala 2.13 project, using Java 11, GraalVM 20.2.0 on Docker raises the error:

Wxception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: Invoke with MethodHandle argument could not be reduced to at most a single call or single field access. The method handle must be a compile time constant, e.g., be loaded from a `static final` field. Method that contains the method handle invocation: java.lang.invoke.LambdaForm$MH/212255434.invoke_MT(Object, Object)
        at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:86)
        at scala.runtime.Statics.releaseFence(Statics.java:148)
        at scala.collection.immutable.BitmapIndexedMapNode.<init>(HashMap.scala:588)
        at scala.collection.immutable.MapNode$.<clinit>(HashMap.scala:495)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:351)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:271)
        at scala.collection.immutable.HashMap$.<clinit>(HashMap.scala:2161)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:351)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:271)
        at scala.collection.immutable.Map$Map4.updated(Map.scala:563)
        at scala.collection.immutable.Map$Map4.updated(Map.scala:506)
        at scala.collection.immutable.MapOps.$plus(Map.scala:133)
        at scala.collection.immutable.MapOps.$plus$(Map.scala:133)
        at scala.collection.immutable.AbstractMap.$plus(Map.scala:641)
        at zio.Has$HasSyntax$.add$extension(Has.scala:167)
        at zio.Has$.allOf(Has.scala:263)
        at zio.PlatformSpecific$ZEnv$Services$.<init>(PlatformSpecific.scala:32)
        at zio.PlatformSpecific$ZEnv$.Services$lzycompute$1(PlatformSpecific.scala:30)
        at zio.PlatformSpecific$ZEnv$.Services(PlatformSpecific.scala:30)
        at zio.BootstrapRuntime.$init$(BootstrapRuntime.scala:22)
        at com.x.Main$.<clinit>(Main.scala:18)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:351)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:271)
        at com.x.Main.main(Main.scala)

The Docker file looks like this:

FROM oracle/graalvm-ce:20.2.0-java11 as builder

RUN gu install native-image

ARG RESULT_LIB="/staticlibs"

RUN mkdir ${RESULT_LIB} && \
    curl -L -o musl.tar.gz https://musl.libc.org/releases/musl-1.2.1.tar.gz && \
    mkdir musl && tar -xvzf musl.tar.gz -C musl --strip-components 1 && cd musl && \
    ./configure --disable-shared --prefix=${RESULT_LIB} && \
    make && make install && \
    cd / && rm -rf /muscl && rm -f /musl.tar.gz && \
    cp /usr/lib/gcc/x86_64-redhat-linux/4.8.2/libstdc++.a ${RESULT_LIB}/lib/

ENV PATH="$PATH:${RESULT_LIB}/bin"
ENV CC="musl-gcc"

RUN curl -L -o zlib.tar.gz https://zlib.net/zlib-1.2.11.tar.gz && \
   mkdir zlib && tar -xvzf zlib.tar.gz -C zlib --strip-components 1 && cd zlib && \
   ./configure --static --prefix=${RESULT_LIB} && \
    make && make install && \
    cd / && rm -rf /zlib && rm -f /zlib.tar.gz

WORKDIR /app
COPY . /app

RUN ./sbt graalvm-native-image:packageBin

FROM scratch

EXPOSE 8080

COPY --from=builder /app/target/graalvm-native-image/project-name /project-name

ENTRYPOINT ["/project-name"]

And the SBT, like this:

import com.typesafe.sbt.packager.docker.DockerPermissionStrategy

addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.0" cross CrossVersion.full)

enablePlugins(GitVersioning, GraalVMNativeImagePlugin)

val ZioVersion      = "1.0.3"
val Http4sVersion   = "0.21.13"
val CirceVersion    = "0.13.0"
val ZioCatsIterop   = "2.2.0.1"
val ZioConfig       = "1.0.0-RC30-1"
val ZioLogging      = "0.4.0"
val ScalaXmlVersion = "1.2.0"
val xtractVersion   = "2.2.1"
val TapirVersion    = "0.17.0-M9"

resolvers += Resolver.sonatypeRepo("releases")
resolvers += Resolver.sonatypeRepo("snapshots")

lazy val root = (project in file("."))
  .settings(
    organization := "com.x.x",
    name := "project-name",
    version := "1.0.0",
    scalaVersion := "2.13.3",
    maxErrors := 3,
    semanticdbEnabled := true,
    semanticdbVersion := scalafixSemanticdb.revision,
    libraryDependencies ++= Seq(
      "org.http4s"                  %% "http4s-blaze-server"      % Http4sVersion,
      "org.http4s"                  %% "http4s-scala-xml"         % Http4sVersion,
      "org.http4s"                  %% "http4s-blaze-client"      % Http4sVersion,
      "org.http4s"                  %% "http4s-circe"             % Http4sVersion,
      "org.http4s"                  %% "http4s-dsl"               % Http4sVersion,
      "io.circe"                    %% "circe-generic"            % CirceVersion,
      "io.circe"                    %% "circe-generic-extras"     % CirceVersion,
      "dev.zio"                     %% "zio"                      % ZioVersion,
      "dev.zio"                     %% "zio-interop-cats"         % ZioCatsIterop,
      "dev.zio"                     %% "zio-config"               % ZioConfig,
      "dev.zio"                     %% "zio-config-typesafe"      % ZioConfig,
      "dev.zio"                     %% "zio-logging"              % ZioLogging,
      "dev.zio"                     %% "zio-streams"              % ZioVersion,
      "org.scala-lang.modules"      %% "scala-xml"                % ScalaXmlVersion,
      "com.lucidchart"              %% "xtract"                   % xtractVersion,
      "dev.zio"                     %% "zio-test"                 % ZioVersion   % "test",
      "dev.zio"                     %% "zio-test-sbt"             % ZioVersion   % "test",
      "dev.zio"                     %% "zio-test-magnolia"        % ZioVersion   % "test",
      "dev.zio"                     %% "zio-streams"              % ZioVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-core"               % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-zio"                % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-zio-http4s-server"  % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-http4s"  % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-redoc-http4s"       % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-json-circe"         % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-openapi-docs"       % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-openapi-circe-yaml" % TapirVersion,
      "com.softwaremill.sttp.tapir" %% "tapir-sttp-stub-server"   % TapirVersion % "test",
      "org.scala-lang.modules"      %% "scala-xml"                % ScalaXmlVersion
    )
  )

lazy val nativeImageProject = project.settings(
  libraryDependencies += "org.scalameta" %% "svm-subs" % "20.2.0" % "compile-internal"
)

scalafixDependencies in ThisBuild +=
  "com.github.liancheng" %% "organize-imports" % "0.4.4"

Global / cancelable := false

javacOptions ++= Seq("-source", "11", "-target", "11")

testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")

scalacOptions --= Seq(
  "-target:jvm-11",
  "-Xfatal-warnings",
  "-Wunused"
)

initialize := {
  val _           = initialize.value
  val javaVersion = sys.props("java.specification.version")
  if (javaVersion != "11")
    sys.error(
      "Java 11 is required for this project. Found " + javaVersion + " instead"
    )
}

publishArtifact in (Compile, packageDoc) := false

publishArtifact in packageDoc := false

sources in (Compile, doc) := Seq.empty

graalVMNativeImageOptions ++= Seq(
  "--verbose",
  "--no-server",
  "--no-fallback",
  "--install-exit-handlers",
  "--allow-incomplete-classpath",
  "--enable-all-security-services",
  "-J-Xmx8G",
  "-J-Xms4G",
  "-H:+ReportUnsupportedElementsAtRuntime",
  "-H:+ReportExceptionStackTraces",
  "-H:+PrintClassInitialization",
  "-H:+RemoveSaturatedTypeFlows",
  "-H:EnableURLProtocols=http,https",
  "-H:+JNI",
  "--initialize-at-build-time=scala.runtime.Statics$VM"
)

val os = System.getProperty("os.name").toLowerCase()

val graalSpcOpts = os match {
  case linux if linux.contains("linux") =>
    Seq("--static", "--libc=musl")
  case _                                => Seq.empty
}
graalVMNativeImageOptions ++= graalSpcOpts

addCommandAlias("fmt", "all scalafmtSbt scalafmt test:scalafmt")
addCommandAlias("chk", "all scalafmtSbtCheck scalafmtCheck test:scalafmtCheck")

To Reproduce Steps to reproduce the behavior:

  1. Run command docker build -t [tagname] .
  2. Run command docker run -d -p 8080:8080 [tagname] .

Expected behavior

The application runs correctly.

Installation:

terpstra commented 3 years ago

(Removed irrelevant comment; I see you are using 2.13)