0

I have a java web application that comes wiht a abstract class, (lets call it ClassA) deployed on an application server. This java web application also loads classes from external jars dinamically, by using the approach on this question's accepted response.

Everything works fine, until I get to load a class (call it, ClassB) that extends from ClassA. I get a java.lang.ClassNotFoundException: ClassA error message on my SysOut, pointing to the line that loads the class: urlClassLoader.loadClass(className);.

I assumed I wouldn't have a problem, since when I call URLClassLoader.newInstance(), it gets created from the default parent class loader, which I suppose should be the SystemClassLoader, which I assume contains the WebApp classes.

  • Is any of my assumptions wrong?

  • How can I load a class from an external Jar, which happens to extend from a parent class loaded in the WebApplication classloader?

I tried changing the deployment configuration of my WebApp from parent first to parent last and got the same error. I also tried doing a Class.forName("ClassA") before executing the URLClassLoader.loadClass("ClassB") line but got the same error again.

Community
  • 1
  • 1
Roberto Linares
  • 2,215
  • 3
  • 23
  • 35
  • can you just pass ClassA.getClassLoader as a parent parameter to your custom class loader? – AdamSkywalker Mar 08 '16 at 20:50
  • Well, that actually solved my problem! That means, my URLClassLoader doesn't check in the SystemClassloader when I do a Class.forName()? Can I somewhat "merge" the two classloaders? – Roberto Linares Mar 08 '16 at 22:07
  • I suspect that your ClassA was loaded by webapp classloader (which is child of system classloader) and your UrlClassLoader is a child of system class loader also, so they are two leafs of the same parent. Not 100% sure because it depends on a web container you use. – AdamSkywalker Mar 08 '16 at 22:19
  • Ah, that makes sense. Thanks! I would suggest to post that as an answer and I will mark it as accepted. – Roberto Linares Mar 08 '16 at 22:32

1 Answers1

1

It seems that ClassA is loaded by some container's WebAppClassLoader which is a child of SystemClassLoader. Your custom URLClassLoader is a child of SystemClassLoader too and that's the reason why ClassB doesn't "see" ClassA.

To solve the problem, ClassB should be loaded by WebAppClassLoader or its child, it can be achieved with:

ClassLoader webAppCL = ClassA.class.getClassLoader();
URLClassLoader myCL = new URLClassLoader(urls, webAppCL);
AdamSkywalker
  • 11,408
  • 3
  • 38
  • 76