Skip to content

[native-image] running play on GraalVM/SubstrateVM #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
schmitch opened this issue May 18, 2018 · 9 comments
Closed

[native-image] running play on GraalVM/SubstrateVM #424

schmitch opened this issue May 18, 2018 · 9 comments
Assignees

Comments

@schmitch
Copy link

Hello,
I wanted to share my knowledge of running Play on GraalVM and wanted to point out some "issues" along the way.

Some error messages I couldn't really resolve are these:

  • Error: Must not have a FileDescriptor in the image heap.
  • Error: Must not have a started Thread in the image heap.

See: https://gist.github.com/schmitch/469eae4062373b6fe67def99ec220103
(I also created a repository to reproduce them: https://github.com/schmitch/play-scala-starter-example)

After that I tried to create a Play application in the "embedded" mode which is basically described here: https://www.playframework.com/documentation/2.6.x/ScalaEmbeddingPlayAkkaHttp
The good thing is, the issue's above aren't raised, however I had a problem because of the issues I described here: https://discuss.lightbend.com/t/akka-and-graal-s-native-image-tool/940/9

Currently I guess after fixing these "issues" there is still some work for play because in some cases we need proxy's or reflection where we might not need to. But a simple application could probably be made to run under substratevm.

@cstancu
Copy link
Member

cstancu commented May 18, 2018

@schmitch thank you for your report. The Must not have a <unsupported-feature> in the image heap. errors have been updated and are more descriptive now:

Detected an <unsupported-feature> in the image heap. This is not supported. 
The object was reached from a static initializer. All static class initialization 
is done during native image construction, thus a static initializer cannot 
contain code that captures state dependent on the build machine. Write 
your own initialization methods and call them explicitly from your main entry point.

,where <unsupported-feature> currently can be: a started Thread, a FileDescriptor, or a ZipFile object.

In the near future we will also support loading resources via ClassLoader, probably similarly to how we support resource bundles currently, i.e., they need to be specified at image build time via a command line option.

We already support reflection through configuration files and are currently looking into supporting java.lang.reflect.Proxy.

That being said, the best way to make an application/framework compatible with SubstrateVM is to, if possible, avoid using unsupported features.

@schmitch
Copy link
Author

schmitch commented Jun 6, 2018

Well we could probably look if we could rewrite some logic that supports SubstrateVM, however without support for ClassLoader#getResource would make it fail on runtime.
I all problems are Logging related, we could mostly lazy load the logger, however one file is problematic since it isn't our: org.slf4j.impl.StaticLoggerBinder.SINGLETON (logback-classic) which also uses a FileDescriptor. But that is not a problem on running Play in embedded mode since one can just leave out play-logback and run without logback.

I have created some work that now supports image creation, but fails on runtime:
Play branch https://github.com/schmitch/playframework/tree/substrate-vm-optimization
Play project https://github.com/schmitch/play-scala-starter-example/tree/substratevm

Part of Stacktrace:
Caused by: com.typesafe.config.ConfigException$BugOrBroken: Context class loader is not set for the current thread; if Thread.currentThread().getContextClassLoader() returns null, you must pass a ClassLoader explicitly to ConfigFactory.defaultApplication

(didn't tested rc2, yet)

@cstancu
Copy link
Member

cstancu commented Jun 13, 2018

Related: #470 (comment)

@cstancu
Copy link
Member

cstancu commented Jul 26, 2018

Is loading resources via Thread.getContextClassLoader().getResource() still a problem for you? We added support for ClassLoader.getSystemClassLoader() and Thread.getContextClassLoader(). See #470 (comment) for reference.

@schmitch
Copy link
Author

Well unfortunatly it fails with:
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Accessing an URL protocol that was not enabled. The URL protocol resource is not tested and might not work as expected. It can be enabled by adding the -H:EnableURLProtocols=resource option to the native-image command.
now.
But I tried to enable -H:EnableURLProtocols=resource

@cstancu
Copy link
Member

cstancu commented Jul 27, 2018

Can you please provide the steps to reproduce this?

@schmitch
Copy link
Author

Well just clone:

Play branch https://github.com/schmitch/playframework/tree/substrate-vm-optimization
and run cd framework && sbt publishLocal
after that clone:
Play project https://github.com/schmitch/play-scala-starter-example/tree/substratevm
and run sh build-2.12.sh (needs $GRAALVM_HOME to be set (to the latest version))

@cstancu
Copy link
Member

cstancu commented Mar 15, 2019

As of 427e54b the resource URL protocol is enabled by default and it doesn't require any special config.

@cstancu cstancu closed this as completed Mar 15, 2019
@SchrodingerZhu
Copy link

failed to read configurations for GraalVM 19+/Play 2.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants