Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I control which ClassLoader loads a class?
    text
    copied!<p>The situation at hand is not as simple as the title seems to indicate.</p> <p>Java 1.6_17 running via JWS.</p> <p>I have a class, lets say <code>MyClass</code> and one of its instance member variables is a Type from an errant 3rd party library where during class initialization it dynamically tries loading some of its own classes with <code>Class.forName(String)</code>. In one of these cases it happens to dynamically call: <code>Class.forName("foo/Bar")</code>.This class name doesn't follow the JLS for binary names and ultimately leads to a <code>java.lang.NoClassDefFoundError: foo/Bar</code>.</p> <p>We have a custom <code>ClassLoader</code> which I've added a sanitize method to <code>ClassLoader.findClass(String)</code> and <code>ClassLoader.loadClass(String)</code> which fixes this problem.</p> <p>I can call stuff like: <code>myCustomClassLoader.findClass("foo/Bar")</code></p> <p>Which then loads the class without any problems. But even if I load the class ahead of time, I still get the exception later. This is because during initialization of <code>MyClass</code> which refers to <code>Bar</code> - <em>their</em> code ends up calling <code>Class.forName("foo/Bar")</code> in a static block somewhere. This actually would be OK if the ClassLoader it was trying to use was my custom class loader. But it isn't. It is the <code>com.sun.jnlp.JNLPClassLoader</code> which doesn't do such sanitation, thus my problem.</p> <p>I've made sure that <code>Thread.currentThread().getContextClassLoader()</code> is set to my custom class loader. But this (as you know) has no effect. I even set it as the first thing i do in <code>main()</code> due to some stuff I read and still, <code>MyClass.class.getClassLoader()</code> - is the JNLPClassLoader. If I could force it to NOT be the JNLPClassLoader and to use mine instead, problem solved.</p> <p>How can I control which ClassLoader is used to load the class via their static Class.forName("foo/Bar") call made during class initialization? I believe if I can force <code>MyClass.class.getClassLoader()</code> to return my custom class loader, my problem will be resolved.</p> <p>I'm open to other options if anyone has ideas.</p> <p>TL;DR: Help me force all <code>Class.forName(String)</code> calls in a third party library which are referenced by <code>MyClass</code> - to use the classloader of my choosing.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload