A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/pmd/pmd/issues/4035 below:

[core] ConcurrentModificationException in DefaultRuleViolationFactory · Issue #4035 · pmd/pmd · GitHub

Affects PMD Version: 7.0.x (maybe also 6)

Make sure, to test with the latest PMD version.

Description:

During the development of sonar-pmd plugin, the integration tests that uses the sonar-orchestrator would sometimes succeed and sometimes fail. When failures occur we see ConcurrentModificationExceptions in DefaultRuleViolationFactory.

Exception Stacktrace:

[WARNING] Exception applying rule DoNotExtendIOException on file /Users/pp/alpha/git/sonar-pmd/integration-test/projects/pmd-extensions/src/main/java/pmd/Foo.java, continuing with next rule
org.apache.commons.lang3.exception.ContextedRuntimeException: java.util.ConcurrentModificationException
Exception Context:
	[1:Rule applied on node=[ClassOrInterfaceType:5:26]IOException]
---------------------------------
	at net.sourceforge.pmd.internal.util.AssertionUtil.contexted(AssertionUtil.java:172)
	at net.sourceforge.pmd.lang.rule.internal.RuleApplicator.applyOnIndex(RuleApplicator.java:72)
	at net.sourceforge.pmd.lang.rule.internal.RuleApplicator.apply(RuleApplicator.java:52)
	at net.sourceforge.pmd.RuleSets.apply(RuleSets.java:141)
	at net.sourceforge.pmd.processor.PmdRunnable.processSource(PmdRunnable.java:158)
	at net.sourceforge.pmd.processor.PmdRunnable.processSource(PmdRunnable.java:110)
	at net.sourceforge.pmd.processor.PmdRunnable.run(PmdRunnable.java:83)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.util.ConcurrentModificationException: null
	at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:719)
	at java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:741)
	at net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory.suppressOrNull(DefaultRuleViolationFactory.java:42)
	at net.sourceforge.pmd.RuleContext.addViolationWithPosition(RuleContext.java:137)
	at net.sourceforge.pmd.RuleContext.addViolationWithMessage(RuleContext.java:110)
	at net.sourceforge.pmd.RuleContext.addViolation(RuleContext.java:83)
	at net.sourceforge.pmd.lang.rule.AbstractRule.addViolation(AbstractRule.java:321)
	at net.sourceforge.pmd.lang.rule.XPathRule.apply(XPathRule.java:136)
	at net.sourceforge.pmd.lang.rule.AbstractDelegateRule.apply(AbstractDelegateRule.java:237)
	at net.sourceforge.pmd.lang.rule.internal.RuleApplicator.applyOnIndex(RuleApplicator.java:69)
	... 10 common frames omitted

Code Sample demonstrating the issue:

Not applicable.

Steps to reproduce:

Clone https://github.com/jborgers/sonar-pmd and run:

Run with OpenJDK 64-Bit Server VM Zulu11.56+19-CA (build 11.0.15+10-LTS, mixed mode) on mac m1 (seems also to occur on amd64 chips).

Looking at the code it seems that a Set of ViolationSuppressors is returned when still being initialised due to concurrent threads checking for null and one is returning a non-fully initialised Set.

The code changes below seems to fix this, all integration tests in sonar-pmd succeed each time with this update:

In: net.sourceforge.pmd.lang.rule.impl.DefaultRuleViolationFactory

    private final AtomicReference<Set<ViolationSuppressor>> allSuppressors = new AtomicReference<>();

    private Set<ViolationSuppressor> getAllSuppressors() {
        if (this.allSuppressors.get() == null) {
            // lazy loaded because calling getSuppressors in constructor
            // is not safe wrt initialization of static constants
            // (order dependent otherwise)
            Set<ViolationSuppressor> myAllSuppressors = new LinkedHashSet<>(getSuppressors());
            myAllSuppressors.add(ViolationSuppressor.NOPMD_COMMENT_SUPPRESSOR);
            myAllSuppressors.add(ViolationSuppressor.REGEX_SUPPRESSOR);
            myAllSuppressors.add(ViolationSuppressor.XPATH_SUPPRESSOR);
            if (!this.allSuppressors.compareAndSet(null, myAllSuppressors)) {
                return allSuppressors.get();
            }
        }
        return this.allSuppressors.get();
    }

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4