I tried to replace our Factory class that returns classes by string name using reflection with a CDI-based method.
So I put an @Inject @Any Instance<IData> possibleCandidates as a class variable. Then in the getIDataInstanceByClassname(String className) I’m creating an instance via Class.forName and compare it to every instance in the possibleCandidates list to then return a matching “injectable” instance.
However accessing possibleCandidates ends up in a NullPointerException. Whether I start a for loop or use possibleCandidates.iterator(). However, inspecting the variable does not return null but InstanceImpl<T> filled with various values.
How come accessing it produces a NPE?
Some code:
@Instance
@Any
private Instance<IData> possibleCandidates;
public IData getClassByClassname( String className ) {
try {
Class<?> clazz = Class.forName( className );
Iterator<IData> it = possibleCandidates.iterator(); // NPE gets thrown here
while ( it.hasNext() ) {
IData dataInstance = it.next();
if ( dataInstance.getClass().equals( clazz ) ) {
return dataInstance;
}
}
}
catch( Exception e ) { ... }
}
There was one class in that list, that produced a NullPointerException at construction time which caused any access to the Instance list to fail. I could not see the cause of the NPE in the Debugging mode, but when I added some logging, the underlying reason was clear.
So, remember kids: Always rethrow exceptions in the catch block or dome something with it. But never throw a different exception without putting the original exception as the cause into it.