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

Error while building blaze #772

Closed
asm0dey opened this issue Nov 3, 2018 · 3 comments
Closed

Error while building blaze #772

asm0dey opened this issue Nov 3, 2018 · 3 comments
Assignees

Comments

@asm0dey
Copy link

asm0dey commented Nov 3, 2018

It will be awesome to build blaze (https://github.com/fizzed/blaze) with native image because it would make possible to create blazingly fast shell-like experience of scripting in java.

But currently jar can't be built because of exception

Build on Server(pid: 8027, port: 46161)*
[blaze:8027]    classlist:   1,532.52 ms
[blaze:8027]        (cap):     867.66 ms
[blaze:8027]        setup:   2,242.02 ms
[blaze:8027]     analysis:  31,178.64 ms
2 fatal errors detected:
fatal error: java.lang.IndexOutOfBoundsException: index -1
        at java.util.concurrent.atomic.AtomicReferenceArray.checkedByteOffset(AtomicReferenceArray.java:78)
        at java.util.concurrent.atomic.AtomicReferenceArray.get(AtomicReferenceArray.java:125)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldTypeStore(AnalysisObject.java:213)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldFlow(AnalysisObject.java:199)
        at com.oracle.graal.pointsto.flow.LoadFieldTypeFlow$LoadInstanceFieldTypeFlow.onObservedUpdate(LoadFieldTypeFlow.java:159)
        at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:347)
        at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:389)
        at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:508)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:174)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        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)
fatal error: java.lang.IndexOutOfBoundsException: index -1
        at java.util.concurrent.atomic.AtomicReferenceArray.checkedByteOffset(AtomicReferenceArray.java:78)
        at java.util.concurrent.atomic.AtomicReferenceArray.get(AtomicReferenceArray.java:125)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldTypeStore(AnalysisObject.java:213)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldFlow(AnalysisObject.java:199)
        at com.oracle.graal.pointsto.flow.LoadFieldTypeFlow$LoadInstanceFieldTypeFlow.onObservedUpdate(LoadFieldTypeFlow.java:159)
        at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:347)
        at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:389)
        at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:508)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:174)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        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: Processing image build request failed
@cstancu
Copy link
Member

cstancu commented Nov 6, 2018

Thank you for your report. I was able to reproduce and isolate the issue. We will have a fix soon.

@cstancu
Copy link
Member

cstancu commented Feb 21, 2019

The error reporting in this case has been improved. Instead of an IndexOutOfBoundsException you should now get:

Error: Field jdk.nashorn.internal.runtime.ScriptFunction.data is not present on type java.lang.Object. Error encountered while analysing jdk.nashorn.internal.runtime.ScriptFunction.invoke(java.lang.Object, java.lang.Object[]) 
Parsing context:
	parsing jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
	parsing jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
	parsing jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
	parsing jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
	parsing jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
	parsing javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
	parsing com.fizzed.blaze.nashorn.BlazeNashornEngine.queryScriptFunctions(BlazeNashornEngine.java:106)
	parsing com.fizzed.blaze.nashorn.BlazeNashornEngine.init(BlazeNashornEngine.java:65)
	parsing com.fizzed.blaze.core.Blaze$Builder.compileScript(Blaze.java:315)
	parsing com.fizzed.blaze.core.Blaze$Builder.build(Blaze.java:326)
	parsing com.fizzed.blaze.cli.Bootstrap.buildBlaze(Bootstrap.java:211)
	parsing com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:140)
	parsing com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:54)
	parsing com.fizzed.blaze.cli.Bootstrap.main(Bootstrap.java:42)
	parsing com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:152)
	parsing com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_5087f5482cc9a6abc971913ece43acb471d2631b(generated:0)

The error is due to a call to the MethodHandle adapter java.lang.invoke.LambdaForm$MH.1106314392.invokeExact_MT(Ljava/lang/Object;, Ljava/lang/Object;, Ljava/lang/Object;) generated by HotSpot for the INVOKEVIRTUAL java/lang/invoke/MethodHandle.invokeExact (Ljdk/nashorn/internal/runtime/ScriptObject;)Ljdk/nashorn/internal/runtime/ScriptFunction; bytecode. The adapter method has all the static type information erased, and, from the point of view of the static points-to analysis, can return any of the types seen as instantiated in the system. Since there is not enough type information the analysis cannot apply any type narrowing and it later tries to access a field on a super type that doesn't declare it. In this case, the JVM ensures type safety through dynamic type checking, but we don't have access to any of that information during image building unless the MethodHandle object is a constant.

The native-image MethodHandle support is limited to cases where the MethodHandle object is a compile time constant. In that case we can constant fold and recursively inline until we get to a concrete method invocation. There is more work to be done to gracefully recover when we find a non-constant MethodHandle argument during image build time and report the problem at runtime instead.

The underlying problem here is that the blaze uses nashorn which makes heavy use of MethodHandles. Thus, native-image cannot support nashorn. What would be interesting would be to refactor blaze to use Graal.js instead.

@cstancu
Copy link
Member

cstancu commented Mar 15, 2019

We now disable the nashorn engine in native-image. When you build an image with native-image --language:js ... the Graal.js engine is included and returned by new ScriptEngineManager().getEngineByName("js"). This fix will be available in RC14 which should come out soon.

Now, using native-image -H:IncludeResources='.*/bundled.txt$' --language:js --allow-incomplete-classpath -jar blaze-lite-0.18.0.jar I can successfully build a native image of blaze. However, when I run it I get

$ ./blaze-lite-0.18.0 blaze.js 
[INFO] Resolving dependencies...
[INFO] Resolved dependencies in 0 ms
[INFO] Compiling script...
[ERROR] The Nashorn scripting engine is not supported by native-image due to its use of invokedynamic. The native-image static analysis runs under a closed-world assumption which requires that all called methods and their call sites are known ahead-of-time, whereas invokedynamic can introduce calls at run time or change the method that is invoked. Therefore, only specific use cases of invokedynamic are supported, namely when the invokedynamic can be reduced to a single virtual call or field access during native image generation.
com.oracle.svm.core.jdk.UnsupportedFeatureError: The Nashorn scripting engine is not supported by native-image due to its use of invokedynamic. The native-image static analysis runs under a closed-world assumption which requires that all called methods and their call sites are known ahead-of-time, whereas invokedynamic can introduce calls at run time or change the method that is invoked. Therefore, only specific use cases of invokedynamic are supported, namely when the invokedynamic can be reduced to a single virtual call or field access during native image generation.
	at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:102)
	at jdk.nashorn.api.scripting.NashornScriptEngineFactory.getScriptEngine(NashornScriptEngineFactory.java:40)
	at javax.script.ScriptEngineManager.getEngineByName(ScriptEngineManager.java:238)
	at com.fizzed.blaze.nashorn.BlazeNashornEngine.init(BlazeNashornEngine.java:58)
	at com.fizzed.blaze.core.Blaze$Builder.compileScript(Blaze.java:315)
	at com.fizzed.blaze.core.Blaze$Builder.build(Blaze.java:326)
	at com.fizzed.blaze.cli.Bootstrap.buildBlaze(Bootstrap.java:211)
	at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:140)
	at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:54)
	at com.fizzed.blaze.cli.Bootstrap.main(Bootstrap.java:42)

It looks like blaze is trying to use nashorn directly: ScriptEngine scriptEngine = this.scriptEngineManager.getEngineByName("nashorn");. Please try using the js engine descriptor.

I am closing this issue as the original problem has been resolved.

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