classpath - Parent Last Classloader to solve Java Class path hell? -


i have project uses 2 versions of bouncycastle jars bcprov-jdk15 , bcprov-jdk16. jvm loads older version there feature wrote needs newer version run. tried solve classpath hell using custom class loader. after googling , of previous stackoverflow answers[1] [2] , blog, wrote following parent last class loader load classes newer jar before delegating parent class loader.

public class parentlastclassloader extends classloader {      private string jarfile; //path jar file     private hashtable classes = new hashtable(); //used cache defined classes      public parentlastclassloader(classloader parent, string path)     {         super(parent);         this.jarfile = path;     }      @override     public class<?> findclass(string name) throws classnotfoundexception     {         system.out.println("trying find");         throw new classnotfoundexception();     }      @override     protected synchronized class<?> loadclass(string classname, boolean resolve) throws classnotfoundexception     {         system.out.println("trying load");         try         {             system.out.println("loading class in child : " + classname);             byte classbyte[];             class result = null;              //checks in cached classes             result = (class) classes.get(classname);             if (result != null) {                 return result;             }              try {                 jarfile jar = new jarfile(jarfile);                 jarentry entry = jar.getjarentry(classname + ".class");                 inputstream = jar.getinputstream(entry);                 bytearrayoutputstream bytestream = new bytearrayoutputstream();                 int nextvalue = is.read();                 while (-1 != nextvalue) {                     bytestream.write(nextvalue);                     nextvalue = is.read();                 }                  classbyte = bytestream.tobytearray();                 result = defineclass(classname, classbyte, 0, classbyte.length, null);                 classes.put(classname, result);                 return result;             } catch (exception e) {                 throw new classnotfoundexception(classname + "not found", e);             }         }         catch( classnotfoundexception e ){              system.out.println("delegating parent : " + classname);             // didn't find it, try parent             return super.loadclass(classname, resolve);         }     } } 

i loaded main class in feature class loader bouncycaslte classes used in feature not loaded custom classloader.

classloader loader = new parentlastclassloader(thread.currentthread().getcontextclassloader(), pathtojar); class myclass = loader.loadclass("mainclassofthefeature"); method mainmethod = myclass.getmethod("mainmethod"); mainmethod.invoke(myclass.getconstructor().newinstance()); 

jvm still uses classes loaded older version. how can make jvm load classes class loader when running feature , use loaded older classes in older jar when feature not running?

edit: problem remains after setting custom classloader thread context classloader in mainmethod of feature main class.

thread.currentthread().setcontextclassloader(this.getclass().getclassloader()); 

i managed solve problem. modified code of parentlastclassloader array of all jarfile paths needed feature. when class loaded, jarfiles needed feature searched .class files. if class file cannot found, delegated parent.

    private  class parentlastclassloader extends classloader {      private string[] jarfiles; //paths jar files     private hashtable classes = new hashtable(); //used cache defined classes      public parentlastclassloader(classloader parent, string[] paths)     {         super(parent);         this.jarfiles = paths;     }      @override     public class<?> findclass(string name) throws classnotfoundexception     {         system.out.println("trying find");         throw new classnotfoundexception();     }      @override     protected synchronized class<?> loadclass(string classname, boolean resolve) throws classnotfoundexception     {         system.out.println("trying load");         try         {             system.out.println("loading class in child : " + classname);             byte classbyte[];             class result = null;              //checks in cached classes             result = (class) classes.get(classname);             if (result != null) {                 return result;             }              for(string jarfile: jarfiles){                 try {                     jarfile jar = new jarfile(jarfile);                     jarentry entry = jar.getjarentry(classname.replace(".","/") + ".class");                     inputstream = jar.getinputstream(entry);                     bytearrayoutputstream bytestream = new bytearrayoutputstream();                     int nextvalue = is.read();                     while (-1 != nextvalue) {                         bytestream.write(nextvalue);                         nextvalue = is.read();                     }                      classbyte = bytestream.tobytearray();                     result = defineclass(classname, classbyte, 0, classbyte.length, null);                     classes.put(classname, result);                 } catch (exception e) {                     continue;                 }             }              result = (class) classes.get(classname);             if (result != null) {                 return result;             }             else{                 throw new classnotfoundexception("not found "+ classname);             }         }         catch( classnotfoundexception e ){              system.out.println("delegating parent : " + classname);             // didn't find it, try parent             return super.loadclass(classname, resolve);         }     } } 

the parentlastclassloader instantiated follows.

classloader loader = new parentlastclassloader(thread.currentthread().getcontextclassloader(), paths); 

once parentlastclassloader instantiated, mainclassofthefeature loaded , mainmethod invoked.


Comments

Popular posts from this blog

html5 - What is breaking my page when printing? -

c# - must be a non-abstract type with a public parameterless constructor in redis -

ajax - PHP/JSON Login script (Twitter style) not setting sessions -