classloader - Malformed Java package class name while loading runtime-compile source -


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