Playframework: Unterstützung von GraalVM und nativer Image-Kompilierung

Erstellt am 18. Juni 2019  ·  3Kommentare  ·  Quelle: playframework/playframework

Suchen Sie Hilfe?

Oracle hat "GraalVM" veröffentlicht, die es unter anderem ermöglicht, aus beliebigem Java/Scala-Code eine native Anwendung zu bauen. Der Rückgang des Ressourcenverbrauchs (insbesondere des RAM) ist für eine Micro-Service-Architektur äußerst nützlich.
Ein Beispiel für die Leistungssteigerung wurde hier gemacht .
Und es wurden einige Anstrengungen unternommen, um es mit Akka zu verwenden: hier , was gut funktionierte, wenn Sie ein wenig zusätzliche Arbeit leisten.

In Bezug auf Play! wurde vor ca. einem Jahr eine Untersuchung durchgeführt, aber seitdem kein nennenswertes Update, zumindest keine leicht auffindbare Dokumentation für Play! als natives Image kompiliert.

Spielversion (2.5.x / etc)

Play 2.7.2 (auch getestet Play 2.8.0-M1, kein Unterschied)

API (Scala / Java / Keine / Beide)

Scala

Betriebssystem (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

Centos 7,4

JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)

openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-20190420092731.buildslave.jdk8u-src-tar--b03)
OpenJDK GraalVM CE 19.0.0 (build 25.212-b03-jvmci-19-b01, mixed mode)

Bibliotheksabhängigkeiten

Nativer Packager in der plugins.sbt:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.22")

Ich habe auch die verschiedenen hier beschriebenen Abhängigkeiten verwendet.

Erwartetes Verhalten

sbt graalvm-native-image:packageBin
Sollte ein gültiges natives Image erzeugen, das genauso funktioniert wie "sbt run"

Tatsächliches Verhalten

sbt graalvm-native-image:packageBin
erzeugt folgende Ausgabe:

[info] Build on Server(pid: 11141, port: 36524)
[info] [toto:11141]    classlist:  21,260.28 ms
[info] [toto:11141]        (cap):   1,767.01 ms
[info] [toto:11141]        setup:   2,388.54 ms
[error] SLF4J: Class path contains multiple SLF4J bindings.
[error] SLF4J: Found binding in [jar:file:/root/.ivy2/cache/org.slf4j/slf4j-jdk14/jars/slf4j-jdk14-1.7.26.jar!/org/slf4j/impl/StaticLoggerBinder.class]
[error] SLF4J: Found binding in [jar:file:/root/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
[error] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
[error] SLF4J: Actual binding is of type [org.slf4j.impl.JDK14LoggerFactory]
[error] warning: unknown locality of class Lplay/api/ApplicationLoader$JavaApplicationLoaderAdapter$1;, assuming class is not local. To remove the warning report an issue to the library or language author. The issue is caused by Lplay/api/ApplicationLoader$JavaApplicationLoaderAdapter$1; which is not following the naming convention.
[info] [toto:11141]   (typeflow):  13,441.84 ms
[info] [toto:11141]    (objects):  17,188.40 ms
[info] [toto:11141]   (features):   1,067.56 ms
[info] [toto:11141]     analysis:  32,508.22 ms
[info] [toto:11141]     (clinit):   1,399.26 ms
[info] [toto:11141]     universe:   2,136.28 ms
[info] [toto:11141]      (parse):   1,952.24 ms
[info] [toto:11141]     (inline):   4,481.05 ms
[info] [toto:11141]    (compile):  20,128.95 ms
[info] [toto:11141]      compile:  27,921.33 ms
[info] [toto:11141]        image:   2,155.43 ms
[info] [toto:11141]        write:     496.31 ms
[info] [toto:11141]      [total]:  89,001.17 ms
[success] Total time: 127 s, completed Jun 18, 2019 3:54:19 PM

Auch wenn die endgültige Ausgabe "[Erfolg]" lautet, wenn Sie versuchen, die generierte Anwendung zu starten:

[root<strong i="11">@localhost</strong> toto]# target/graalvm-native-image/toto
Oops, cannot start the server.
<strong i="12">@7c8imkl6p</strong>: Cannot load play.application.loader[play.application.loader [play.api.inject.guice.GuiceApplicationLoader] was not loaded.]
        at play.utils.Reflect$.loadClass$1(Reflect.scala:132)
        at play.utils.Reflect$.configuredClass(Reflect.scala:145)
        at play.api.ApplicationLoader$.apply(ApplicationLoader.scala:166)
        at play.core.server.ProdServerStart$.start(ProdServerStart.scala:58)
        at play.core.server.ProdServerStart$.main(ProdServerStart.scala:31)
        at play.core.server.ProdServerStart.main(ProdServerStart.scala)
Caused by: java.lang.ClassNotFoundException: play.api.inject.guice.GuiceApplicationLoader
        at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:51)
        at java.lang.ClassLoader.loadClass(Target_java_lang_ClassLoader.java:131)
        at play.utils.Reflect$.loadClass$1(Reflect.scala:126)
        ... 5 more

Reproduzierbarer Testfall

Projekt: https://github.com/gilles-degols/play-graal/
Dies ist ein sehr einfaches, automatisch generiertes Play-Projekt, aus dem ich alle Dienste, Controller und Filter entfernt habe. Die Idee ist, es zunächst so einfach wie möglich zu kompilieren und dann nach und nach die erweiterten Funktionen von Play! damit.

help wanted

Hilfreichster Kommentar

@schmitch du hast recht! Indem ich hier ein Projekt verwendete
Ich denke, wir können dieses Ticket schließen, aber es wäre für die Zukunft interessant, den ursprünglichen Beitrag, den Sie hier geschrieben

Nochmals vielen Dank für Ihren ersten Blogbeitrag & diesen Kommentar!

Alle 3 Kommentare

Hallo @gilles-degols.
Dies ist nicht in unserem kurzfristigen Plan, aber definitiv eine interessante Untersuchung.

Tatsächlich ist das Problem hier, dass Sie Guice @gilles-degols verwenden, wenn Sie ohne Jungs spielen, funktioniert es, wenn Sie alles Notwendige in das Bild einfügen. mit guice müssen Sie dem Image grundsätzlich alle Klassen hinzufügen, die dynamisch eingebunden werden.

@schmitch du hast recht! Indem ich hier ein Projekt verwendete
Ich denke, wir können dieses Ticket schließen, aber es wäre für die Zukunft interessant, den ursprünglichen Beitrag, den Sie hier geschrieben

Nochmals vielen Dank für Ihren ersten Blogbeitrag & diesen Kommentar!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen