ensured engine.cleanup() is now being called

Former-commit-id: 99afdd8d82d6dce65d8dd3ac23893070b318c082
This commit is contained in:
Jeremy Long
2014-02-22 16:46:59 -05:00
parent 303a3ac376
commit 1f408dd7a7
8 changed files with 158 additions and 91 deletions

View File

@@ -741,47 +741,57 @@ public class DependencyCheckTask extends Task {
validateConfiguration(); validateConfiguration();
populateSettings(); populateSettings();
final Engine engine = new Engine(); Engine engine = null;
for (Resource resource : path) {
final FileProvider provider = resource.as(FileProvider.class);
if (provider != null) {
final File file = provider.getFile();
if (file != null && file.exists()) {
engine.scan(file);
}
}
}
try { try {
engine.analyzeDependencies(); engine = new Engine();
DatabaseProperties prop = null;
CveDB cve = null; for (Resource resource : path) {
try { final FileProvider provider = resource.as(FileProvider.class);
cve = new CveDB(); if (provider != null) {
cve.open(); final File file = provider.getFile();
prop = cve.getDatabaseProperties(); if (file != null && file.exists()) {
} catch (DatabaseException ex) { engine.scan(file);
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex); }
} finally {
if (cve != null) {
cve.close();
} }
} }
final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); try {
reporter.generateReports(reportOutputDirectory, reportFormat); engine.analyzeDependencies();
DatabaseProperties prop = null;
CveDB cve = null;
try {
cve = new CveDB();
cve.open();
prop = cve.getDatabaseProperties();
} catch (DatabaseException ex) {
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
} finally {
if (cve != null) {
cve.close();
}
}
final ReportGenerator reporter = new ReportGenerator(applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
reporter.generateReports(reportOutputDirectory, reportFormat);
if (this.failBuildOnCVSS <= 10) { if (this.failBuildOnCVSS <= 10) {
checkForFailure(engine.getDependencies()); checkForFailure(engine.getDependencies());
}
if (this.showSummary) {
showSummary(engine.getDependencies());
}
} catch (IOException ex) {
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to generate dependency-check report", ex);
throw new BuildException("Unable to generate dependency-check report", ex);
} catch (Exception ex) {
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "An exception occurred; unable to continue task", ex);
throw new BuildException("An exception occurred; unable to continue task", ex);
} }
if (this.showSummary) { } catch (DatabaseException ex) {
showSummary(engine.getDependencies()); Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "", ex);
} finally {
if (engine != null) {
engine.cleanup();
} }
} catch (IOException ex) {
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "Unable to generate dependency-check report", ex);
throw new BuildException("Unable to generate dependency-check report", ex);
} catch (Exception ex) {
Logger.getLogger(DependencyCheckTask.class.getName()).log(Level.FINE, "An exception occurred; unable to continue task", ex);
throw new BuildException("An exception occurred; unable to continue task", ex);
} }
} }

View File

@@ -98,36 +98,46 @@ public class App {
* @param files the files/directories to scan * @param files the files/directories to scan
*/ */
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, String extraExtensions) { private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, String extraExtensions) {
final Engine scanner = new Engine(); Engine scanner = null;
for (String file : files) {
scanner.scan(file);
}
scanner.analyzeDependencies();
final List<Dependency> dependencies = scanner.getDependencies();
DatabaseProperties prop = null;
CveDB cve = null;
try { try {
cve = new CveDB(); scanner = new Engine();
cve.open();
prop = cve.getDatabaseProperties(); for (String file : files) {
} catch (DatabaseException ex) { scanner.scan(file);
Logger.getLogger(App.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex); }
} finally {
if (cve != null) { scanner.analyzeDependencies();
cve.close(); final List<Dependency> dependencies = scanner.getDependencies();
DatabaseProperties prop = null;
CveDB cve = null;
try {
cve = new CveDB();
cve.open();
prop = cve.getDatabaseProperties();
} catch (DatabaseException ex) {
Logger.getLogger(App.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
} finally {
if (cve != null) {
cve.close();
}
}
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
}
} catch (DatabaseException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
Logger.getLogger(App.class.getName()).log(Level.FINE, "", ex);
} finally {
if (scanner != null) {
scanner.cleanup();
} }
}
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
} catch (Exception ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
} }
} }

View File

@@ -32,6 +32,7 @@ import org.owasp.dependencycheck.analyzer.AnalyzerService;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex; import org.owasp.dependencycheck.data.cpe.CpeMemoryIndex;
import org.owasp.dependencycheck.data.cpe.IndexException; import org.owasp.dependencycheck.data.cpe.IndexException;
import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory;
import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.update.CachedWebDataSource; import org.owasp.dependencycheck.data.update.CachedWebDataSource;
@@ -67,11 +68,14 @@ public class Engine {
/** /**
* Creates a new Engine. * Creates a new Engine.
*
* @throws DatabaseException thrown if there is an error connecting to the database
*/ */
public Engine() { public Engine() throws DatabaseException {
this.extensions = new HashSet<String>(); this.extensions = new HashSet<String>();
this.dependencies = new ArrayList<Dependency>(); this.dependencies = new ArrayList<Dependency>();
this.analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class); this.analyzers = new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
ConnectionFactory.initialize();
boolean autoUpdate = true; boolean autoUpdate = true;
try { try {
@@ -85,6 +89,13 @@ public class Engine {
loadAnalyzers(); loadAnalyzers();
} }
/**
* Properly cleans up resources allocated during analysis.
*/
public void cleanup() {
ConnectionFactory.cleanup();
}
/** /**
* Loads the analyzers specified in the configuration file (or system properties). * Loads the analyzers specified in the configuration file (or system properties).
*/ */

View File

@@ -173,7 +173,9 @@ public final class ConnectionFactory {
} }
/** /**
* Cleans up resources and unloads any registered database drivers. * Cleans up resources and unloads any registered database drivers. This needs to be called to ensure the driver is
* unregistered prior to the finalize method being called as during shutdown the class loader used to load the
* driver may be unloaded prior to the driver being de-registered.
*/ */
public static synchronized void cleanup() { public static synchronized void cleanup() {
if (driver != null) { if (driver != null) {

View File

@@ -69,5 +69,6 @@ public class EngineIntegrationTest {
ReportGenerator rg = new ReportGenerator("DependencyCheck", ReportGenerator rg = new ReportGenerator("DependencyCheck",
instance.getDependencies(), instance.getAnalyzers(), dbProp); instance.getDependencies(), instance.getAnalyzers(), dbProp);
rg.generateReports("./target/", "ALL"); rg.generateReports("./target/", "ALL");
instance.cleanup();
} }
} }

View File

@@ -160,6 +160,8 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
instance.analyze(dependency, engine); instance.analyze(dependency, engine);
int ending_size = engine.getDependencies().size(); int ending_size = engine.getDependencies().size();
engine.cleanup();
assertTrue(initial_size < ending_size); assertTrue(initial_size < ending_size);
} finally { } finally {
@@ -186,6 +188,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
int initial_size = engine.getDependencies().size(); int initial_size = engine.getDependencies().size();
instance.analyze(dependency, engine); instance.analyze(dependency, engine);
int ending_size = engine.getDependencies().size(); int ending_size = engine.getDependencies().size();
engine.cleanup();
assertTrue(initial_size < ending_size); assertTrue(initial_size < ending_size);
@@ -214,7 +217,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
engine.scan(file); engine.scan(file);
engine.analyzeDependencies(); engine.analyzeDependencies();
int ending_size = engine.getDependencies().size(); int ending_size = engine.getDependencies().size();
engine.cleanup();
assertTrue(initial_size < ending_size); assertTrue(initial_size < ending_size);
} finally { } finally {
@@ -261,7 +264,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
engine.scan(file); engine.scan(file);
engine.analyzeDependencies(); engine.analyzeDependencies();
int ending_size = engine.getDependencies().size(); int ending_size = engine.getDependencies().size();
engine.cleanup();
assertTrue(initial_size < ending_size); assertTrue(initial_size < ending_size);
} finally { } finally {
@@ -292,6 +295,7 @@ public class ArchiveAnalyzerTest extends BaseIndexTestCase {
// } // }
// assertTrue(failed); // assertTrue(failed);
int ending_size = engine.getDependencies().size(); int ending_size = engine.getDependencies().size();
engine.cleanup();
assertEquals(initial_size, ending_size); assertEquals(initial_size, ending_size);
} finally { } finally {
instance.close(); instance.close();

View File

@@ -150,6 +150,8 @@ public class ReportGeneratorTest {
ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp);
generator.generateReport(templateName, writeTo); generator.generateReport(templateName, writeTo);
engine.cleanup();
InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/DependencyCheck.xsd"); InputStream xsdStream = ReportGenerator.class.getClassLoader().getResourceAsStream("schema/DependencyCheck.xsd");
StreamSource xsdSource = new StreamSource(xsdStream); StreamSource xsdSource = new StreamSource(xsdStream);
StreamSource xmlSource = new StreamSource(new File(writeTo)); StreamSource xmlSource = new StreamSource(new File(writeTo));

View File

@@ -280,30 +280,37 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
* *
* @return the Engine used to scan the dependencies. * @return the Engine used to scan the dependencies.
*/ */
private Engine executeDependencyCheck() { private Engine executeDependencyCheck() throws DatabaseException {
final InputStream in = DependencyCheckMojo.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE); final InputStream in = DependencyCheckMojo.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
LogUtils.prepareLogger(in, logFile); LogUtils.prepareLogger(in, logFile);
populateSettings(); populateSettings();
final Engine engine = new Engine(); Engine engine = null;
final Set<Artifact> artifacts = project.getArtifacts(); try {
for (Artifact a : artifacts) { engine = new Engine();
if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) { final Set<Artifact> artifacts = project.getArtifacts();
continue; for (Artifact a : artifacts) {
} if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
continue;
}
if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) { if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
continue; continue;
} }
if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) { if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
continue; continue;
} }
engine.scan(a.getFile().getAbsolutePath()); engine.scan(a.getFile().getAbsolutePath());
}
engine.analyzeDependencies();
} finally {
if (engine != null) {
engine.cleanup();
}
} }
engine.analyzeDependencies();
return engine; return engine;
} }
@@ -794,13 +801,23 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
* @throws MojoFailureException thrown if a CVSS score is found that is higher then the configured level * @throws MojoFailureException thrown if a CVSS score is found that is higher then the configured level
*/ */
public void execute() throws MojoExecutionException, MojoFailureException { public void execute() throws MojoExecutionException, MojoFailureException {
final Engine engine = executeDependencyCheck(); Engine engine = null;
generateExternalReports(engine); try {
if (this.showSummary) { engine = executeDependencyCheck();
showSummary(engine.getDependencies()); generateExternalReports(engine);
} if (this.showSummary) {
if (this.failBuildOnCVSS <= 10) { showSummary(engine.getDependencies());
checkForFailure(engine.getDependencies()); }
if (this.failBuildOnCVSS <= 10) {
checkForFailure(engine.getDependencies());
}
} catch (DatabaseException ex) {
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, "", ex);
} finally {
if (engine != null) {
engine.cleanup();
}
} }
} }
@@ -825,8 +842,18 @@ public class DependencyCheckMojo extends AbstractMojo implements MavenMultiPageR
* @throws MavenReportException if a maven report exception occurs * @throws MavenReportException if a maven report exception occurs
*/ */
public void generate(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException { public void generate(Sink sink, SinkFactory sinkFactory, Locale locale) throws MavenReportException {
final Engine engine = executeDependencyCheck(); Engine engine = null;
generateMavenSiteReport(engine, sink); try {
engine = executeDependencyCheck();
generateMavenSiteReport(engine, sink);
} catch (DatabaseException ex) {
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
Logger.getLogger(DependencyCheckMojo.class.getName()).log(Level.FINE, "", ex);
} finally {
if (engine != null) {
engine.cleanup();
}
}
} }
// <editor-fold defaultstate="collapsed" desc="required setter/getter methods"> // <editor-fold defaultstate="collapsed" desc="required setter/getter methods">