加载运行时编译源时Java包类名格式错误
我有一个Java运行时编译器,如下所示:加载运行时编译源时Java包类名格式错误,java,classloader,jsr199,Java,Classloader,Jsr199,我有一个Java运行时编译器,如下所示: public class Compiler { private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); private final Map<String, String> source = new HashMap<String, String>(); private final MemoryFileManage
public class Compiler {
private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
private final Map<String, String> source = new HashMap<String, String>();
private final MemoryFileManager manager = new MemoryFileManager(this.compiler);
public void add(String classname, String fileContent) {
add(Collections.singletonMap(classname, fileContent));
}
public void add(Map<String, String> map) {
source.putAll(map);
}
public void compile() {
List<Source> list = new ArrayList<Source>();
for (Map.Entry<String, String> entry : source.entrySet()) {
list.add(new Source(entry.getKey(), JavaFileObject.Kind.SOURCE, entry.getValue()));
}
this.compiler.getTask(null, this.manager, null, null, null, list).call();
}
public byte[] getByteCode(String name) {
return this.manager.map.get(name).toByteArray();
}
}
我哪里出错了?aClass.getName()的结果是正确的。如果希望程序返回“TestClass”,应使用
aClass.getSimpleName()
我检查了
java.lang.Class.getPackage()
的源代码。它将调用Package.getPackage(this)
,在您的案例中调用class.getClassLoader().getPackage(“example.test”)
。由于SimpleClassLoader
具有重写方法受保护的类findClass(字符串名称)
,因此还应重写方法受保护的包getPackage(字符串名称)
并返回您体验的对象。示例。test包未定义,需要在compile方法中调用definePackage()
初始化:
public void compile() {
List<Source> list = new ArrayList<Source>();
for (Map.Entry<PackageClass, String> entry : source.entrySet()) {
list.add(new Source(entry.getKey().getCanonicalName(), JavaFileObject.Kind.SOURCE, entry.getValue()));
if(getPackage(entry.getKey().getPackage()) == null) {
definePackage(entry.getKey().getPackage(), null, null, null, null, null, null, null);
}
}
this.compiler.getTask(null, this.manager, null, null, null, list).call();
}
public void compile(){
列表=新的ArrayList();
对于(Map.Entry:source.entrySet()){
添加(新源(entry.getKey().getCanonicalName(),JavaFileObject.Kind.Source,entry.getValue());
if(getPackage(entry.getKey().getPackage())==null){
定义包(entry.getKey().getPackage(),null,null,null,null,null,null,null);
}
}
this.compiler.getTask(null,this.manager,null,null,null,list).call();
}
Ah,在通过definePackage()定义类时,我似乎还需要定义包
Compiler compiler = new Compiler();
String className = "example.test.TestClass";
String source = "package example.test; public class TestClass{}";
compiler.add(className, source);
compiler.compile();
byte[] byteCode = compiler.getByteCode(className);
Class<?> aClass = Class.forName(className, true, new SimpleClassLoader(className, byteCode));
System.out.println("Package: " + aClass.getPackage()); // Should be "example.text"
System.out.println("Name: " + aClass.getSimpleName()); // Should be "TestClass"
Package: null
Name: TestClass
public void compile() {
List<Source> list = new ArrayList<Source>();
for (Map.Entry<PackageClass, String> entry : source.entrySet()) {
list.add(new Source(entry.getKey().getCanonicalName(), JavaFileObject.Kind.SOURCE, entry.getValue()));
if(getPackage(entry.getKey().getPackage()) == null) {
definePackage(entry.getKey().getPackage(), null, null, null, null, null, null, null);
}
}
this.compiler.getTask(null, this.manager, null, null, null, list).call();
}