diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java index c68fefdb8..426f90cc0 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java @@ -941,13 +941,14 @@ public class Check extends Update { } } DatabaseProperties prop = null; - CveDB cve; try { - cve = CveDB.getInstance(); + final CveDB cve = CveDB.getInstance(); prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { //TODO shouldn't this be a fatal exception log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); + } finally { + CveDB.close(); } final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index 506ae0cac..b8a0abe19 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -285,6 +285,7 @@ public class App { final CveDB cve = CveDB.getInstance(); final DatabaseProperties prop = cve.getDatabaseProperties(); final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); + CveDB.close(); try { report.generateReports(reportDirectory, outputFormat); } catch (ReportException ex) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index 14c9a4e2a..8be22c518 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -126,11 +126,7 @@ public class Engine implements FileFilter { * Properly cleans up resources allocated during analysis. */ public void cleanup() { - try { - CveDB.getInstance().closeDatabase(); - } catch (DatabaseException ex) { - LOGGER.trace("Error closing the database", ex); - } + CveDB.close(); ConnectionFactory.cleanup(); } @@ -754,6 +750,7 @@ public class Engine implements FileFilter { if (!cve.dataExists()) { throw new NoDataException("No documents exist"); } + CveDB.close(); } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index eafdb7b1e..b6c35acef 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -850,6 +850,8 @@ public class DependencyCheckScanAgent { } catch (DatabaseException ex) { //TODO shouldn't this throw an exception or return? LOGGER.debug("Unable to retrieve DB Properties", ex); + } finally { + CveDB.close(); } final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index 455e6689c..f30127e35 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -182,6 +182,10 @@ public class CPEAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { + if (cve != null) { + CveDB.close(); + cve = null; + } if (cpe != null) { cpe.close(); cpe = null; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java index 10525ee62..e254932af 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java @@ -68,6 +68,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { + CveDB.close(); cveDB = null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index f8239eadf..bd7b79b7c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -208,6 +208,14 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } + /** + * Closes the data source. + */ + @Override + public void closeAnalyzer() { + CveDB.close(); + cvedb = null; + } /** * Returns the name of the analyzer. * diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index ffaabf023..ac105dbf6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -64,6 +64,11 @@ public final class CveDB { * Singleton instance of the CveDB. */ private static CveDB instance = null; + /** + * Track the number of current users of the CveDB; so that if someone is + * using database another user cannot close the connection on them. + */ + private int usageCount = 0; /** * The logger. */ @@ -84,7 +89,7 @@ public final class CveDB { /** * The prepared statements. */ - private EnumMap preparedStatements; + private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); /** * The enum value names must match the keys of the statements in the @@ -191,6 +196,10 @@ public final class CveDB { if (instance == null) { instance = new CveDB(); } + if (!instance.isOpen()) { + instance.open(); + } + instance.usageCount += 1; return instance; } @@ -202,17 +211,17 @@ public final class CveDB { * database. */ private CveDB() throws DatabaseException { - openDatabase(); } /** * Tries to determine the product name of the database. * + * @param conn the database connection * @return the product name of the database if successful, {@code null} else */ - private synchronized String determineDatabaseProductName() { + private static String determineDatabaseProductName(Connection conn) { try { - final String databaseProductName = connection.getMetaData().getDatabaseProductName(); + final String databaseProductName = conn.getMetaData().getDatabaseProductName(); LOGGER.debug("Database product: {}", databaseProductName); return databaseProductName; } catch (SQLException se) { @@ -228,37 +237,42 @@ public final class CveDB { * @throws DatabaseException thrown if there is an error opening the * database connection */ - public synchronized void openDatabase() throws DatabaseException { - if (!isOpen()) { - connection = ConnectionFactory.getConnection(); - final String databaseProductName = determineDatabaseProductName(); - statementBundle = databaseProductName != null + private synchronized void open() throws DatabaseException { + if (!instance.isOpen()) { + instance.connection = ConnectionFactory.getConnection(); + final String databaseProductName = determineDatabaseProductName(instance.connection); + instance.statementBundle = databaseProductName != null ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) : ResourceBundle.getBundle("data/dbStatements"); - preparedStatements = prepareStatements(); - databaseProperties = new DatabaseProperties(this); + instance.prepareStatements(); + instance.databaseProperties = new DatabaseProperties(instance); } } /** - * Closes the DB4O database. Close should be called on this object when it - * is done being used. + * Closes the database connection. Close should be called on this object + * when it is done being used. */ - public synchronized void closeDatabase() { - if (isOpen()) { - closeStatements(); - try { - connection.close(); - } catch (SQLException ex) { - LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); - LOGGER.debug("", ex); - } catch (Throwable ex) { - LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); - LOGGER.debug("", ex); + public static synchronized void close() { + if (instance != null) { + instance.usageCount -= 1; + if (instance.usageCount <= 0 && instance.isOpen()) { + instance.usageCount = 0; + instance.closeStatements(); + try { + instance.connection.close(); + } catch (SQLException ex) { + LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); + LOGGER.debug("", ex); + } catch (Throwable ex) { + LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); + LOGGER.debug("", ex); + } + instance.statementBundle = null; + instance.preparedStatements.clear(); + instance.databaseProperties = null; + instance.connection = null; } - connection = null; - preparedStatements = null; - databaseProperties = null; } } @@ -272,16 +286,12 @@ public final class CveDB { } /** - * Prepares all statements to be used and returns them. + * Prepares all statements to be used. * - * @return the prepared statements * @throws DatabaseException thrown if there is an error preparing the * statements */ - private synchronized EnumMap prepareStatements() - throws DatabaseException { - - final EnumMap result = new EnumMap<>(PreparedStatementCveDb.class); + private void prepareStatements() throws DatabaseException { for (PreparedStatementCveDb key : values()) { final String statementString = statementBundle.getString(key.name()); final PreparedStatement preparedStatement; @@ -294,9 +304,8 @@ public final class CveDB { } catch (SQLException exception) { throw new DatabaseException(exception); } - result.put(key, preparedStatement); + preparedStatements.put(key, preparedStatement); } - return result; } /** @@ -343,7 +352,7 @@ public final class CveDB { @SuppressWarnings("FinalizeDeclaration") protected void finalize() throws Throwable { LOGGER.debug("Entering finalize"); - closeDatabase(); + close(); super.finalize(); } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java index ad25e6ae4..6958d6ba7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java @@ -94,6 +94,7 @@ public class EngineVersionCheck implements CachedWebDataSource { @Override public void update() throws UpdateException { try { + final CveDB db = CveDB.getInstance(); final boolean autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true); final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL); @@ -105,7 +106,9 @@ public class EngineVersionCheck implements CachedWebDataSource { */ if (enabled && autoupdate && original != null && original.equals(current)) { LOGGER.debug("Begin Engine Version Check"); - final DatabaseProperties properties = CveDB.getInstance().getDatabaseProperties(); + + final DatabaseProperties properties = db.getDatabaseProperties(); + final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); final long now = System.currentTimeMillis(); updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); @@ -124,6 +127,8 @@ public class EngineVersionCheck implements CachedWebDataSource { throw new UpdateException("Error occurred updating database properties."); } catch (InvalidSettingException ex) { LOGGER.debug("Unable to determine if autoupdate is enabled", ex); + } finally { + CveDB.close(); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 80ebb1bf6..98a12d958 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -139,6 +139,7 @@ public class NvdCveUpdater implements CachedWebDataSource { throw new UpdateException("Database Exception, unable to update the data to use the most current data.", ex); } finally { shutdownExecutorServices(); + CveDB.close(); } } @@ -206,6 +207,8 @@ public class NvdCveUpdater implements CachedWebDataSource { return cve.dataExists(); } catch (DatabaseException ex) { return false; + } finally { + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index 79e372d13..0c2fd0bdf 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -54,11 +54,6 @@ public abstract class BaseDBTestCase extends BaseTest { CveDB.getInstance().openDatabase(); } - @AfterClass - public static void tearDownClass() throws Exception { - CveDB.getInstance().closeDatabase(); - } - public static void ensureDBExists() throws Exception { File f = new File("./target/data/dc.h2.db"); if (f.exists() && f.isFile() && f.length() < 71680) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java index 5a78871c1..85958a39c 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java @@ -73,6 +73,7 @@ public class EngineIntegrationTest extends BaseDBTestCase { } CveDB cveDB = CveDB.getInstance(); DatabaseProperties dbProp = cveDB.getDatabaseProperties(); + CveDB.close(); ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); rg.generateReports("./target/", "ALL"); instance.cleanup(); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index ff5a4a9e1..d2e655ac7 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -53,7 +53,7 @@ import org.owasp.dependencycheck.exception.InitializationException; * @author Dale Visser */ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { - + private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); /** @@ -117,7 +117,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.analyze(result, engine); int size = engine.getDependencies().size(); assertTrue(size >= 1); - + Dependency dependency = engine.getDependencies().get(0); assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); @@ -136,16 +136,16 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { try { analyzer.initialize(); - + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/sinatra/Gemfile.lock")); final Engine engine = new Engine(); analyzer.analyze(result, engine); - + Dependency dependency = engine.getDependencies().get(0); Vulnerability vulnerability = dependency.getVulnerabilities().first(); assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); - + } catch (InitializationException | DatabaseException | AnalysisException e) { LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); @@ -166,6 +166,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.initialize(); } catch (Exception e) { //expected, so ignore. + LOGGER.error("Exception", e); } finally { assertThat(analyzer.isEnabled(), is(false)); LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); @@ -197,14 +198,14 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { while (dIterator.hasNext()) { Dependency dept = dIterator.next(); LOGGER.info("dept path: " + dept.getActualFilePath()); - + Set identifiers = dept.getIdentifiers(); Iterator idIterator = identifiers.iterator(); while (idIterator.hasNext()) { Identifier id = idIterator.next(); LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); } - + Set prodEv = dept.getProductEvidence().getEvidence(); Iterator it = prodEv.iterator(); while (it.hasNext()) { @@ -217,7 +218,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { Evidence e = vIt.next(); LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); } - + Set vendorEv = dept.getVendorEvidence().getEvidence(); Iterator vendorIt = vendorEv.iterator(); while (vendorIt.hasNext()) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java index 54ad59c88..916f9462d 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java @@ -51,6 +51,8 @@ public class CveDBIntegrationTest extends BaseDBTestCase { instance.commit(); } catch (DatabaseException | SQLException ex) { fail(ex.getMessage()); + } finally { + CveDB.close(); } } @@ -64,6 +66,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue(result.size() > 5); + CveDB.close(); } /** @@ -74,6 +77,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { CveDB instance = CveDB.getInstance(); Vulnerability result = instance.getVulnerability("CVE-2014-0094"); assertEquals("The ParametersInterceptor in Apache Struts before 2.3.16.1 allows remote attackers to \"manipulate\" the ClassLoader via the class parameter, which is passed to the getClass method.", result.getDescription()); + CveDB.close(); } /** @@ -110,6 +114,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } } assertTrue("Expected " + expected + ", but was not identified", found); + CveDB.close(); } /** @@ -165,5 +170,6 @@ public class CveDBIntegrationTest extends BaseDBTestCase { identifiedVersion = new DependencyVersion("1.6.3"); results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); assertNotNull(results); + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java index 99e2b3581..dbe7d22bc 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java @@ -44,6 +44,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (DatabaseException ex) { System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); fail(ex.getMessage()); + } finally { + CveDB.close(); } } @@ -61,6 +63,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; + } finally { + CveDB.close(); } } @@ -77,6 +81,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; - } + } finally { + CveDB.close(); + } } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java index 6c6af8bcf..6067f8e40 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java @@ -41,6 +41,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { assertNotNull(instance); //no exception means the call worked... whether or not it is empty depends on if the db is new //assertEquals(expResult, result); + CveDB.close(); } /** @@ -59,6 +60,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { instance = cveDB.reloadProperties(); long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); assertEquals(expected, results); + CveDB.close(); } /** @@ -73,6 +75,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { String expResult = "default"; String result = instance.getProperty(key, defaultValue); assertEquals(expResult, result); + CveDB.close(); } /** @@ -87,6 +90,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { double version = Double.parseDouble(result); assertTrue(version >= 2.8); assertTrue(version <= 10); + CveDB.close(); } /** @@ -98,5 +102,6 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { DatabaseProperties instance = cveDB.getDatabaseProperties(); Properties result = instance.getProperties(); assertTrue(result.size() > 0); + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java index f379d332d..0b9e72390 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java @@ -149,6 +149,7 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); generator.generateReport(templateName, writeTo); + CveDB.close(); engine.cleanup(); diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index d2e95260c..629d722a4 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -1017,6 +1017,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); + CveDB.close(); try { r.generateReports(outputDir.getAbsolutePath(), format); } catch (ReportException ex) {