i have java runtime compiler follows:
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>(); (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(); } }
and accompanying example simple classloader:
public class simpleclassloader extends classloader { private string classname; private byte[] bytecode; public simpleclassloader(string classname, byte[] bytecode) { super(simpleclassloader.class.getclassloader()); this.classname = classname; this.bytecode = bytecode; } @override protected class<?> findclass(string name) throws classnotfoundexception { if(name.equals(classname)){ return defineclass(name, bytecode, 0, bytecode.length); } return super.findclass(name); } }
when compiling , loading class, resulting class's package name concatenated class name:
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 "example.text" system.out.println("name: " + aclass.getsimplename()); // should "testclass"
the output of unexpectedly following:
package: null name: testclass
where going wrong here?
the result of aclass.getname()
correct. if want program return "testclass", should use aclass.getsimplename()
.
i check source code of java.lang.class.getpackage()
. invoke package.getpackage(this)
invoke class.getclassloader().getpackage("example.test")
in case. because simpleclassloader
has override method protected class findclass(string name)
, should override method protected package getpackage(string name)
, return object expeceted.
Comments
Post a Comment