Menu

#45 Inner-inner classes not covered

open
None
4
2004-09-23
2004-09-23
No

An inner-inner class is not instrumented. The reason is
the superfluous if (....$...) in ModifyingClassLoader.
A test case showing the problem is in the attachment:
The methods in the inner-inner classes should be shown
as not-covered.

... I'll repair this together with the categories, which I
hopefully will check in in a few days (after much more
testing).

Discussion

  • Harald M. Mueller

     
  • Nobody/Anonymous

    Logged In: NO

    Hi there,

    has there been any progress on a solution for this problem?
    We are currently facing this issue and would like to get it
    resolved.

    Also, does the solution also address the instrumenting of
    anonymous inner-classes?

    Thanks

    Sam
    sfraser@peace.com

     
  • Nobody/Anonymous

    Logged In: NO

    The checked-in sources have this repaired. However, the
    build does at the moment not work for the checked-in
    sources [Hansel is, unfortunately, a low-activity project for
    all team-members ... ... ...].

    But you can repair the problem by simply removing the line

    if (clazz.getClassName().indexOf("$") == -1) {

    and the corresponding } from
    ModifyingClassLoader.modifyClass() - this will do the trick.
    Anonymous inner classes are handled exactly as other inner
    classes, as hansel works on byte-code and does - liek the
    JVM - not know the difference between anonymous and non-
    anonymous classes: After the compiler, all classes have
    names.

    Regards
    Harald

     
  • Sam

    Sam - 2004-12-15

    Logged In: YES
    user_id=1179120

    Hi Harald,

    I made the change you outlined below but still not getting
    my anonymous innerclasses insturmented.

    It appears that the innerclass constractor is being
    instrumented but not the methods within the class. Below are
    snippets of my code, if you or any of the other developers
    get a chance to take a look, that would be much appreciated.

    public abstract class ValidatorCommand {
    public abstract boolean isValid(String value, boolean
    isBlankOrNull);

    protected boolean validate() {
    boolean isValid = true;
    try {
    String value = ValidatorUtils.getValueAsString(getBean(),
    getField().getProperty());
    isValid = isValid(value,
    GenericValidator.isBlankOrNull(value));
    } catch (NestedNullException nne) {
    log.debug("Ignoring nested path exception", nne);
    }

    if(!isValid){
    log.debug(validatorName + " rejecting value " +
    bean.getClass().getName() + "." + field);
    }
    return isValid;
    }

     
  • Sam

    Sam - 2004-12-15

    Logged In: YES
    user_id=1179120

    Bugger! sorry about the post below... i pressed some special
    key combination and submitted the form by mistake. Here's
    the code from the top. Note that I have change the
    implementation of the isValid method in CommonsValidator so
    that there is a branching condition.

    /* FIRST CLASS: a command object with an abstract isValid
    method that is implemented by the annonymous innerclass in
    the second class below. */
    public abstract class ValidatorCommand {
    ....
    public abstract boolean isValid(String value, boolean
    isBlankOrNull);

    protected boolean validate() {
    boolean isValid = true;
    try {
    String value = ValidatorUtils.getValueAsString(getBean(),
    getField().getProperty());
    isValid = isValid(value,

    GenericValidator.isBlankOrNull(value));
    } catch (NestedNullException nne) {
    log.debug("Ignoring nested path exception", nne);
    }

    if(!isValid){
    log.debug(validatorName + " rejecting value " +

    bean.getClass().getName() + "." + field);
    }
    return isValid;
    }
    }

    /* SECOND CLASS: constracts a ValidatorCommand as an
    anonymous innerclass, implementing the isValid method */
    public class CommonsValidator {
    ....
    public static boolean validateRequired(Object bean,
    Field field) {
    ValidatorCommand vc = new ValidatorCommand("required",
    bean, field) {
    public boolean isValid(String value, boolean
    isBlankOrNull) {
    if (isBlankOrNull) {
    return true;
    } else {
    return false;
    }
    }
    };

    return vc.validate\(\);
    

    }
    }

    Many thanks,

    Sam

     
  • Harald M. Mueller

    Logged In: YES
    user_id=484627

    You are, unfortunately, very right: Simply removing the if is
    not enough. You must, in the current state of affairs, also
    state that you want to cover the inner class. The only
    possibility I found at the moment is to do something like:

    public static Test suite() throws ClassNotFoundException {
    return new CoverageDecorator
    (TestInnerClassesALittle.class,
    new Class[] { Class.forName
    ("org.hanseltest.CommonsValidator$1") });
    }

    It's not nice because you have to know the name of the inner
    class; and you have to use Class.forName() to pass the Class
    object to the coverage decorator.

    Hope this helps for the moment!
    Regards
    Harald

     

Log in to post a comment.

MongoDB Logo MongoDB