Remove folder from Java classpath at runtime -
is there way remove folder classpath similar adding folder @ runtime (can directory added class path @ runtime?)
please find below snippet technical example demonstrate adding / removing path.
create following source files in directory
import java.io.file; import java.lang.reflect.field; import java.lang.reflect.method; import java.net.url; import java.net.urlclassloader; import java.util.stack; import sun.misc.urlclasspath; public class evilpathdemo { public static void addpath(string path) throws exception { url u = new file(path).touri().tourl(); urlclassloader urlclassloader = (urlclassloader) classloader.getsystemclassloader(); class<?> urlclass = urlclassloader.class; method method = urlclass.getdeclaredmethod("addurl", new class[]{url.class} ); method.setaccessible(true); method.invoke(urlclassloader, new object[]{u}); } public static void removepath(string path) throws exception { url url = new file(path).touri().tourl(); urlclassloader urlclassloader = (urlclassloader) classloader.getsystemclassloader(); class<?> urlclass = urlclassloader.class; field ucpfield = urlclass.getdeclaredfield("ucp"); ucpfield.setaccessible(true); urlclasspath ucp = (urlclasspath) ucpfield.get(urlclassloader); class<?> ucpclass = urlclasspath.class; field urlsfield = ucpclass.getdeclaredfield("urls"); urlsfield.setaccessible(true); stack urls = (stack) urlsfield.get(ucp); urls.remove(url); } public static void main(string[] args) throws exception { string parm = args.length == 1 ? args[0] : ""; string evilpath = "/tmp"; string classpath = system.getproperty("java.class.path"); boolean isevilpathset = false; (string path : classpath.split(file.pathseparator)) { if (path.equalsignorecase(evilpath)) { system.out.printf("evil path '%s' in classpath%n", evilpath); isevilpathset = true; break; } } if (isevilpathset && parm.equalsignorecase("remove")) { system.out.printf("evil path '%s' removed%n", evilpath); removepath(evilpath); } trytoload("foo"); if (parm.equalsignorecase("add")) { system.out.printf("evil path '%s' added%n", evilpath); addpath(evilpath); } trytoload("bar"); } private static void trytoload(string classname) { try { class<?> foo = class.forname(classname); system.out.printf("class loaded: %s%n", foo.getname()); } catch (classnotfoundexception ex) { system.out.println(ex); } } }
.
public class foo { static { system.out.println("i'm foo..."); } }
.
public class bar { static { system.out.println("i'm bar..."); } }
compile them follow
javac evilpathdemo.java javac -d /tmp foo.java bar.java
during test try load classes foo
, bar
.
without /tmp in classpath
java -cp . evilpathdemo java.lang.classnotfoundexception: foo java.lang.classnotfoundexception: bar
adding /tmp classpath
java -cp . evilpathdemo add java.lang.classnotfoundexception: foo evil path '/tmp' added i'm bar... class loaded: bar
with /tmp in classpath
java -cp .:/tmp evilpathdemo evil path '/tmp' in classpath i'm foo... class loaded: foo i'm bar... class loaded: bar
remove /tmp classpath
java -cp .:/tmp evilpathdemo remove evil path '/tmp' in classpath evil path '/tmp' removed java.lang.classnotfoundexception: foo java.lang.classnotfoundexception: bar
during testing found out following cases not working.
- addpath(evilpath);
trytoload("foo");
removepath(evilpath); // had not effect
trytoload("bar"); - removepath(evilpath);
trytoload("foo");
addpath(evilpath); // had no effect
trytoload("bar"); - trytoload("foo");
removepath(evilpath); // had no effect
trytoload("bar");
i did not spent time find out why. because don't see practical use in it. if need/wish play classpaths have how classloaders working.
Comments
Post a Comment