beanshell / beanshell

Beanshell scripting language
Apache License 2.0
815 stars 183 forks source link

Getting .class files #752

Open NeumimTo opened 4 months ago

NeumimTo commented 4 months ago

I would like to check what bytecode bsh actually generates. I found out that theres sys. property which can be used for this exact purpose - bsh.debugClasses

 public static void main(String[] a) throws Exception {
        File file = new File(".");
        System.setProperty("bsh.debugClasses", file.getAbsolutePath());

        BshScriptEngine engine = (BshScriptEngine) new BshScriptEngineFactory().getScriptEngine();

        CompiledScript compiledScript = engine.compile(script);
        Action action = (Action) compiledScript.eval();

        Interpreter interpreter = new Interpreter();
        action = (Action) interpreter.eval(script);

    }

I tried using Interpreter directly and scriptengine (which would be preferred way for me) to compile/execute bsh scripts. But none of these two approaches actually generated .class files within the dir i provided.

Im on 3.0.0 snapshot

NeumimTo commented 4 months ago

I did some more digging. There appears to be differences between implementing an interface and inheriting from a class.

The script which i was using was just

            return new Action() {
                public int run( str ) {
                    return str.hashCode();
                }
            }

The .class file was generated only when then Action was an abstract class. No .class file was generated for case when Action was an interface.

nickl- commented 4 months ago

This will require more in depth investigation, off hand I can say:

BeanShell only generates bytecode for virtual classes (bsh scripted classes, intefaces and enums) but uses compiled classes directly as found on the class path.

The class generation code is located in bsh.ClassGenerator which is also where the saveClasses method is which does the file persistence.

https://github.com/beanshell/beanshell/blob/2ffb8046ac3ff34f0ad53decd4c98df06c8ff419/src/main/java/bsh/ClassGenerator.java#L140-L148

It may be that we are not calling this for all instances.

Hope this helps, in the interim.

nickl- commented 4 months ago

This method is also not currently covered by unit tests, so it is very likely that you have discovered a bug where new features have not yet been included in the save class functionality.

Screenshot_20240103_122043

Your help with this will be very much appreciated.

nickl- commented 4 months ago

The issue #72 covers some documentation which may help with writing unit tests.