This approach works without problems when using only a single classloader. But the classloaders in java form a hierachy. If the same class is loaded in two different classloaders, the classes are of different type.
Therefor hansel creates its own shadow hierachy. For each classloader used in the hierachy, a modifying classloader is created.
Unfortunatly there still is a problem: When a new Classloader is created it delegates the calls to loadClass() to the system classloader. This causes problems, because these classes are not type compatible with the classes loaded by hansels modifying classloader.
Depending on wether this is happpening in your own code, or a third party library there are different ways of dealing with this problem.
classloader = org.hansel.ClassloaderFactory.wrappClassLoader(classloader);This works regardless of the code being run from a coverage test or in a "normal" environment. But since having references to hansel in production code is perhaps not such a good idea, you probably want to do this in a classloader factory, which can be exchanged, depending on the situation.
ignorepackages= third.party.package., sun.,java.,javax.,junit., org.hansel.ProbeTableInterface, org.hansel.ClassLoaderFactoryInterface
CoverageDecorator cd = new CoverageDecorator(new Class[] {your.tested.Class.class},
new String[] {"third.party.package"},
true);
In some rare cases, this does not help. These cases occur when code, that is not loaded using the modifying classloader, loads classes, that have to be modified. This happens for example, when objects are created by parsing a xml file.
In these cases you can only hope, that the developers of the third party code have included a possibility to set the classloader, that is used to load the classes.
The following list contains the classes, that are known to cause problems, and (if possible) workarounds. If you find libraries, that are not included in this list, please tell me about them.
Product/Library | Workaround |
---|---|
Apache Digester |
After creating a new Digester, set the classloader:
Digester digester = new Digester(); digester.setClassLoader(getClass().getClassLoader()); |
WebLogic RMI |
In the setUp() method of the test set the context classloader:Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
and set it back to the old value in the tearDown() method.
|