Run piece of code contained in a String

JavaReflection

Java Problem Overview


I have a piece of Java code in a String.

String javaCode = "if(polishScreenHeight >= 200 && " +
    "polishScreenHeight <= 235 && polishScreenWidth >= 220) { }";

Is it possible to convert this Java String to a Java statement and run it? Possibly using Java reflection?

Java Solutions


Solution 1 - Java

As has already been suggested you can compile, save and run code on the fly using the Compiler API.

Another neat alternative would be to use beanshell. Beanshell is no longer actively developed, but I can vouch for it's reliability, I've used it successfully in multiple production projects.

Solution 2 - Java

Use BeanShell. There's a page on how to use it from Java.

Solution 3 - Java

Beanshell (as Boris suggested) is a way to "execute" java source code. But it looks like, you want to "execute" fragments that can interact with the compiled classes. Your example contains variabe names.

Reflection will definitly not help, because reflection targets classes ("classfiles").

You could try to define a complete class ("valid java source file"), compile it and load it (url classloader). Then you should be able to use the methods from that "live generated class". But once a class is loaded, you can't get rid of it (unload), so this will work only once (AFAIK).

Solution 4 - Java

As far as I know there is no simple way to do this.

However, in Java 6 onwards, you can compile source code for complete classes using javax.tools.Compiler. The compiled classes can then be loaded and executed. But I don't think this will achieve what you want.

Solution 5 - Java

Another way would be to execute your code as Groovy code, see this for an example.

Solution 6 - Java

you can use this code to run method from using this code new Statement(Object target, String methodName, Object[] arguments).execute();

import java.beans.Statement;

public class HelloWorld {

  public void method_name(String name) {
      System.out.println(name);
  }

  public static void main(String[] args) throws Exception {
      HelloWorld h = new HelloWorld();
      new Statement(h, "method_name", new Object[]{"Hello world"}).execute();
  }
 }

Solution 7 - Java

Try the JavaCompiler API.

Someone else answered this way better than I could, though: https://stackoverflow.com/questions/935175/convert-string-to-code-in-java

Be careful before actually using something like this...

Solution 8 - Java

It is not Java, but as pgras has already suggested you could use GrooyScript like so :

    Binding binding = new Binding();
    GroovyShell shell = new GroovyShell(binding);
    
    String[] strings = new String[]{"World", "Groovy"};
    shell.setVariable("args", strings);
    
    String script = "return \"Hello \" + args[1]";
    String value = (String) shell.evaluate(script);
    System.out.println(value); // Hello Groovy

Solution 9 - Java

  1. Please reevaluate your design and this should be your last alternative.
  2. You should validate the sanity of the String which will be executed to avoid future injection attack.

Now If you can have the String as JavaScript then below code should help,

public class EvalScript {

	    public static void main(String[] args) throws Exception {
	        // create a script engine manager
	        ScriptEngineManager factory = new ScriptEngineManager();
	        // create a JavaScript engine
	        ScriptEngine engine = factory.getEngineByName("JavaScript");

	        // below JS function is executed.
	        /*
	         * student object value will be provided by the program as the JSON String.
			function checkStudentElgibility(student){
			  if(student.age >= 10 && student.currentGrade >= 5){
			    return true;
			  }
			}
			// student object value will be provided by the program as the JSON String
			
			checkStudentElgibility(student);
	        */
	        
	        String studentJsonString = "{\n" + 
	        		"  \"age\" : 10,\n" + 
	        		"  \"currentGrade\" : 5\n" + 
	        		"}";
	        String javaScriptFunctionString = "function checkStudentElgibility(student){\n" + 
	        		"  if(student.age >= 10 && student.currentGrade >= 5){\n" + 
	        		"    return true;\n" + 
	        		"  }\n" + 
	        		"}\n" + 
	        		"checkStudentElgibility(student);";
	        
	        StringBuilder javaScriptString = new StringBuilder();
	        javaScriptString.append("student=");
		        javaScriptString.append(studentJsonString);
	        javaScriptString.append("\n");
	        javaScriptString.append(javaScriptFunctionString);
	        
	       Object object = engine.eval(javaScriptString.toString());
	  
	       System.out.println(object);

           // You can also pass the object as follows,

           // evaluate JavaScript code that defines an object with one method
            engine.eval("var obj = new Object()");
            engine.eval("obj.hello = function(name) { print('Hello, ' + name) 
              }");

           // expose object defined in the script to the Java application
             Object obj = engine.get("obj");

         // create an Invocable object by casting the script engine object
            Invocable inv = (Invocable) engine;

      // invoke the method named "hello" on the object defined in the
     // in js Object with "Script Method" as parameter 
         
               inv.invokeMethod(obj, "hello", "Script Method!");





    // You can also use Java Objects as Java script object and you can also pass Objects as reference inside Java script function


              		        String jsString = "    var obj = new Object()\n" + 
		        		"    var ArrayList = Java.type(\"java.util.ArrayList\");\n" +
		        		"    var customSizeArrayList = new ArrayList(16);\n" + 
		        		"    obj.hello = function(name) { \n" + 
		        		"       customSizeArrayList(name);	\n" + 
		        		"       print('Hello, ' + name) \n" + 
		        		"    }";
		    }
		    
	    
}

 

Reference : https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/prog_guide/javascript.html#A1147187

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionblue-skyView Question on Stackoverflow
Solution 1 - JavaJoelView Answer on Stackoverflow
Solution 2 - JavaBoris PavlovićView Answer on Stackoverflow
Solution 3 - JavaAndreas DolkView Answer on Stackoverflow
Solution 4 - JavaSteve McLeodView Answer on Stackoverflow
Solution 5 - JavapgrasView Answer on Stackoverflow
Solution 6 - JavaLasitha LakmalView Answer on Stackoverflow
Solution 7 - JavaMikeView Answer on Stackoverflow
Solution 8 - JavaJonas_HessView Answer on Stackoverflow
Solution 9 - JavaPeruView Answer on Stackoverflow