Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyzer missing hook to filter classes using Agent includes/excludes settings #930

Open
systemsplanet-zz opened this issue Aug 29, 2019 · 2 comments

Comments

@systemsplanet-zz
Copy link

org.jacoco.core.analysis.Analyzer should include a way to skip (short circuit) analyzing classes based on
the values used by the JaCoCo agent's includes and excludes settings.
Otherwise Reports coverage is incorrectly calculated when directories containing Jars are analyzed (unless you manually explode the jars and exclude classes yourself). I've solved this issued using the change below:

private void analyzeClass(final byte[] source) {
        final long classId = CRC64.classId(source);
        final ClassReader reader = InstrSupport.classReaderFor(source);
        final String className = reader.getClassName();
        if (!filter.includeInReport(className)) return;  // <<<<<< SHORT CIRCUIT
        if ((reader.getAccess() & Opcodes.ACC_MODULE) != 0) {
            return;
        }
        if ((reader.getAccess() & Opcodes.ACC_SYNTHETIC) != 0) {
            return;
        }
        final ClassVisitor visitor = createAnalyzingVisitor(classId,className);
        reader.accept(visitor, 0);
    }

Note this Filter implementation only handles includes and excludes.
It does not account for options.getExclClassloader(),options.getInclBootstrapClasses(), or options.getInclNoLocationClasses().

import java.security.CodeSource;
import java.security.ProtectionDomain;
import org.jacoco.agent.rt.internal_035b120.CoverageTransformer;
import org.jacoco.core.runtime.WildcardMatcher;

public class Filter {
    private static final String AGENT_PREFIX;
    static {
        final String name = CoverageTransformer.class.getName();
        AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.')));
    }
    private final WildcardMatcher includes;
    private final WildcardMatcher excludes;

    public Filter (String includesStr, String excludesStr) {
        includes = new WildcardMatcher(toVMName(includesStr));
        excludes = new WildcardMatcher(toVMName(excludesStr));
    }

    public boolean includeInReport( final String className) {
        boolean include = !className.startsWith(AGENT_PREFIX) && includes.matches(className) && !excludes.matches(className);
        return include;
    }
    
    private static String toVMName(final String srcName) {
        return srcName.replace('.', '/');
    }
}
@marchof
Copy link
Member

marchof commented Aug 29, 2019

The Analyzeris used during report generation. It is typically used in a different stage of the build and in a different JVM that the JaCoCo agent. Therefore the Analyzer has no access to the agent's includes and excludes settings.

Otherwise Reports coverage is incorrectly calculated when directories containing Jars are analyzed (unless you manually explode the jars and exclude classes yourself).

If I understand your issue correctly this is the core of the request. Actually the way how class files are provided to the Analyzer highly depends on the integration (Ant, Maven, CLI, ...). Maybe you can describe your setup a bit more in detail so we can get an understanding of your use case: What integration are you using? How does your setup look like? What classes are you going to filter (why?).

@systemsplanet-zz
Copy link
Author

systemsplanet-zz commented Aug 29, 2019 via email

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

No branches or pull requests

2 participants