Run a simple text file as Java

后端 未结 3 449
忘了有多久
忘了有多久 2021-01-17 23:50

I have a simple .txt file which has pure Java code inside it like

   public class C {
      public static void main(String[] args ) {
        System.out.prin         


        
相关标签:
3条回答
  • 2021-01-18 00:20

    You can use the javax.tools api form Java 6 to compile the code on the fly. However since your extension is illegal it will complain with a error: C.txt Class names are only accepted if annotation processing is explicitly requested.

    To get around this (as mentioned in the comments) you must first load the code into a String and then execute it:

    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileObject;
    import javax.tools.SimpleJavaFileObject;
    import javax.tools.ToolProvider;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.net.URI;
    import java.util.Iterator;
    import java.util.NoSuchElementException;
    
    public class MyCompiler2 {
        public static void main(String[] args) throws Exception {
            String program = "";
            try {
                BufferedReader in = new BufferedReader(new FileReader("C.txt"));
                String str;
                while ((str = in.readLine()) != null) {
                    program += str;
                }
                in.close();
            } catch (IOException e) {
            }
    
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            Iterable<? extends JavaFileObject> fileObjects;
            fileObjects = getJavaSourceFromString(program);
    
            compiler.getTask(null, null, null, null, null, fileObjects).call();
    
            Class<?> clazz = Class.forName("C");
            Method m = clazz.getMethod("main", new Class[]{String[].class});
            Object[] _args = new Object[]{new String[0]};
            m.invoke(null, _args);
        }
    
        static Iterable<JavaSourceFromString> getJavaSourceFromString(String code) {
            final JavaSourceFromString jsfs;
            jsfs = new JavaSourceFromString("code", code);
            return new Iterable<JavaSourceFromString>() {
                public Iterator<JavaSourceFromString> iterator() {
                    return new Iterator<JavaSourceFromString>() {
                        boolean isNext = true;
    
                        public boolean hasNext() {
                            return isNext;
                        }
    
                        public JavaSourceFromString next() {
                            if (!isNext)
                                throw new NoSuchElementException();
                            isNext = false;
                            return jsfs;
                        }
    
                        public void remove() {
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }
    }
    
    class JavaSourceFromString extends SimpleJavaFileObject {
        final String code;
    
        JavaSourceFromString(String name, String code) {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.code = code;
        }
    
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }
    

    Notice how you need to explicitly provide the method and class name in order for reflection to execute your code.

    0 讨论(0)
  • 2021-01-18 00:30

    Check out this thread for how to start the compile from within Java...

    How to set the source for compilation by a CompilationTask

    0 讨论(0)
  • 2021-01-18 00:47

    I think I'd start with BeanShell, which allows you to compile and execute Java source held in a string.

    0 讨论(0)
提交回复
热议问题