Skip to content
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

Graal native image support #29

Closed
sdeleuze opened this issue Jun 5, 2018 · 18 comments
Closed

Graal native image support #29

sdeleuze opened this issue Jun 5, 2018 · 18 comments
Assignees
Milestone

Comments

@sdeleuze
Copy link
Collaborator

sdeleuze commented Jun 5, 2018

Currently even with Graal snapshots it fails with following error:

mx native-image -Dio.netty.noUnsafe=true -H:ReflectionConfigurationFiles=/home/seb/workspace/spring-fu/samples/simple-webapp/graal.json -H:+ReportUnsupportedElementsAtRuntime -Dfile.encoding=UTF-8  -jar /home/seb/workspace/spring-fu/samples/simple-webapp/build/libs/simple-webapp-all.jar 
   classlist:  10,845.71 ms
       (cap):   3,785.48 ms
       setup:   7,078.43 ms
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Jun 05, 2018 2:48:49 PM io.netty.util.internal.PlatformDependent <clinit>
INFO: Your platform does not provide complete low-level API for accessing direct buffers reliably. Unless explicitly requested, heap buffer will always be preferred to avoid potential system instability.
    analysis:  38,365.98 ms
fatal error: java.lang.reflect.MalformedParameterizedTypeException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
	at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1005)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:381)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:281)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:378)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:104)
Caused by: java.lang.reflect.MalformedParameterizedTypeException
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:58)
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:51)
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:92)
	at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
	at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:140)
	at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at sun.reflect.generics.repository.ClassRepository.getSuperInterfaces(ClassRepository.java:108)
	at java.lang.Class.getGenericInterfaces(Class.java:913)
	at com.oracle.svm.hosted.analysis.Inflation.fillGenericInfo(Inflation.java:240)
	at com.oracle.svm.hosted.analysis.Inflation.checkType(Inflation.java:148)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080)
	at com.oracle.svm.hosted.analysis.Inflation.checkObjectGraph(Inflation.java:125)
	at com.oracle.graal.pointsto.BigBang.checkObjectGraph(BigBang.java:582)
	at com.oracle.graal.pointsto.BigBang.finish(BigBang.java:554)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:642)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:364)
	at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Error: Image building with exit status 1

graal.json

[
  {
    "name" : "io.netty.channel.socket.nio.NioSocketChannel",
    "methods" : [
      { "name" : "<init>", "parameterTypes" : [] }
    ]
  },
  {
    "name" : "io.netty.channel.socket.nio.NioServerSocketChannel",
    "methods" : [
      { "name" : "<init>", "parameterTypes" : [] }
    ]
  }
]

We need to report this kind of issues to Graal project and provide custom spring-fu.json reflection configuration in order to provide first class support for native images.

@sdeleuze sdeleuze added this to the 1.0.0.M3 milestone Jun 5, 2018
@rivasdiaz
Copy link

Kotlin ticket: https://youtrack.jetbrains.net/issue/KT-23962

@sdeleuze
Copy link
Collaborator Author

With KT-23962 and graal#416 now fixed we should now give it another try.

@sdeleuze
Copy link
Collaborator Author

I think we are quite close to get it working. On this branch with Graal 1.0.0.RC2, the executable is created and throw this exception when running:

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_94_ApplicationKt_main.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:173)
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: RuntimeMXBean methods
	at java.lang.Throwable.<init>(Throwable.java:265)
	at java.lang.Error.<init>(Error.java:70)
	at com.oracle.svm.core.jdk.UnsupportedFeatureError.<init>(UnsupportedFeatureError.java:31)
	at com.oracle.svm.core.jdk.Target_com_oracle_svm_core_util_VMError.unsupportedFeature(VMErrorSubstitutions.java:105)
	at com.oracle.svm.core.jdk.SubstrateRuntimeMXBean.getUptime(JavaManagementSubstitutions.java:238)
	at org.springframework.fu.ApplicationDsl.run(ApplicationDsl.kt:181)
	at org.springframework.fu.ApplicationDsl.run$default(ApplicationDsl.kt:164)
	at org.springframework.fu.sample.minimal.ApplicationKt.main(Application.kt:35)
	... 3 more

Not sure yet how we could avoid using RuntimeMXBean methods to avoid this error.
Any thoughts @dsyer @jhoeller?

@sdeleuze sdeleuze modified the milestones: 1.0.0.M3, 1.0.0.M2 Jun 18, 2018
@sdeleuze sdeleuze self-assigned this Jun 18, 2018
@sdeleuze
Copy link
Collaborator Author

Good news, KT-23962 will be fixed in upcoming Kotlin 1.2.51.

@sdeleuze sdeleuze modified the milestones: 0.0.2, 0.0.1 Jun 20, 2018
@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Jun 20, 2018

Spring Fu minimal webapp is now compiling to a native image successfully with Graal 1.0.0.RC2, Kotlin 1.2.60 (will also work with 1.2.51) and Netty!!!

Startup time is 33 ms with Graal (to be compared with 900 ms with Java 10). The self-sufficient executable size is 50 MB but we will maybe be able to reduce it via #34.

Jetty also works.

@Peter-B-Kessler
Copy link

Thanks for finding a (previously) unused corner of the SubstrateVM runtime. I have filed an issue to implement RuntimeMXBean.getUptime(). Not all of the RuntimeMXBean methods make sense in the context of a native image. Are there others you need, and what do you think they should they should return?

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Jun 21, 2018

@Peter-B-Kessler Thanks! In Spring Boot, we use getName() (to get the PID) and getClassPath() (which could maybe be replaced by System.getProperty("java.class.path")) in addition to getUptime(). Do you think those would make sense with SubstrateVM runtime?

@Peter-B-Kessler
Copy link

RuntimeMXBean.getName() already returns the "expected" pid@hostname. (At some point we will support JDK-9 and the ProcessHandle.pid() method and I will sleep better.)

RuntimeMXBean.getClassPath() should return null because there is no path from which SubstrateVM loads classes at runtime. Similarly RuntimeMXBean.getBootClassPath() should return null.

When I implement RuntimeMXBean.getUptime() I will see what can be done for the rest of the RuntimeMXBean methods.

@sdeleuze
Copy link
Collaborator Author

Ok thanks a lot!

@sdeleuze
Copy link
Collaborator Author

@Peter-B-Kessler Any chance you could notice me when this is on GraalVM master in order to allow me to try it and make progress on the Boot side as well?

@Peter-B-Kessler
Copy link

The changes are in https://github.com/oracle/graal/blob/master/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaManagementSubstitutions.java. I don't know what the release schedule is for the next set of built binaries. You could build from sources by following the instructions in https://github.com/oracle/graal/blob/master/substratevm/README.md.

You might be disappointed that getClassPath() returns null, but that is the correct value for it to return: there is no class path at runtime.

getUptime() (and getStartTime()) depend on a startup hook that runs if your application is called from the usual static void main(String[]) entry point. If you embed SubstrateVM in another application and start it from a different entry point, to get reasonable answers from those methods you will have to call those startup hooks yourself, via RuntimeSupport.executeStartupHooks().

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Jul 2, 2018

Make sense thanks.

Next issue we face: oracle/graal#507

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Jul 3, 2018

I have updated graal branch in order to leverage GraalVM 1.0 RC3. Sadly we have a regression under investigation, see https://twitter.com/sdeleuze/status/1014051429621862400. For now, I have updated the branch to leverage Jetty instead.

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Jul 4, 2018

Related Spring Framework issue for GraalVM native image support is SPR-16991.

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Aug 29, 2018

@Peter-B-Kessler @cstancu Any plan to release a RC6 shortly? It would allow our user to create Spring Fu apps that works out of the box as native images.

@cstancu
Copy link

cstancu commented Aug 29, 2018

@sdeleuze RC6 should come out in 1 week or less.

@sdeleuze
Copy link
Collaborator Author

@cstancu Awesome thanks

@sdeleuze
Copy link
Collaborator Author

sdeleuze commented Sep 4, 2018

I reopen this issue since oracle/graal#655 regression makes it impossible to compile a Spring Fu webapp with Graal 1.0.0-RC6.

@sdeleuze sdeleuze reopened this Sep 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants