forked from phoedos/pmd
bug fixes: multithreading issues reported by Ryan Gustafson in the forum
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4889 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -25,6 +25,7 @@ import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
|
||||
@ -32,6 +33,7 @@ import edu.emory.mathcs.backport.java.util.concurrent.Executors;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@ -272,9 +274,6 @@ public class PMD {
|
||||
} catch (RuleSetNotFoundException rsnfe) {
|
||||
System.out.println(opts.usage());
|
||||
rsnfe.printStackTrace();
|
||||
} catch (IOException ioe) {
|
||||
System.out.println(opts.usage());
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
report.end();
|
||||
|
||||
@ -368,28 +367,30 @@ public class PMD {
|
||||
|
||||
private static class PmdThreadFactory implements ThreadFactory {
|
||||
|
||||
public PmdThreadFactory(Report report, RuleSetFactory ruleSetFactory) {
|
||||
this.report = report;
|
||||
public PmdThreadFactory(RuleSetFactory ruleSetFactory) {
|
||||
this.ruleSetFactory = ruleSetFactory;
|
||||
}
|
||||
|
||||
private final Report report;
|
||||
|
||||
private final RuleSetFactory ruleSetFactory;
|
||||
private final AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
return new PmdThread(counter.incrementAndGet(), r, report, ruleSetFactory);
|
||||
PmdThread t = new PmdThread(counter.incrementAndGet(), r, ruleSetFactory);
|
||||
threadList.add(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public List<PmdThread> threadList = Collections.synchronizedList(new LinkedList<PmdThread>());
|
||||
|
||||
}
|
||||
|
||||
private static class PmdThread extends Thread {
|
||||
|
||||
public PmdThread(int id, Runnable r, Report report, RuleSetFactory ruleSetFactory) {
|
||||
public PmdThread(int id, Runnable r, RuleSetFactory ruleSetFactory) {
|
||||
super(r, "PmdThread " + id);
|
||||
this.id = id;
|
||||
context = new RuleContext();
|
||||
context.setReport(report);
|
||||
context.setReport(new Report());
|
||||
this.ruleSetFactory = ruleSetFactory;
|
||||
}
|
||||
|
||||
@ -426,9 +427,9 @@ public class PMD {
|
||||
*/
|
||||
public static void processFiles(int threadCount, RuleSetFactory ruleSetFactory, SourceType sourceType, List files, RuleContext ctx, String rulesets,
|
||||
boolean debugEnabled, boolean shortNamesEnabled, String inputPath,
|
||||
String encoding, String excludeMarker) throws IOException {
|
||||
String encoding, String excludeMarker) {
|
||||
|
||||
PmdThreadFactory factory = new PmdThreadFactory(ctx.getReport(), ruleSetFactory);
|
||||
PmdThreadFactory factory = new PmdThreadFactory(ruleSetFactory);
|
||||
ExecutorService executor = Executors.newFixedThreadPool(threadCount, factory);
|
||||
|
||||
for (Iterator i = files.iterator(); i.hasNext();) {
|
||||
@ -447,6 +448,12 @@ public class PMD {
|
||||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
Report mainReport = ctx.getReport();
|
||||
for(PmdThread thread: factory.threadList) {
|
||||
Report r = thread.context.getReport();
|
||||
mainReport.merge(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +175,7 @@ public class Report {
|
||||
return suppressedRuleViolations;
|
||||
}
|
||||
|
||||
public synchronized void addRuleViolation(IRuleViolation violation) {
|
||||
public void addRuleViolation(IRuleViolation violation) {
|
||||
|
||||
// NOPMD excluder
|
||||
Integer line = new Integer(violation.getBeginLine());
|
||||
@ -198,7 +198,7 @@ public class Report {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addMetric(Metric metric) {
|
||||
public void addMetric(Metric metric) {
|
||||
metrics.add(metric);
|
||||
for (Iterator i = listeners.iterator(); i.hasNext();) {
|
||||
ReportListener listener = (ReportListener) i.next();
|
||||
@ -206,10 +206,25 @@ public class Report {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addError(ProcessingError error) {
|
||||
public void addError(ProcessingError error) {
|
||||
errors.add(error);
|
||||
}
|
||||
|
||||
public void merge(Report r) {
|
||||
Iterator i = r.errors();
|
||||
while (i.hasNext()) {
|
||||
addError((ProcessingError)i.next());
|
||||
}
|
||||
i = r.metrics();
|
||||
while (i.hasNext()) {
|
||||
addMetric((Metric)i.next());
|
||||
}
|
||||
i = r.iterator();
|
||||
while (i.hasNext()) {
|
||||
addRuleViolation((IRuleViolation)i.next());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMetrics() {
|
||||
return !metrics.isEmpty();
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ public class RuleSetFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private int minPriority = Rule.LOWEST_PRIORITY;
|
||||
|
||||
public void setMinimumPriority(int minPriority) {
|
||||
@ -187,7 +186,6 @@ public class RuleSetFactory {
|
||||
*/
|
||||
private RuleSet createRuleSet(InputStream inputStream, ClassLoader classLoader) {
|
||||
try {
|
||||
this.classLoader = classLoader;
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = builder.parse(inputStream);
|
||||
Element root = doc.getDocumentElement();
|
||||
@ -203,7 +201,7 @@ public class RuleSetFactory {
|
||||
if (node.getNodeName().equals("description")) {
|
||||
ruleSet.setDescription(parseTextNode(node));
|
||||
} else if (node.getNodeName().equals("rule")) {
|
||||
parseRuleNode(ruleSet, node);
|
||||
parseRuleNode(ruleSet, node, classLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,13 +257,13 @@ public class RuleSetFactory {
|
||||
* @param ruleSet the ruleset being constructed
|
||||
* @param ruleNode must be a rule element node
|
||||
*/
|
||||
private void parseRuleNode(RuleSet ruleSet, Node ruleNode)
|
||||
private void parseRuleNode(RuleSet ruleSet, Node ruleNode, ClassLoader classLoader)
|
||||
throws ClassNotFoundException, InstantiationException,
|
||||
IllegalAccessException, RuleSetNotFoundException {
|
||||
Element ruleElement = (Element) ruleNode;
|
||||
String ref = ruleElement.getAttribute("ref");
|
||||
if (ref.trim().length() == 0) {
|
||||
parseInternallyDefinedRuleNode(ruleSet, ruleNode);
|
||||
parseInternallyDefinedRuleNode(ruleSet, ruleNode, classLoader);
|
||||
} else {
|
||||
parseExternallyDefinedRuleNode(ruleSet, ruleNode);
|
||||
}
|
||||
@ -277,7 +275,7 @@ public class RuleSetFactory {
|
||||
* @param ruleSet the ruleset being constructed
|
||||
* @param ruleNode must be a rule element node
|
||||
*/
|
||||
private void parseInternallyDefinedRuleNode(RuleSet ruleSet, Node ruleNode)
|
||||
private void parseInternallyDefinedRuleNode(RuleSet ruleSet, Node ruleNode, ClassLoader classLoader)
|
||||
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
|
||||
Element ruleElement = (Element) ruleNode;
|
||||
|
||||
|
Reference in New Issue
Block a user