Search code examples
javabeanshell

Java-Beanshell: Run methods from within beanshell without class reference


I am a newbie to BeanShell and learning it. Currently, I have below code to get user input as a string and then evaluate it using BeanShell eval method.

package beanshell;

import bsh.EvalError;
import bsh.Interpreter;

public class DemoExample {

    public static void main( String [] args ) throws EvalError  {
        Interpreter i = new bsh.Interpreter();
        String usrIp = "demoExmp.printValue(\"Rohit\");";

        i.eval(""
                + "import beanshell.DemoExample;"
                + "DemoExample demoExmp = new beanshell.DemoExample();"
                + ""+usrIp);
    }

    public static void printValue(String strVal){
        System.out.println("Printing Value "+strVal);
    }
}

But expectation is - user should not provide class reference and code should run fine. So user input value is as below:

String usrIp = "printValue(\"Rohit\");";

Please help.


Solution

  • Cool, we can achieve this using reflection as below.

    package beanshell;
    
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    
    import bsh.EvalError;
    import bsh.Interpreter;
    
    public class Demo_Eval {
        public static Interpreter i = new Interpreter();
    
        public static void main(String[] args) throws FileNotFoundException, IOException, EvalError, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
            String userInput = "printValue()";
    
            Object result = i.eval(""
                    + "public class EvalUserInput extends beanshell.Demo_Eval{"
                    + "public static void getUserInput(){"
                    + userInput+";"
                    + "}"
                    + "}");
    
            Class<?> noparams[] = {};
            Class cls = (Class) result;
            Object obj = cls.newInstance();
            cls.getDeclaredMethod("getUserInput", noparams).invoke(obj, null);
        }
    
        public static void printValue(){
            System.out.println("Printed");
        }
    }