4

I've done some searching, and it seems a few people have asked similar questions, but none of them were quite what I was looking for (some suggested some scripting stuff but i didn't have enough knowledge of what i was doing so i want to use java only if possible).

I need to be able to read lines of code from a String, and then execute them in Java (like this):

String code = "System.out.println(\"Test code\");";

A lot of people reading this post might ask why don't you just execute

System.out.println("Test code");

but I want to execute code other than the println method from Strings.

Is it possible to execute code using java alone, if so how would it compile??

Coder
  • 1,175
  • 1
  • 12
  • 32
  • 4
    write the string to a file.java, compile and run it... – Stav Alfi Aug 22 '17 at 14:57
  • You may also use java reflection to invoke methods without object creation. – nllsdfx Aug 22 '17 at 15:00
  • 1
    What for do you want to do this? – Herr Derb Aug 22 '17 at 15:00
  • @StavAlfi Yeah that might just work! however i would i run it? i dont want to have to javac it. Is there any way to run a text file from a program? – Coder Aug 22 '17 at 15:00
  • 2
    @JohnD nope, code always must be compiled. – nllsdfx Aug 22 '17 at 15:01
  • @HerrDerb I want to make a program where you type input into the console and the notepad is opened and what you typed is returned. Runtime.getRuntime().exec("notepad.exe"); r.keyPress(KeyEvent.VK_H); r.keyPress(KeyEvent.VK_I); – Coder Aug 22 '17 at 15:02
  • Also have a look at mbeans – nllsdfx Aug 22 '17 at 15:03
  • 1
    [This answer](https://stackoverflow.com/a/27396372/6069) may provide some pointers. – agnul Aug 22 '17 at 15:04
  • 1
    @JohnD So you actually just want to type in some strings and have them in a text file, which is opened with notepad? – Herr Derb Aug 22 '17 at 15:04
  • 1
    Use of [Java Compiler API](http://javabeat.net/the-java-6-0-compiler-api/) can help you here – mhasan Aug 22 '17 at 15:04
  • @HerrDerb yea and i use Thread.sleep(); to make it seem like someone is typing with no one there – Coder Aug 22 '17 at 15:06
  • @mhasan can you give me a code example of how i'd use the compiler api to run a program? – Coder Aug 22 '17 at 15:08
  • 2
    @JohnD as I understand you don't need to compile anything. You only want to input a string and have it "typed" 1to1 in notepad. Is that right? – Herr Derb Aug 22 '17 at 15:10
  • @JohnD Yor idea, snippet of code in comment can be done in many ways, depends on detail. You proposal seems big overdesign – Jacek Cz Aug 22 '17 at 15:16
  • Groovy language and its shells, consoles is very good solution of simmilar problems – Jacek Cz Aug 22 '17 at 15:17

3 Answers3

4

You can't do this as easily as I imagine you hope to. The kind of thing you're describing is something you might see in a dynamic language. Java is very much not a dynamic language - this is part of its character.

If you have tools.jar in your classpath, you can compile Java code from within your Java program:

com.sun.tools.javac.Main javac = new com.sun.tools.javac.Main();
String[] options = new String[] {
    "-classpath", classpath, "-d", outputDir, filename
};
javac.compile(options);

From there you could wrestle with the classloader, load the class you have compiled, and run it.

However this is not an easy or mainstream way to use Java, and generally people don't do it because it's neither good practice nor necessary. It is a security feature that you can't run code supplied by the user after compilation.


If you want a more dynamic language, in the Java ecosystem, you could look at Groovy.


Alternatively, you can run user-supplied Javascript, giving it controlled access to your Java program's data, using the Java Scripting API.

slim
  • 40,215
  • 13
  • 94
  • 127
  • 2
    Internal classes like com.sun ... is bad proposition, specially when official javax.tools.JavaCompiler exist – Jacek Cz Aug 22 '17 at 15:20
  • I don't have tools.jar in my classpath, i use IntelliJ how do i add it? – Coder Aug 22 '17 at 15:21
  • Full JDK (JRE has not this jar) – Jacek Cz Aug 22 '17 at 15:22
  • 2
    @JohnD Don't. I hoped to dissuade you in the body of the answer. It's difficult enough that you need to be experienced to do it. And once you're experienced you understand why it's not wise. – slim Aug 22 '17 at 15:23
1

It is possible but the java code cannot be executed as such, it's not interpreted, it needs to be compiled first. So you need to put your string into a main function of another java file, then compile it and finally run it.

You might need this : http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

Chamalo90
  • 76
  • 7
1

If I understand correct, you want to input a string into the java console. This given string then should be magically be typed-in in an external program. If I did not understand correct, I'll remove that answer again.

public class Test {

    public static void main(String[] args) throws IOException, ClassNotFoundException, Exception {
    Robot robot = new Robot();
    String text = "Hello";
    File file = File.createTempFile("tmp", ".txt");

    if (Desktop.isDesktopSupported()) {
        Desktop.getDesktop().edit(file);
        Thread.sleep(1000);
    } else {
        // dunno, up to you to handle this
    }
    for (char c : text.toCharArray()) {
        int keyEvent = KeyEvent.getExtendedKeyCodeForChar(c);
        robot.keyPress(keyEvent);
        Thread.sleep(500);
    }
    }
}

If you run this basic code, notepad should open and the text Hello is getting typed. That's what I've prepared for you. Now what you need to do is using a Scanner to get the string from the console instead from a static string.

Herr Derb
  • 4,977
  • 5
  • 34
  • 62