views:

89

answers:

3

Hi,

Is there a way in using externally stored sourcecode and loading it into a Java programm, so that it can be used by it?

I would like to have a program that can be altered without editing the complete source code and that this is even possible without compiling this every time. Another advantage is, that I can change parts of the code like I want.

Of course I have to have interfaces so that it is possible to send data into this and getting it back into the fixed source program again.

And of course it should be faster than a pure interpreting system.

So is there a way in doing this like an additional compiling of these external source code parts and a start of the programm after this is done?

Thank you in advance, Andreas :)

A: 

Java6 has a scripting API. I've used it with Javascript, but I believe you can have it compile external Java code as well.

http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/

Edit: Here is a more relevant link: http://blogs.sun.com/sundararajan/entry/dynamic%5Fsource%5Fcode%5Fin%5Fjava

Kevin O'Donnell
Java != JavaScript. The real answer covers under each `javax.tools` API and a (custom) `ClassLoader`.
BalusC
The original question specified "externally stored sourcecode". Last time I checked classloaders don't compile sourcecode into bytecode.
Kevin O'Donnell
+1  A: 

In Java 6 or later, you can get access to the compiler through the javax.tools package. ToolProvider.getSystemJavaCompiler() will get you a javax.tools.JavaCompiler, which you can configure to compile your source. If you are using earlier versions of Java, you can still get at it through the internal com.sun.tools.javac.Main interface, although it's a lot less flexible.

ataylor
+4  A: 

You need the javax.tools API for this. Thus, you need to have at least the JDK installed to get it to work. Here's a basic kickoff example (without proper exception and encoding handling just to make the basic example less opaque, cough):

public static void main(String... args) throws Exception {
    String source = "public class Test { static { System.out.println(\"test\"); } }";

    File root = new File("/test");
    File sourceFile = new File(root, "Test.java");
    Writer writer = new FileWriter(sourceFile);
    writer.write(source);
    writer.close();

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    compiler.run(null, null, null, sourceFile.getPath());

    URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
    Class<?> cls = Class.forName("Test", true, classLoader);
}

This should print test in stdout, as done by the static initializer in the test source code. Further use would be more easy if those classes implements a certian interface which is already in the classpath. Otherwise you need to involve the Reflection API to access and invoke the methods/fields.

BalusC