I have come into a situation where I want to conditionally load and resolve a class.
Loading it is as easy as getting a handle to the correct ClassLoader
and calling the loadClass
method. after calling the loadClass
method, I get a valid handle to the class I wanted to load. However, the target class' static intializers are not getting invoked because the class is not being resolved until later. Unfortunately, the classes static initializers register important callbacks. An example of this is shown below.
public class ClassA
{
public static void main(String[] args) throws Throwable
{
Class<?> classB = ClassA.class.getClassLoader().loadClass("ClassB");
System.out.println(classB.getName());
}
}
public class ClassB
{
static
{
System.out.println("Class B initializer.");
}
}
The output of running ClassA in this example is of course:ClassB
I have found a temporary workaround which is (in my opinion) a bit of a hack
and that is to call an unimportant static function in ClassB
which forces the the class to be resolved. This method is shown below.
public class ClassA
{
public static void main(String[] args) throws Throwable
{
Class<?> classB = ClassA.class.getClassLoader().loadClass("ClassB");
classB.getMethod("something").invoke(null);
System.out.println(classB.getName());
}
}
public class ClassB
{
static
{
System.out.println("Class B initializer.");
}
public static void something(){}
}
The output from this method is (as expected):
Class B Initializer.
ClassB
This method has many problems with it such as I have to depend on the class having a public static function, and worry about any side effects of calling that function. Is there a more legitimate way to force classes to resolve?