kamranzafar / JCL

Jar Class Loader, a configurable and dynamic custom classloader designed to create, manage and manipulate isolated Java classloaders in IoC frameworks and web applications.
http://kamranzafar.github.com/
579 stars 161 forks source link

ClassLoader order is broken #54

Open Aklakan opened 7 years ago

Aklakan commented 7 years ago

By default, JCL uses the local loader for loading classes. Hence, JCL will by default always prefer its own loader to load classes from the jar. However, this makes it impossible for the application code to pass arguments to dynamically loaded classes, as the arguments use the application's class loader, where as the dynamic class' method parameter types use the JCL class loader:

Let's assume these classes are both in the application code and the imported Jar:

class Engine { }
interface Car { void setEngine(Engine engine); }

Then this does not work:

JarClassLoader jcl = new JarClassLoader();
jcl.add("fancyCars.jar"); // Contains class FancyCar implements Car {}
Object o = factory.create(jcl, "FancyCar");
Car car = JclUtils.cast(o, Car.class);

Engine engine = new DefaultEngine(); // Create some engine

// This statement breaks:
car.setEngine(engine);

// Reason:
// engine.getClass().getClassLoader() uses the application's class loader, whereas
// the Engine class that appears as the parameter type of FancyCar::setEngine is loaded via JCL

Per documenation, a work around should be to simply use the local class loader last, however this leads to another required workaround:

jcl.getLocalLoader().setOrder(100);

// This is a workaround to force updating the internal order of loaders;
// as of jcl 2.9-SNAPSHOT, there is no e.g. jcl.updateLoaderOrder() method
// I suggest to introduce it.

jcl.addLoader(jcl.getLocalLoader()); // Adding a loader updates the order