Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

CachedClassMirrors.classForName should defer to loaded class objects first, then to cached class mirrors. #13

Closed
tstockwell opened this Issue Oct 23, 2012 · 1 comment

Comments

Projects
None yet
2 participants

While weaving, Kilim was giving me an erroneous error that a method in a base class was not pausable.
I discovered that the Detector.getPausableStatus method erroneous reported that the method in question was not pausable.
I also discoverd that the Detector.getPausableStatus method determines if an exception type is Pausable by comparing it to an instance of ClassMirror, like so...


    ClassMirror c = classForName(ex);
    if (PAUSABLE.isAssignableFrom(c)) {
        return PAUSABLE_METHOD_FOUND;
    }

The source of the problem was that PAUSABLE.isAssignableFrom(c) returned false for the exception type declared by the method in question.
That is, Kilim used the isAssignableFrom method to determine if the method throws an exception of type Pausable, and the PAUSABLE.isAssignableFrom(c) returned false when passed a ClassMirror instance that represented Pausable.

I eventually determined that the reason for this was that the instance of Pausable used in the Detector.getPausableStatus method, 'PAUSABLE ', was an instance of a RuntimeClassMirror, and the instance passed to it was an instance of CachedClassMirror.
I also eventually determined that this was so because the CachedClassMirrors.classForName method returned cached classed before returning runtime classes. Here is the old version of the CachedClassMirrors.classForName method, notice that the code doesnt do what the comment in it says it should do....


public ClassMirror classForName(String className)
        throws ClassMirrorNotFoundException {
    // defer to loaded class objects first, then to cached class mirrors.
    ClassMirror ret = cachedClasses.get(className); 

    if (ret == null) {
        ret = delegate.classForName(className);
    }
    if (ret == null) {
        throw new ClassMirrorNotFoundException(className);
    }
    return ret;
}

I changed the above code to this and my problems were solved...


public ClassMirror classForName(String className)
        throws ClassMirrorNotFoundException {
    // defer to loaded class objects first, then to cached class mirrors.
    ClassMirror ret = delegate.classForName(className);

    if (ret == null) {
        ret = cachedClasses.get(className); 
    }
    if (ret == null) {
        throw new ClassMirrorNotFoundException(className);
    }
    return ret;
}
Owner

kilim commented Oct 28, 2012

Fixed in commit 125d6f8

@kilim kilim closed this Oct 28, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment