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

JSR 223 different behaviour between compiled execution and evaluated #5876

Open
andsel opened this issue Sep 13, 2019 · 2 comments

Comments

@andsel
Copy link

commented Sep 13, 2019

Environment

Provide at least:

  • JRuby version (jruby -v) and command line (flags, JRUBY_OPTS, etc)
    jruby-9.2.8.0
  • Operating system and platform (e.g. uname -a)
    Linux 5.0.0-27-generic #28-Ubuntu SMP Tue Aug 20 19:53:07 UTC 2019 x86_64 x86_64
    x86_64 GNU/Linux
    JVM: OpenJDK 12.0.2

Other relevant info you may wish to add:

  • Installed or activated gems
  • Application/framework version (e.g. Rails, Sinatra)
  • Environment variables

Expected Behavior

Both eval invoked on ScriptEngine and on CompiledScript prints same value of local variable

  • Describe your expectation of how JRuby should behave, perhaps by showing how CRuby/MRI behaves.
    Both ways of execution should output the same string

  • Provide an executable Ruby script or a link to an example repository.
    NB put the tests in two separate unit test or run one at a time

@Test
public void testEvaluateCompiled() throws ScriptException {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("jruby");

    Bindings bindings = new SimpleBindings();
    bindings.put("message", "my variable");

    CompiledScript compiled = ((Compilable) engine).compile("puts \">>>>>>\" + message");
    compiled.eval(bindings);
}

@Test
public void testEvaluateInterpreted() throws ScriptException {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("jruby");

    Bindings bindings = new SimpleBindings();
    bindings.put("message", "my variable");

    engine.eval("puts \">>>>>>\" + message", bindings);
}

Actual Behavior

  • Describe or show the actual behavior.
    the test testEvaluateCompiled fails with error while the other print correctly the string >>>>>>global variable

  • Provide text or screen capture showing the behavior.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules (file:/home/andrea/.gradle/caches/modules-2/files-2.1/org.jruby/jruby-complete/9.2.8.0/2dbdff9d9f4142e4a0bc2b743ded9487a80459ef/jruby-complete-9.2.8.0.jar) to field java.io.FileDescriptor.fd
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
NameError: undefined local variable or method `message' for main:Object
  <main> at <script>:1



javax.script.ScriptException: org.jruby.embed.EvalFailedException: (NameError) undefined local variable or method `message' for main:Object

	at org.jruby.embed.jsr223.JRubyCompiledScript.wrapException(JRubyCompiledScript.java:103)
	at org.jruby.embed.jsr223.JRubyCompiledScript.eval(JRubyCompiledScript.java:92)
	at org.jruby.embed.jsr223.JRubyCompiledScript.eval(JRubyCompiledScript.java:77)
	at org.logstash.log.Log4jRubyScriptingTest.testEvaluateCompiled(Log4jRubyScriptingTest.java:42)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.jruby.embed.EvalFailedException: (NameError) undefined local variable or method `message' for main:Object
	at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:131)
	at org.jruby.embed.jsr223.JRubyCompiledScript.eval(JRubyCompiledScript.java:86)
	... 24 more
Caused by: org.jruby.exceptions.NameError: (NameError) undefined local variable or method `message' for main:Object
	at RUBY.<main>(<script>:1)
@headius

This comment has been minimized.

Copy link
Member

commented Sep 16, 2019

Huh yeah that doesn't seem right. I wonder if it's something to do with how it's compiling the code? Like perhaps it's compiling message as a method call since there's no context to indicate it's a variable, while the eval version sees it in the binding and makes it a variable access...

@andsel

This comment has been minimized.

Copy link
Author

commented Sep 16, 2019

@headius I give you just little more context, I'm using this code to run as a Script element in Log4j2 and I can't change the way the variables are declared because it's done by Log4J itself.
Having eval and compiled works in the same way, identifying the message as a variable could be a great thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.