Netflix / conductor

Conductor is a microservices orchestration engine.
Apache License 2.0
12.83k stars 2.33k forks source link

Nashorn failing to generate bytecode not handled gracefully #1523

Open Valarin opened 4 years ago

Valarin commented 4 years ago

When WF contains Lambda task (code snippet No. 1) that fails to compile (code snippet No. 2) WF is not switched to FAILED status - it is kept in RUNNING status forever.

{
  "name": "LAMBDA_TASK",
  "taskReferenceName": "lambda_ref",
  "type": "LAMBDA",
  "inputParameters": {
    "preResultTasks": "['a', 'b']",
    "scriptExpression": "return ($.preResultTasks.find(task => task.name == 'a')) ? 'YES' : 'NO';"
  }
}
[ERROR] 2020-02-03 15:18:00,519 GenericExceptionMapper - Error AssertionError url: 'tasks'
java.lang.AssertionError: Failed generating bytecode for <eval>:1
  at jdk.nashorn.internal.codegen.CompilationPhase$BytecodeGenerationPhase.transform(CompilationPhase.java:431)
  at jdk.nashorn.internal.codegen.CompilationPhase.apply(CompilationPhase.java:624)
  at jdk.nashorn.internal.codegen.Compiler.compile(Compiler.java:655)
  at jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.compileTypeSpecialization(RecompilableScriptFunctionData.java:725)
  at jdk.nashorn.internal.runtime.RecompilableScriptFunctionData.getBest(RecompilableScriptFunctionData.java:905)
  at jdk.nashorn.internal.runtime.ScriptFunctionData.getBest(ScriptFunctionData.java:375)
  at jdk.nashorn.internal.runtime.ScriptFunctionData.getBestInvoker(ScriptFunctionData.java:237)
  at jdk.nashorn.internal.runtime.ScriptFunction.findCallMethod(ScriptFunction.java:871)
  at jdk.nashorn.internal.runtime.ScriptObject.lookup(ScriptObject.java:1825)
  at jdk.nashorn.internal.runtime.linker.NashornLinker.getGuardedInvocation(NashornLinker.java:104)
  at jdk.nashorn.internal.runtime.linker.NashornLinker.getGuardedInvocation(NashornLinker.java:98)
  at jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker.getGuardedInvocation(CompositeTypeBasedGuardingDynamicLinker.java:176)
  at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
  at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154)
  at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253)
  at jdk.nashorn.internal.scripts.Script$26$\^eval\_.:program(<eval>:1)
  at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
  at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
  at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
  at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
  at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
  at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
  at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
  at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
  at com.netflix.conductor.core.events.ScriptEvaluator.eval(ScriptEvaluator.java:52)
  at com.netflix.conductor.core.execution.tasks.Lambda.execute(Lambda.java:74)
  at com.netflix.conductor.core.execution.WorkflowExecutor.decide(WorkflowExecutor.java:979)
  at com.netflix.conductor.core.execution.WorkflowExecutor.decide(WorkflowExecutor.java:1014)
  at com.netflix.conductor.core.execution.WorkflowExecutor.completeWorkflow(WorkflowExecutor.java:652)
  at com.netflix.conductor.core.execution.WorkflowExecutor.decide(WorkflowExecutor.java:958)
  at com.netflix.conductor.core.execution.WorkflowExecutor.decide(WorkflowExecutor.java:1014)
  at com.netflix.conductor.core.execution.WorkflowExecutor.decide(WorkflowExecutor.java:1014)
  at com.netflix.conductor.core.execution.WorkflowExecutor.updateTask(WorkflowExecutor.java:895)
  at com.netflix.conductor.service.ExecutionService.updateTask(ExecutionService.java:204)
  at com.netflix.conductor.service.TaskServiceImpl.updateTask(TaskServiceImpl.java:137)
  at com.netflix.conductor.interceptors.ServiceInterceptor.invoke(ServiceInterceptor.java:52)
  at com.netflix.conductor.server.resources.TaskResource.updateTask(TaskResource.java:107)
  at sun.reflect.GeneratedMethodAccessor331.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
  at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
  at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
  at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
  at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
  at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
  at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
  at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
  at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
  at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
  at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
  at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
  at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
  at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
  at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:286)
  at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:276)
  at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:181)
  at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
  at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
  at com.netflix.conductor.server.JerseyModule$1.doFilter(JerseyModule.java:82)
  at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
  at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:120)
  at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:135)
  at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604)
  at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)
  at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
  at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1296)
  at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
  at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)
  at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
  at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1211)
  at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
  at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
  at org.eclipse.jetty.server.Server.handle(Server.java:500)
  at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:386)
  at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:562)
  at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:378)
  at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:270)
  at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
  at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
  at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
  at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
  at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
  at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
  at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
  at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:388)
  at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
  at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
  at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.AssertionError: jdk.nashorn.internal.ir.BinaryNode
  at jdk.nashorn.internal.codegen.CodeGenerator$2.enterDefault(CodeGenerator.java:1226)
  at jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor.enterBIND(NodeOperatorVisitor.java:744)
  at jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor.enterBinaryNode(NodeOperatorVisitor.java:137)
  at jdk.nashorn.internal.ir.BinaryNode.accept(BinaryNode.java:335)
  at jdk.nashorn.internal.codegen.CodeGenerator.loadExpression(CodeGenerator.java:857)
  ...
kishorebanala commented 4 years ago

@Valarin Thanks for reporting this. I'll mark this as a bug, and please let us know if you have resolved it meanwhile and could contribute.

beatfreaker commented 4 years ago

@Valarin @kishorebanala I might be wrong but I think below comment should solve this issue

I see that you are using Javascript arrow function, now as it is es6 feature and if we wan't to use it we have to enable it in nashorn while creating ScriptEngine by passing --language=es6

example:

NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine("--language=es6");

But ScriptEngine is not created in this way in ScriptEvaluator.Java

and even if we implement it, you have to run it on Java 9+ env, as arrow function within nashorn engine is not supported in Java 8

apanicker-nflx commented 4 years ago

@beatfreaker Thanks for helping debug this. In the long term, we plan to switch to Oracle GraalVM instead of Nashorn in the future versions of Conductor and will revisit this during the migration.