In order to schedule the execution of a job, i get the name of a class as a string-input.
This class may be in one of two packages, but i don't know which one so i have to check this.
By now, i have two try-catch-blocks
Class<Job> clazz;
String className; //the above mentioned string, will be initialized
try {
clazz = (Class<Job>) Class.forName("package.one." + className);
} catch (ClassNotFoundException ex) {
try {
clazz = (Class<Job>) Class.forName("package.two." + className);
} catch (ClassNotFoundException ex1) {
//some error handling code here, as the class is
//in neither of the two packages
}
}
For more packages this will get uglier and more unreadable. Furthermore, it is - for me - against the concept of exceptions, as exceptions should'nt be expected/used for flow-control!
Is there any way to rewrite this without the utilization of the ClassNotFoundException
?
You can use Guava's Reflection utilities to get the ClassInfo of every class loaded in the classpath.
In the loop you can implement your custom logic to load the class with the
className
you're providing.I'd stick to the
Class.forName
method for that.You can store the class and package names in
Collection
s orSet
s and loop through those elements. When you get aClassNotFoundException
, you just continue your search. If you don't get an exception, you exit the loop usingbreak
, as you have found the class you were looking for.The reason I'd go for
Class.forName
is that it loads the class for you if it had not been already loaded by the VM. This is quite a powerful side effect.It basically relieves you of the trouble of digging through the whole
CLASSPATH
and looking for class files to load in the VM and dealing with issues such as whether the class has already been loaded or not by the VM.EDIT:
Jakob Jenkov has written some really great articles/tutorials on Java. I've found them extremely useful when dealing with reflection, class loaders and concurrency (some of the "hardest" aspects of Java).
Here's a good article on the Java class loader by him, for if you still decide not to use
Class.forName
.In this case, I wouldn't worry about using the
ClassNotFoundException
. While in general a case can be made to not use exceptions for flow control, here it hardly counts as such.I'd probably wrap it in a function, like so
or return the class directly, if you so wish