Skip to content

Class made in eval can be used normally in that eval but can only be used by reflection in later eval #5

@benrayfield

Description

@benrayfield

System.out.println("java.version="+System.getProperty("java.version"));
System.out.println("java.runtime.name="+System.getProperty("java.runtime.name"));
ScriptEngine jshell = new JShellScriptEngine();
Bindings b = jshell.createBindings();
jshell.setBindings(b, ScriptContext.GLOBAL_SCOPE);
jshell.setBindings(b, ScriptContext.ENGINE_SCOPE);
long start = System.nanoTime();
jshell.eval("long kk = 0L; for(int i=0; i<100000000; i++) kk += i; System.out.println("kk="+kk); 20;");
double duration = (System.nanoTime()-start)*1e-9;
System.out.println("duration="+duration+" loopBodiesPerSec="+(1e8/duration));
Object xy = jshell.eval("class PairXY{ public final int x, y; public PairXY(int x, int y){ this.x = x; this.y=y; } public Object theT(){ return 9.87; } } Class PairXYClass = PairXY.class;");
System.out.println("PairXYClass: "+jshell.eval("PairXYClass"));
System.out.println("xy = "+xy);
System.out.println("xy.getClass() = "+xy.getClass());
Object mmB = jshell.eval("Object mmB = PairXYClass.getConstructor(int.class,int.class).newInstance(55,66);");
System.out.println("mmB = "+mmB);
System.out.println("mmB.getClass() = "+mmB.getClass());
double calledTheTByReflection = (Double) mmB.getClass().getMethod("theT").invoke(mmB);
System.out.println("calledTheTByReflection = "+calledTheTByReflection);

Outputs this...

java.version=11.0.2
java.runtime.name=OpenJDK Runtime Environment
kk=4999999950000000
duration=0.523169 loopBodiesPerSec=1.9114282382939357E8
PairXYClass: class REPL.$JShell$3$PairXY
xy = class REPL.$JShell$3$PairXY
xy.getClass() = class java.lang.Class
mmB = REPL.$JShell$3$PairXY@55b62629
mmB.getClass() = class REPL.$JShell$3$PairXY
calledTheTByReflection = 9.87

If "new PairXY(2,3)" is in the first eval, it works, but not if its in the second later evals. So I put its Class object in a jshell var so the later evals could see it and use by reflection, and it works, as you see theT called which returns 9.87.

Is there an easier way to keep classes across evals?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions