java:运行时编译继承class
java: compile inheriting class at runtime
我目前正在为我的大学做一个项目。
我开发的应用程序允许用户在文本区域中键入 java 方法。然后,应用程序将这些方法放入 class 中,并应在用户点击编译按钮时对其进行编译。
到目前为止,我使用的是这种方法:
一开始它对我有用,但它只能编译一个简单的(独立的)class。我必须在运行时编译的 class 从应用程序扩展了另一个 class。
通过这种方式,用户应该可以访问我实现的超级 class 中的某些方法。
这是我用来编译 class:
的方法
public Class<?> loadClass(String filename) {
WorkingDirectory workingDirectory = WorkingDirectory.getInstance();
File directory = workingDirectory.getCompileDirectory();
File javaFile = workingDirectory.createJavaFileFromUserProgram(filename);
Class<?> cls = null;
try {
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, javaFile.getPath());
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { directory.toURI().toURL() });
cls = Class.forName(filename, true, classLoader);
} catch (Exception e) {
e.printStackTrace();
}
return cls;
}
这适用于不扩展任何内容的 class。当我添加扩展时,我得到了这个错误信息:
error: cannot find symbol
public class UsersClass extends ExistingClass { public void main() {
^
symbol: class ExistingClass
1 error
java.lang.ClassNotFoundException: UsersClass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at utils.SimulatorClassloader.loadClass(SimulatorClassloader.java:51)
at simulator.Simulator.lambda(Simulator.java:171)....
有人知道我在方法中需要 add/change 什么吗?我做了几个小时的研究,但从那以后我没有取得任何进展。
我没有识别出一些错误,但是通过 LKTN.25 提示我找到了它们。
首先:UsersClass 在导入部分有错字。
这个错误消失后又出现了另一个错误。
其次:我的基础 class 没有默认构造函数,子 class 也没有。并且 subclass 没有覆盖其他构造函数。因此无法创建 subclass 的实例。
显然 "Does someone know what I need to add/change in my method?" 不是正确的问题。错误在别处。
更新:
我以为我必须在用户 class 中插入一个构造函数,因为我无法在运行时创建实例。
用户 class 根本不需要构造函数(像往常一样 java)。它从超级 class.
中获取
显然以下代码段不起作用。
Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle());
try {
Method method = cls.getMethod("main");
try {
method.invoke(cls.newInstance());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
但是这个(稍微修改过的代码)确实有效:
Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle());
try {
Method method = cls.getMethod("main");
try {
Object obj = cls.newInstance();
method.invoke(obj);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
我目前正在为我的大学做一个项目。 我开发的应用程序允许用户在文本区域中键入 java 方法。然后,应用程序将这些方法放入 class 中,并应在用户点击编译按钮时对其进行编译。
到目前为止,我使用的是这种方法:
一开始它对我有用,但它只能编译一个简单的(独立的)class。我必须在运行时编译的 class 从应用程序扩展了另一个 class。 通过这种方式,用户应该可以访问我实现的超级 class 中的某些方法。 这是我用来编译 class:
的方法 public Class<?> loadClass(String filename) {
WorkingDirectory workingDirectory = WorkingDirectory.getInstance();
File directory = workingDirectory.getCompileDirectory();
File javaFile = workingDirectory.createJavaFileFromUserProgram(filename);
Class<?> cls = null;
try {
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, javaFile.getPath());
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { directory.toURI().toURL() });
cls = Class.forName(filename, true, classLoader);
} catch (Exception e) {
e.printStackTrace();
}
return cls;
}
这适用于不扩展任何内容的 class。当我添加扩展时,我得到了这个错误信息:
error: cannot find symbol
public class UsersClass extends ExistingClass { public void main() {
^
symbol: class ExistingClass
1 error
java.lang.ClassNotFoundException: UsersClass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at utils.SimulatorClassloader.loadClass(SimulatorClassloader.java:51)
at simulator.Simulator.lambda(Simulator.java:171)....
有人知道我在方法中需要 add/change 什么吗?我做了几个小时的研究,但从那以后我没有取得任何进展。
我没有识别出一些错误,但是通过 LKTN.25 提示我找到了它们。
首先:UsersClass 在导入部分有错字。 这个错误消失后又出现了另一个错误。
其次:我的基础 class 没有默认构造函数,子 class 也没有。并且 subclass 没有覆盖其他构造函数。因此无法创建 subclass 的实例。
显然 "Does someone know what I need to add/change in my method?" 不是正确的问题。错误在别处。
更新: 我以为我必须在用户 class 中插入一个构造函数,因为我无法在运行时创建实例。 用户 class 根本不需要构造函数(像往常一样 java)。它从超级 class.
中获取显然以下代码段不起作用。
Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle());
try {
Method method = cls.getMethod("main");
try {
method.invoke(cls.newInstance());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
但是这个(稍微修改过的代码)确实有效:
Class<?> cls = new SimulatorClassloader().loadClass(this.simulatorGUI.getStageTitle());
try {
Method method = cls.getMethod("main");
try {
Object obj = cls.newInstance();
method.invoke(obj);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}