我有经常被推送到数据库的Java代码(解释为什么它在数据库中太复杂了,这只会把焦点从主要问题转移开来。)
在运行时我查询数据库。我可以执行从数据库中获取的代码吗?我只在代码中存储main方法的内容。运行数据库的服务器是HTTP服务器。
数据库中的示例代码(仅供参考):
int i = 10;
int j = 2;
int k = i*j;
System.out.println("Result is " + k);
预期产出:
Result is 20
答案 0 :(得分:4)
任何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添加到您的依赖项中。
答案 1 :(得分:0)
您可以构建java源代码,然后使用反射加载java类。因此,将新的Servlet添加到HTTP服务器,将其命名为getJar
,并将以下内容放在doGet
方法中(假设您已经创建了数据库连接):
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);