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:
Xavier Le Vourch
2006-12-17 01:44:19 +00:00
parent 958c6bf91a
commit 70ef1ccc2f
3 changed files with 41 additions and 21 deletions

View File

@ -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);
}
}
/**

View File

@ -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();
}

View File

@ -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;