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

EngineException when running in GraalVM Native Image #103

Closed
murphye opened this issue Jun 17, 2020 · 28 comments
Closed

EngineException when running in GraalVM Native Image #103

murphye opened this issue Jun 17, 2020 · 28 comments
Labels
bug Something isn't working

Comments

@murphye
Copy link

murphye commented Jun 17, 2020

Description

Please see this updated project: https://github.com/murphye/djl-demo/blob/master/pneumonia-detection-quarkus/README.md

I have two endpoints:

/detect will attempt to run the model, and will fail with the following error:

Caused by: ai.djl.engine.EngineException: No deep learning engine found.
Please refer to https://github.com/awslabs/djl/blob/master/docs/development/troubleshooting.md for more details.
        at ai.djl.engine.Engine.getInstance(Engine.java:90)
        at ai.djl.repository.zoo.Criteria$Builder.<init>(Criteria.java:193)
        at ai.djl.repository.zoo.Criteria.builder(Criteria.java:173)
        at com.example.ExampleResource.detect(ExampleResource.java:45)

/check will print out information showing that the TensorFlow Engine has been loaded properly.

>>>>>>>> ZooProvider: ai.djl.repository.zoo.DefaultZooProvider [models/saved_model:ai.djl.localmodelzoo:saved_model [
        ai.djl.localmodelzoo:saved_model:N/A {}

]]
>>>>>>>> Engine: TensorFlow

There is a contradiction of information here as TensorFlow Engine is loading, but still doesn't work. This only occurs when running in Native mode, as JVM mode is OK

I am not sure how to proceed. I suggest trying to add more debugging info to DJL to understand what is happening. Quarkus team will have debugger support soon.

How to Reproduce?

See instructions https://github.com/murphye/djl-demo/blob/master/pneumonia-detection-quarkus/README.md

Run the two endpoints and observe the logs.

What have you tried to solve it?

These configs enable the ServiceLoader mechanism:

  1. https://github.com/murphye/djl-demo/blob/master/pneumonia-detection-quarkus/src/main/resources/reflection-config.json
  2. https://github.com/murphye/djl-demo/blob/master/pneumonia-detection-quarkus/src/main/resources/resources-config.json

Also see https://github.com/murphye/djl-demo/blob/master/pneumonia-detection-quarkus/src/main/resources/application.properties

Environment Info

Using Maven rather than Gradle as it provides error messages that Gradle does not for Native compilation. Using Mac and GraalVM 20.1.0 with Quarkus 1.5.1.Final

@murphye murphye added the bug Something isn't working label Jun 17, 2020
@frankfliu
Copy link
Contributor

frankfliu commented Jun 17, 2020

@murphye
I added debug log to troubleshoot engine load and model zoo loading:
0af494a
b4d31d9

Engine exception might be a bug in 0.5.0, I'm trying to debug with 0.6.0-SNAPSHOT, I made some changes to your code, will post update a bit later.

@frankfliu
Copy link
Contributor

@murphye I made some changes in my branch: https://github.com/frankfliu/djl-demo/tree/quarkus/covid19-detection-quarkus

Now EngineException is gone. But I'm still facing java.lang.UnsatisfiedLinkError.

This was the same static initialization issue. I tried to add --initialize-at-run-time and --initialize-at-build-time, doesn't seem work.

All the static initializer are not executed at all. I'm not sure if I add these parameter correctly or not.

@murphye
Copy link
Author

murphye commented Jun 18, 2020

@frankfliu Did you push your changes to your branch? Can you add link to your commit?

Now that we have overcome this issue, I can try again with my original --initialize-at-run-time changes. You can see those here in the old project:

https://github.com/murphye/djl-demo/blob/master/covid19-detection-quarkus/src/main/resources/application.properties#L4

That being said it would be good to know how they got this working without --initialize-at-run-time.
https://twitter.com/bytedeco/status/1270330181924777994

@frankfliu
Copy link
Contributor

Here is my commit: frankfliu/djl-demo@1f3ef47
And the PR I created to your repo: https://github.com/murphye/djl-demo/pull/3

@frankfliu
Copy link
Contributor

@murphye I made some progress.

  1. I created a project only use graalvm: https://github.com/frankfliu/djl-demo/tree/graalvm/graalvm
    1. With a lot of manual configurations, I'm able to load TF engine, and make it partially working.
    2. Then I hit an issue with BufferedImage: [native-image] Use of Graphics fails oracle/graal#1163, It looks like we have to find an alternative image processing library.
    3. The key to make this project work is to use javacpp 1.5.4-SNAPSHOT version. I didn't find a way to make other javacpp version work with GraalVM.
  2. I try to apply the same trick to this project, I created a PR in your repo: https://github.com/murphye/djl-demo/pull/5, but I was not able build native image:
Fatal error:java.lang.NoClassDefFoundError
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
	at java.base/java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1006)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:463)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:359)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:518)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:117)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:546)
Caused by: java.lang.NoClassDefFoundError: io/netty/internal/tcnative/SSLPrivateKeyMethod
	at jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVM.getDeclaredMethods(Native Method)
	at jdk.internal.vm.ci/jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.getDeclaredMethods(HotSpotResolvedObjectTypeImpl.java:958)
	at com.oracle.svm.jni.access.JNIAccessibleMethod.anyMatchIgnoreReturnType(JNIAccessibleMethod.java:139)
	at com.oracle.svm.jni.access.JNIAccessibleMember.findHidingSubclasses(JNIAccessibleMember.java:103)

I'm not sure how I can continue on this. Can you bring this to quarkus team?

@murphye
Copy link
Author

murphye commented Jun 22, 2020

I made some progress as well. but on a different path. I am able to compile and run in Native, but the TensorFlow libs are not being loaded correctly.

15:13:30,448 WARN  [ai.djl.ten.eng.TfEngine] Failed load TensorFlow native library.: java.lang.UnsatisfiedLinkError: no jnitensorflow in java.library.path: [/Users/ermurphy/Library/Java/Extensions, /Library/Java/Extensions, /Network/Library/Java/Extensions, /System/Library/Java/Extensions, /usr/lib/java, .]

I am trying to bundle with the executable after copying to the target directory:

{
  "resources": [
    {
      "pattern": ".*\\.properties$"
    },
    {
      "pattern": ".*\\.EngineProvider$"
    },
    {
      "pattern": ".*\\.ZooProvider$"
    },
    {
      "pattern": ".*\\.dylib$"
    }
  ]
}

I will look at your Pull Request and do some further analysis. It seems to be more complicated than it should be to get this working. My other example project was fairly straightforward.

https://github.com/murphye/quarkus-tensorflow-inception
https://github.com/murphye/quarkus-tensorflow-inception/blob/master/src/main/java/io/quarkus/tensorflow/LoadTensorFlow.java
https://github.com/murphye/quarkus-tensorflow-inception/blob/master/src/main/resources/resources-config.json

@murphye
Copy link
Author

murphye commented Jun 22, 2020

@frankfliu Per your issue, try adding this to application.properties

quarkus.ssl.native=true

@murphye
Copy link
Author

murphye commented Jun 22, 2020

Per oracle/graal#1163, I have read that PNG works, but JPG does not. I have used Apache Commons Image in my other project, but it has serious limitations if the JPG is compressed too much, it cannot read the file.

https://github.com/murphye/quarkus-tensorflow-inception/blob/master/src/main/java/io/quarkus/tensorflow/ObjectDetectionService.java#L71

@frankfliu
Copy link
Contributor

@murphye I made some changes to workaround image problem. Using apache commons imaging seems work. commons images doesn't support save JPG file and some of JPG file cannot load properly. But it works in general. See my PR: deepjavalibrary/djl-demo#55

I will try quarkus.ssl.native=true for quarkus project

@frankfliu
Copy link
Contributor

@murphye I tried quarkus.ssl.native=true, it doesn't work, still got java.lang.ClassNotFoundException: io.netty.internal.tcnative.SSLPrivateKeyMethod,

I even tried add this to resource-config.json and jni-config.json, no luck.

@murphye
Copy link
Author

murphye commented Jun 22, 2020

@frankfliu I will research. Cannot find any relevant GitHub issues. Possibly a conflict with JNI config for TensorFlow & Netty?

I have concerns that there is too much configuration in the solution. It may be good to find other example of using JavaCPP with Native Image (without DJL) as a baseline.

This would be good to examine
https://twitter.com/bytedeco/status/1270330181924777994
https://gitter.im/bytedeco/javacpp?at=5ee020547b6da9126a85bfb9

@murphye
Copy link
Author

murphye commented Jun 23, 2020

@frankfliu There is something called javacpp-shadowed.jar included with GraalVM 20.1.0 that should augment SubstrateVM to work with JavaCPP.

In other words, all of the extra config shouldn't be necessary. That is all I know for now, based on some quick research.

@frankfliu
Copy link
Contributor

@murphye I made some changes to make DJL GraalVM friendly: https://github.com/frankfliu/djl/tree/graalvm, with this change you don't need adding configuration. You can see this demo project, it's working by default now: https://github.com/frankfliu/djl-demo/tree/graalvm/graalvm

It seems quarkus did something strange and changed default build behavior. With the same dependency, I got following error:

[pneumonia-detection-quarkus-1.0.0-SNAPSHOT-runner:84135]     analysis:  16,204.33 ms,  2.70 GB
7 fatal errors detected:
Fatal error:com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing com.oracle.svm.reflect.Pointer_deallocatorThread_330a2bfd42a35375c44762314d9730587206b5b5.get(java.lang.Object) 
Parsing context:
	parsing java.lang.reflect.Field.get(Field.java:418)
	parsing sun.security.jgss.GSSContextImpl.<init>(GSSContextImpl.java:135)
	parsing com.sun.security.jgss.ExtendedGSSContextImpl.<init>(ExtendedGSSContextImpl.java:39)
	parsing com.sun.security.jgss.Extender.wrap(Extender.java:53)
	parsing sun.security.jgss.GSSManagerImpl.wrap(GSSManagerImpl.java:268)
	parsing sun.security.jgss.GSSManagerImpl.createContext(GSSManagerImpl.java:160)
	parsing sun.net.www.protocol.http.spnego.NegotiatorImpl.init(NegotiatorImpl.java:99)
	parsing sun.net.www.protocol.http.spnego.NegotiatorImpl.<init>(NegotiatorImpl.java:117)
	parsing com.oracle.svm.reflect.NegotiatorImpl_constructor_05205bad162fde13ea8ccd44c4e0600dc67c2f2b_10.newInstance(Unknown Source)
	parsing java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	parsing java.util.ResourceBundle$Control.newBundle(ResourceBundle.java:3196)
	parsing java.util.ResourceBundle.loadBundle(ResourceBundle.java:1994)
	parsing java.util.ResourceBundle.findBundle(ResourceBundle.java:1776)
	parsing java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1662)
	parsing java.util.ResourceBundle$1.getBundle(ResourceBundle.java:409)
	parsing java.util.logging.Logger.findResourceBundle(Logger.java:2189)
	parsing java.util.logging.Logger.getResourceBundle(Logger.java:905)
	parsing org.jboss.logmanager.Logger.logRaw(Logger.java:733)
	parsing org.jboss.logmanager.Logger.log(Logger.java:706)
	parsing org.jboss.logmanager.Logger.log(Logger.java:719)
	parsing org.jboss.logging.JBossLogManagerLogger.doLog(JBossLogManagerLogger.java:42)
	parsing org.jboss.logging.Logger.error(Logger.java:1507)
	parsing io.quarkus.runtime.Quarkus.run(Quarkus.java:67)
	parsing io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
	parsing io.quarkus.runtime.Quarkus.run(Quarkus.java:106)
	parsing io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
	parsing com.oracle.svm.core.JavaMainWrapper.runCore(JavaMainWrapper.java:149)
	parsing com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:184)
	parsing com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_5087f5482cc9a6abc971913ece43acb471d2631b(generated:0)

	at com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:138)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:340)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:311)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:112)
	at com.oracle.graal.pointsto.DefaultAnalysisPolicy$DefaultVirtualInvokeTypeFlow.onObservedUpdate(DefaultAnalysisPolicy.java:228)
	at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:470)
	at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:542)
	at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:530)
	at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:173)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Caused by: org.graalvm.compiler.graph.GraalGraphError: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Detected a started Thread in the image heap. Threads running in the image generator are no longer running at image run time.  Object has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image run time by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
	at node: 4|LoadField#deallocatorThread

I don't know how to found offending class with the error message.

@murphye
Copy link
Author

murphye commented Jun 24, 2020

@frankfliu

(Edited comment for better response)

  1. I believe you did the correct thing by adding GraalVM support to DJL directly. The path that we were on before was not the right path because of too much configuration, etc.

  2. Make sure you have -H:+TraceClassInitialization to the build to give a better error for --initialize-at-run-time=<class-name> issue.

I see that you have it here. https://github.com/frankfliu/djl-demo/blob/quarkus/pneumonia-detection-quarkus/src/main/resources/application.properties#L5

@murphye
Copy link
Author

murphye commented Jun 26, 2020

@frankfliu Do you have all your latest code committed to DJL and demo project? I will take another look at this next week.

@frankfliu
Copy link
Contributor

@murphye I'm done on my side:

  1. I made some more changes in my private DJL branch: https://github.com/frankfliu/djl/tree/graalvm, I removed static initializer in djl code base. You can build to your local .m2 by:
cd djl
gradle pTML
gradle :tensorflow:tensorflow-native-auto:pTML
  1. I pushed quarkus-pt branch in my demo repo: https://github.com/frankfliu/djl-demo/tree/quarkus-pt/pneumonia-detection-quarkus. I'm using pytorch engine, it can generate native-image and looks fine except crash in PyTorch engine JNI code. I think that different issue.
  2. I updated quarkus branch in my repo: you can see the native-image compile error using my branch: https://github.com/frankfliu/djl-demo/tree/quarkus/pneumonia-detection-quarkus, the
  3. If I add --initialize-at-run-time=org.tensorflow\,ai.djl\,org.bytedeco, you will see a different error: io.netty.internal.tcnative.SSLPrivateKeyMethod

@murphye
Copy link
Author

murphye commented Jun 29, 2020

@frankfliu Thanks I will try to look in next couple of days. Seems like we are getting closer however. I am optimistic considering I had previous TensorFlow demo working in Quarkus.

@murphye
Copy link
Author

murphye commented Jul 8, 2020

I took some time off, and have also been sick. Will return to this as soon as possible.

@murphye
Copy link
Author

murphye commented Jul 15, 2020

OK... getting the latest code so I can test. I noticed there is aa PMD error causing build to fail.

<file name="/Users/ermurphy/GitHub/djl/api/src/main/java/ai/djl/engine/Engine.java">
<violation beginline="48" endline="84" begincolumn="9" endcolumn="9" rule="NonThreadSafeSingleton" ruleset="Multithreading" package="ai.djl.engine" class="Engine" method="initEngine" externalInfoUrl="https://pmd.github.io/pmd-6.21.0/pmd_rules_java_multithreading.html#nonthreadsafesingleton" priority="3">
Singleton is not thread safe
</violation>

https://pmd.github.io/latest/pmd_rules_java_multithreading.html#nonthreadsafesingleton

initEngine needs to be synchronized

@murphye
Copy link
Author

murphye commented Jul 15, 2020

Ok, I was able to replicate the error related to io.netty.internal.tcnative.SSLPrivateKeyMethod

This is actually related to an error that I had previously on my prior TensorFlow demo, where I for some reason needed to add dependency to get TensorFlow working:
murphye/quarkus-tensorflow-inception@93eb435#diff-600376dffeb79835ede4a0b285078036L36

There must be some hidden dependency on tcnative and it's not being handled well by GraalVM. Update: I believe this is a Quarkus-related issue, but I cannot put my finger on it other than it may be related to loading classes at Runtime. May need to open up an issue, as adding the dependency is only a workaround.

Adding this dependency allowed the native build to complete:

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-tcnative</artifactId>
        <version>2.0.31.Final</version>
    </dependency>

@murphye
Copy link
Author

murphye commented Jul 15, 2020

Ok, so this is what I get when I run the executable and hit the /detect endpoint:

ermurphy@MacBook-Pro-7 pneumonia-detection-quarkus % target/pneumonia-detection-quarkus-1.0.0-SNAPSHOT-runner 
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-07-15 01:13:46,142 INFO  [io.quarkus] (main) pneumonia-detection-quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 1.6.0.Final) started in 0.024s. Listening on: http://0.0.0.0:8080
2020-07-15 01:13:46,142 INFO  [io.quarkus] (main) Profile prod activated. 
2020-07-15 01:13:46,142 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy, resteasy-jackson]
2020-07-15 01:14:15,762 DEBUG [ai.djl.rep.zoo.ModelZoo] (executor-thread-1) Searching model in zoo provider: ai.djl.tensorflow.zoo.TfZooProvider
2020-07-15 01:14:15,762 DEBUG [ai.djl.rep.zoo.ModelZoo] (executor-thread-1) Searching model in zoo provider: ai.djl.repository.zoo.DefaultZooProvider
2020-07-15 01:14:15,763 DEBUG [ai.djl.rep.zoo.ModelZoo] (executor-thread-1) No model zoo found in zoo provider: ai.djl.repository.zoo.DefaultZooProvider
2020-07-15 01:14:15,763 DEBUG [ai.djl.rep.zoo.ModelZoo] (executor-thread-1) Checking ModelLoader: cv/image_classification ai.djl.tensorflow:resnet
Loading:     100% |████████████████████████████████████████|
2020-07-15 01:14:15,771 DEBUG [ai.djl.uti.cud.CudaUtils] (executor-thread-1) cudart library not found.
2020-07-15 01:14:15,771 DEBUG [ai.djl.ten.eng.LibUtils] (executor-thread-1) Using cache dir: /Users/ermurphy/.tensorflow/cache
2020-07-15 01:14:15,771 DEBUG [ai.djl.ten.eng.LibUtils] (executor-thread-1) Loading TensorFlow library from: /Users/ermurphy/.tensorflow/cache/2.2.0-cpu-osx-x86_64/libjnitensorflow.dylib
No Java runtime present, requesting install.

I then get a pop up window from Mac OS asking me to install Java 6! Weird, right?

Screen Shot 2020-07-15 at 1 25 43 AM

Update: Upon some research, I found this is related to JNI linking to Java libraries in Mac OS and it may require some change to how TensorFlow is linked, but I am not sure. I did not have this issue previously with the TensorFlow native libraries from the TensorFlow project.

@murphye
Copy link
Author

murphye commented Jul 15, 2020

As an alternative, I ran the Docker-based build using these commands:

./mvnw package -Pnative -Dquarkus.native.container-build=true
docker build -f src/main/docker/Dockerfile.native -t quarkus/pneumonia-detection-quarkus .
docker run -i --rm -p 8080:8080 quarkus/pneumonia-detection-quarkus
curl localhost:8080/detect

Unfortunately I get errors:

2020-07-15 06:01:19,597 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /detect failed, error id: d4d7e1b1-b0ae-4aee-a827-29c740ca3f3a-1: org.jboss.resteasy.spi.UnhandledException: java.nio.file.AccessDeniedException: /work/?
        at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
        at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:216)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:515)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at java.lang.Thread.run(Thread.java:834)
        at org.jboss.threads.JBossThread.run(JBossThread.java:479)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
Caused by: java.nio.file.AccessDeniedException: /work/?
        at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:389)
        at java.nio.file.Files.createDirectory(Files.java:689)
        at java.nio.file.Files.createAndCheckIsDirectory(Files.java:796)
        at java.nio.file.Files.createDirectories(Files.java:782)
        at ai.djl.repository.AbstractRepository.getCacheDirectory(AbstractRepository.java:153)
        at ai.djl.repository.RemoteRepository.locate(RemoteRepository.java:76)
        at ai.djl.repository.zoo.BaseModelLoader.getMetadata(BaseModelLoader.java:201)
        at ai.djl.repository.zoo.BaseModelLoader.search(BaseModelLoader.java:196)
        at ai.djl.repository.zoo.BaseModelLoader.match(BaseModelLoader.java:179)
        at ai.djl.repository.zoo.BaseModelLoader.loadModel(BaseModelLoader.java:78)
        at ai.djl.repository.zoo.ModelZoo.loadModel(ModelZoo.java:162)
        at com.example.ExampleResource.detect(ExampleResource.java:70)
        at java.lang.reflect.Method.invoke(Method.java:566)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:638)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:504)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:454)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:456)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:417)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
        ... 19 more

@frankfliu
Copy link
Contributor

frankfliu commented Jul 15, 2020

@murphye My college get the same 'No Java runtime present, requesting install." error on mac.
I can try your solution and take a look model loading issue.
I think the value of System.getProperty("user.home") is initialized at build time and the value is configured at "/work" in your docker, but this folder doesn't exist at runtime.

@frankfliu
Copy link
Contributor

After I added netty dependency and made some configuration change, I'm able to build native image. See my branch: https://github.com/frankfliu/djl-demo/blob/quarkus/pneumonia-detection-quarkus/src/main/resources/application.properties#L4-L9

However, it crash at runtime. The tensorflow share library is loaded successfully, DJL TfEngine is also loaded properly. But it hit segfault in javacpp.

@murphye
Copy link
Author

murphye commented Jul 17, 2020

Here are my last settings... give a try and see:

quarkus.native.enable-jni=true
quarkus.ssl.native=true

quarkus.native.additional-build-args=--report-unsupported-elements-at-runtime, -H:+TraceClassInitialization, --initialize-at-run-time=org.tensorflow\\,ai.djl\\,org.bytedeco

quarkus.log.category."ai.djl".level=DEBUG
quarkus.log.category."com.example".level=DEBUG

@frankfliu
Copy link
Contributor

@murphye I'm able to make PyTorch Engine work. See: deepjavalibrary/djl-demo#84

TensorFlow Engine is still crash at JNI level. I think it related to reflection at JNI code.

@murphye
Copy link
Author

murphye commented Jul 21, 2020

@frankfliu

  1. What other details can you provide on the error?
  2. How can I test on my end to resolve the error from EngineException when running in GraalVM Native Image #103 (comment)?
  3. Is there anything in this code that could be helpful?
    https://github.com/murphye/quarkus-tensorflow-inception/blob/master/src/main/java/io/quarkus/tensorflow/LoadTensorFlow.java

@frankfliu
Copy link
Contributor

DJL with tensorflow engine is work with quarkus now. see: https://github.com/aws-samples/djl-demo/tree/master/quarkus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants