0

I am unable to create ScriptEngine for nashorn in Java 8 (IBM J9JVM). In the following code, the engine is null.

private static void runOther(String[] args){
    ScriptEngineManager engineManager = new ScriptEngineManager();
    ScriptEngine engine = engineManager.getEngineByName("nashorn");
    engine.eval("function sum(a, b) { return a + b; }");
}

This failure is introduced by my library, which performs bytecode generation for MethodHandle in java.lang.invoke package. The changes in my library are:

  1. the change are only for the standard java.lang.invoke package. None is changed for nashorn.
  2. When nashorn is about to set a call site's target with Methodhandle target, my library will transform the target into another method handle b, if the target is created from GuardWithTestHandle and set the call site's target to b. Both 'targetandb` has the same method type.

My last version of the library was completed in Oct 2016 and it was OK for Nashorn. But the new version I built has the WrongMethodTypeException when executing getEngineByName. This exception was handled inside of getEngineByName and null is returned.

The nashorn source code I got is not consist with the nashorn.jar in JVM. During the debug, what I found was that the exception was from:

global = createNashornGlobal();

inside of NashornScriptEngine.<init>. After digesting deep, the exception was thrown when doing MethodHandle invocation at UserAccessorProperty (line318)

/*     */   public Object getObjectValue(ScriptObject self, ScriptObject owner)
/*     */   {
/*     */     try {
/* 215 */       return invokeObjectGetter(getAccessors(owner != null ? owner : self), getObjectGetterInvoker(), self);  //owner and self are the same instance. 
/*     */     } catch (Error|RuntimeException t) {
/* 217 */       throw t;
/*     */     } catch (Throwable t) {
/* 219 */       throw new RuntimeException(t);
/*     */     }
/*     */   }


/*     */   private static Object invokeObjectGetter(Accessors gs, MethodHandle invoker, Object self)
/*     */     throws Throwable
/*     */   {
/* 316 */     Object func = getter;
/* 317 */     if ((func instanceof ScriptFunction)) {
/* 318 */       return invoker.invokeExact(func, self);
/*     */     }
/*     */     
/* 321 */     return ScriptRuntime.UNDEFINED;
/*     */   }

At line 318, the invoker is MutableCallSiteDynamicInvokerHandle and its method type is (Object,Object)Object. Both func and self are declared as Object object here and types of parameters and return value are matched completely.

I can not understand this exception, and have no idea next steps for this issue. Thanks if you can provide some ideas and suggestion for the issue here? Or some options/configurations..

See stacks Debug screen shot for stack.

shijie xu
  • 1,975
  • 21
  • 52
  • can you post the stacktrace? It should be something like `expected`... but `found`... Also the code for `getEngineByName` would help – Eugene Mar 11 '17 at 02:01
  • Thanks @Eugene, do you have way to set `jdk.nashorn.internal.runtime.Context.DEBUG` to be true? This field is false as default, and Nashorn does not print call stack if DEBUG is false. – shijie xu Mar 11 '17 at 12:02
  • no I don't. You also make little sense of what *actually* you changed, or *what jvm you run in into* or even the source code of `getEngineByName`. Even the description where you say : `bytecode generation for MethodHandle` is a bit confusing. So.. can you post the code and explain exactly where it worked and where it does not – Eugene Mar 11 '17 at 12:23
  • The code is large and I add two explanations here – shijie xu Mar 11 '17 at 13:13
  • [I can only repeat myself: I don’t think that it is a good idea…](http://stackoverflow.com/questions/38986780/java-bytecode-variable-index-0s-classname-is-something-strange#comment65400242_38986780). Really, you have hacked into some crucial lowlevel JRE facility and get unexpected results and expect *us* to tell you what’s going on, without even knowing, what you have changed? – Holger Mar 13 '17 at 13:26
  • @Holger, I agree that it is not reasonable to ask the issue when I replaced some default standard Java class, and did not provide details of my modification. I am doing an experiment, which adds million of code to the standard Java package and makes it is hard to paste code here. Anyway, I would try my best to explain my change. Thanks – shijie xu Mar 14 '17 at 14:06

0 Answers0