在运行时加载 java 代码

Loading java code at runtime

我有一个小项目,我必须计算一个列表。计算取决于服务因素。 关键是这些因素会不时发生变化,应该允许用户自行更改。

到目前为止,这些因素是硬编码的,如果不重新编译代码就无法进行任何更改。

目前代码如下所示:

    if (someStatement.equals("someString")) {
        computedList.remove("something");
        }

我的想法是制作一个可编辑且人类可读的文本文件、配置文件等,在运行时/启动时加载?此文件应包含上面的 java 代码。

知道怎么做吗?请注意:目标 PC 没有安装 JDK,只有 JRE。

解决此问题的一种有效方法是使用静态初始化程序。 Static Block in Java 可以在link.

下找到一个简洁明了的解释

此处允许这样做的一个选项是使用 swing API 中的用户输入对话框 - 然后您可以将用户答案存储在变量中并将它们导出到文本 file/config 文件,或者直接在程序中使用它们而不保存它们。您只需在程序的最开始弹出输入对话框,然后再发生任何其他事情,然后程序将 运行 基于这些响应。

您可以使用 Javascript 作为配置文件语言,而不是 java。 Java 7 SE 及更高版本包括可以从 Java 调用的 a javascript interpreter。使用起来并不难,你可以将 java 个对象注入到 javascript 环境中。

基本上,您将创建一个 Java 脚本环境,将 java 对象插入其中,配置文件将配置该对象,然后 运行 配置文件作为java脚本。

好的,开始吧...我找到了一个非常简单的解决方案来解决我的问题。 我正在使用 Codehaus (Link) 的 Janino。这个库有一个集成的 Java 编译器,似乎像 Java 7 中的 JavaCompiler class 一样工作。 但是没有安装 JDK。

通过 Janino,您可以在运行时加载和编译 *.java 文件(人类可读),这正是我所需要的。

我认为他们主页上的示例和代码片段很痛苦,所以这是我自己的实现:

第一步是使用您的 Java 文件具有的在运行时加载的相同方法实现接口:

public interface ZuordnungInterface {

public ArrayList<String> Zuordnung(ArrayList<String> rawList);}

然后在需要 class:

时调用 Janino classloader
File janinoSourceDir = new File(PATH_TO_JAVAFILE);
    File[] srcDir = new File[] { janinoSourceDir };
    String encoding = null;
    ClassLoader parentClassLoader = this.getClass().getClassLoader();
    ClassLoader cl = new JavaSourceClassLoader(parentClassLoader, srcDir,
            encoding);

并创建一个新实例

ZuordnungsInterface myZuordnung = (ZuordnungInterface) cl.loadClass("zuordnung")
                .newInstance();

注意:加载的class名为zuordnung.java,所以调用时不需要扩展cl.loadClass("zuordnung")

最后 class 我想在我的程序运行时加载和编译,它可以位于您想要的任何位置 (PATH_TO_JAVAFILE):

public class zuordnung implements ZuordnungInterface {
public ArrayList<String> Zuordnung(ArrayList<String> rawList){

    ArrayList<String> computedList = (ArrayList<String>) rawList.clone();

    if (Model.getSomeString().equals("Some other string")) {
        computedList.add("Yeah, I loaded an external Java class");
    }


    return computedList;
}}

就是这样。希望对遇到类似问题的人有所帮助!