【问题标题】:Execute Java code that is stored in the database执行存储在数据库中的 Java 代码
【发布时间】:2014-11-30 18:34:24
【问题描述】:

我有定期推送到数据库的 Java 代码(解释为什么它在数据库中太复杂了,这只会将焦点从主要问题上转移)。

在运行时我查询数据库。我可以执行从数据库中获取的代码吗?我只是将 main 方法的内容存储在代码中。运行数据库的服务器是 HTTP 服务器。

数据库中的示例代码(仅供参考):

int i = 10;
int j = 2;
int k = i*j;
System.out.println("Result is " + k);

预期输出:

Result is 20

【问题讨论】:

  • 那么您的数据库是否包含源代码或/和字节码?
  • 您可以使用 db 中的代码动态构建一个 java 类,然后运行它。
  • @msrd0 - 这是源代码
  • @bsro05 - 请您提供参考/示例。 Tnx。
  • @user3760419 你存储完整的类吗?或者只有主要方法的内容?您是使用 HTTP 服务器还是如何访问您的数据库?

标签: java database dynamic


【解决方案1】:

任何 Java 程序都是正确的 Groovy 程序。因此,您可以将 Groovy 依赖项添加到您的项目中,然后使用 GroovyShell 执行您的代码:

GroovyShell shell = new GroovyShell();
shell.evaluate(code);

所以在你的情况下:

GroovyShell shell = new GroovyShell();
shell.evaluate("int i = 10;\n" +
        "int j = 2;\n" +
        "int k = i*j;\n" +
        "System.out.println(\"Result is \" + k);");

然后输出:

结果是 20

或者你可以使用ScriptEngineManager(更常用的方式):

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("groovy");
engine.eval("int i = 10;\n" +
        "int j = 2;\n" +
        "int k = i*j;\n" +
         "System.out.println(\"Result is \" + k);");

但无论如何,您需要将 Groovy 添加到您的依赖项中。

【讨论】:

    【解决方案2】:

    您可以构建 java 源代码,然后使用反射加载 java 类。因此,向您的 HTTP Server 添加一个新的 Servlet,将其命名为 getJar,并将以下内容放入 doGet 方法中(假设您已经创建了 DB 连接):

    File tmp = File.createTempFile("java-code-", ".java");
    PrintWriter out = new PrintWriter(new FileWriter(tmp), true);
    String classname = tmp.getName().substring(0, tmp.getName().length()-5);
    out.println("public class " + classname);
    out.println("{");
    out.println("    public static void executeCode ()");
    out.println("    {");
    out.println(connection.executeQuery("SELECT java-code FROM yourDb WHERE name='"
            + request.getParameter("name").replace("'", "''") + "';");
    out.println("    }");
    out.println("}");
    out.close();
    Runtime.getRuntime().exec("javac \"" + tmp.getAbsolutePath() + "\"").waitFor();
    Runtime.getRuntime().exec("jar cfe \"" + tmp.getAbsolutePath() + ".jar\" \""
             + classname + "\" \"" + tmp.getAbsolutePath() + "\"");
    InputStream in = new InputStream(new FileInputStream(tmp.getAbsolutePath() + ".jar"));
    int read; byte[] buf = new byte[4096];
    while ((read = in.read(buf)) != null)
        response.getOutputStream().write(buf, 0, read);
    in.close();
    

    现在,你可以接收它并为它创建一个ClassLoader,然后执行它:

    ClassLoader cl = new URLClassLoader("http://localhost/getJar?name=whatever");
    Class c = cl.loadClass(classname);
    c.getMethod("executeCode").invoke(null);
    

    【讨论】:

      猜你喜欢
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 2014-11-16
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多