Reputation: 683
I'm using Play for Java and I tried this in my Application.java
// The name of the class to search
String className = "my.fake.company.SuperGreatClass";
Reflections reflections = new Reflections("", new SubTypesScanner(false));
// All classes
Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);
for (Class c : allClasses){
String cName = c.getName();
// Find the class that matches the name to the one we are looking for
if (cName.contains(className))
play.Logger.info(cName); // It always succeeds and logs the name correctly
}
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try {
Class clazz = classLoader.loadClass(className);
Constructor constructor = clazz.getConstructor();
} catch (Exception e) {
play.Logger.error("NOT FOUND: " + e.getMessage());
return badRequest("Cannot find that super great class of yours!");
}
The reflections part correctly identifies my class, but the ClassLoader does not. Unfortunately, I use a third party library that uses the second approach and I cannot change it.
Is there something I can do to change the behaviour of the ClassLoader? I have found this answer but I am not sure if this will work.
The log output is:
2016-02-19 16:00:17 +0200 [INFO ] from application in application-akka.actor.default-dispatcher-3 - - my.fake.company.SuperGreatClass
2016-02-19 16:00:18 +0200 [ERROR] from application in application-akka.actor.default-dispatcher-3 - - NOT FOUND: my.fake.company.SuperGreatClass
Upvotes: 2
Views: 3834
Reputation: 7630
Please have a read about classloaders hierarchy in Java and the contract they follow. This article is one of many describing the loaders hierarchy
In your code you ask System Classloader to load your class. That means that It will only be Bootstrap and System classloaders being queried for your class.
To increase the search area simply invoke
this.getClass().getClassLoader().loadClass(className);
... which should return your class.
Upvotes: 1