mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-21 16:49:43 +01:00
removed TreeSet to improve performance
This commit is contained in:
@@ -1128,7 +1128,7 @@ public class Check extends Update {
|
|||||||
for (Dependency d : dependencies) {
|
for (Dependency d : dependencies) {
|
||||||
boolean firstEntry = true;
|
boolean firstEntry = true;
|
||||||
final StringBuilder ids = new StringBuilder();
|
final StringBuilder ids = new StringBuilder();
|
||||||
for (Vulnerability v : d.getVulnerabilities()) {
|
for (Vulnerability v : d.getVulnerabilities(true)) {
|
||||||
if (firstEntry) {
|
if (firstEntry) {
|
||||||
firstEntry = false;
|
firstEntry = false;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1053,7 +1053,7 @@ public class DependencyCheckScanAgent {
|
|||||||
for (Dependency d : dependencies) {
|
for (Dependency d : dependencies) {
|
||||||
boolean firstEntry = true;
|
boolean firstEntry = true;
|
||||||
final StringBuilder ids = new StringBuilder();
|
final StringBuilder ids = new StringBuilder();
|
||||||
for (Vulnerability v : d.getVulnerabilities()) {
|
for (Vulnerability v : d.getVulnerabilities(true)) {
|
||||||
if (firstEntry) {
|
if (firstEntry) {
|
||||||
firstEntry = false;
|
firstEntry = false;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
|
|
||||||
@@ -83,7 +82,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A list of Identifiers.
|
* A list of Identifiers.
|
||||||
*/
|
*/
|
||||||
private final Set<Identifier> identifiers = new TreeSet<>();
|
private final Set<Identifier> identifiers = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* The file name to display in reports.
|
* The file name to display in reports.
|
||||||
*/
|
*/
|
||||||
@@ -91,11 +90,11 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A set of identifiers that have been suppressed.
|
* A set of identifiers that have been suppressed.
|
||||||
*/
|
*/
|
||||||
private final Set<Identifier> suppressedIdentifiers = new TreeSet<>();
|
private final Set<Identifier> suppressedIdentifiers = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A set of vulnerabilities that have been suppressed.
|
* A set of vulnerabilities that have been suppressed.
|
||||||
*/
|
*/
|
||||||
private final SortedSet<Vulnerability> suppressedVulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
private final Set<Vulnerability> suppressedVulnerabilities = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* The description of the JAR file.
|
* The description of the JAR file.
|
||||||
*/
|
*/
|
||||||
@@ -107,11 +106,11 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
/**
|
/**
|
||||||
* A list of vulnerabilities for this dependency.
|
* A list of vulnerabilities for this dependency.
|
||||||
*/
|
*/
|
||||||
private final SortedSet<Vulnerability> vulnerabilities = new TreeSet<>(new VulnerabilityComparator());
|
private final Set<Vulnerability> vulnerabilities = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A collection of related dependencies.
|
* A collection of related dependencies.
|
||||||
*/
|
*/
|
||||||
private final Set<Dependency> relatedDependencies = new TreeSet<>();
|
private final Set<Dependency> relatedDependencies = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A list of projects that reference this dependency.
|
* A list of projects that reference this dependency.
|
||||||
*/
|
*/
|
||||||
@@ -457,12 +456,53 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an unmodifiable sorted set of suppressedVulnerabilities.
|
* Get the unmodifiable sorted set of vulnerabilities.
|
||||||
|
*
|
||||||
|
* @return the unmodifiable sorted set of vulnerabilities
|
||||||
|
*/
|
||||||
|
public synchronized Set<Vulnerability> getVulnerabilities() {
|
||||||
|
return getVulnerabilities(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unmodifiable list of vulnerabilities; optionally sorted.
|
||||||
|
*
|
||||||
|
* @param sorted if true the list will be sorted
|
||||||
|
* @return the unmodifiable list set of vulnerabilities
|
||||||
|
*/
|
||||||
|
public synchronized Set<Vulnerability> getVulnerabilities(boolean sorted) {
|
||||||
|
Set<Vulnerability> r;
|
||||||
|
if (sorted) {
|
||||||
|
r = new TreeSet<>(vulnerabilities);
|
||||||
|
} else {
|
||||||
|
r = vulnerabilities;
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an unmodifiable set of suppressedVulnerabilities.
|
||||||
*
|
*
|
||||||
* @return the unmodifiable sorted set of suppressedVulnerabilities
|
* @return the unmodifiable sorted set of suppressedVulnerabilities
|
||||||
*/
|
*/
|
||||||
public synchronized SortedSet<Vulnerability> getSuppressedVulnerabilities() {
|
public synchronized Set<Vulnerability> getSuppressedVulnerabilities() {
|
||||||
return Collections.unmodifiableSortedSet(new TreeSet<>(suppressedVulnerabilities));
|
return getSuppressedVulnerabilities(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an unmodifiable, optionally sorted. set of suppressedVulnerabilities.
|
||||||
|
*
|
||||||
|
* @param sorted whether or not the set is sorted
|
||||||
|
* @return the unmodifiable sorted set of suppressedVulnerabilities
|
||||||
|
*/
|
||||||
|
public synchronized Set<Vulnerability> getSuppressedVulnerabilities(boolean sorted) {
|
||||||
|
Set<Vulnerability> r;
|
||||||
|
if (sorted) {
|
||||||
|
r = new TreeSet<>(suppressedVulnerabilities);
|
||||||
|
} else {
|
||||||
|
r = suppressedVulnerabilities;
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableSet(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -525,16 +565,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the unmodifiable sorted set of vulnerabilities.
|
* Determines the SHA1 and MD5 sum for the given file.
|
||||||
*
|
|
||||||
* @return the unmodifiable sorted set of vulnerabilities
|
|
||||||
*/
|
|
||||||
public synchronized SortedSet<Vulnerability> getVulnerabilities() {
|
|
||||||
return Collections.unmodifiableSortedSet(new TreeSet<>(vulnerabilities));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the sha1 and md5 sum for the given file.
|
|
||||||
*
|
*
|
||||||
* @param file the file to create checksums for
|
* @param file the file to create checksums for
|
||||||
*/
|
*/
|
||||||
@@ -624,11 +655,7 @@ public class Dependency extends EvidenceCollection implements Serializable, Comp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a related dependency. The internal collection is normally a
|
* Adds a related dependency.
|
||||||
* {@link java.util.TreeSet}, which relies on
|
|
||||||
* {@link #compareTo(Dependency)}. A consequence of this is that if you
|
|
||||||
* attempt to add a dependency with the same file path (modulo character
|
|
||||||
* case) as one that is already in the collection, it won't get added.
|
|
||||||
*
|
*
|
||||||
* @param dependency a reference to the related dependency
|
* @param dependency a reference to the related dependency
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of dependency-check-core.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
package org.owasp.dependencycheck.dependency;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comparator for Vulnerability objects.
|
|
||||||
*
|
|
||||||
* @author Jeremy Long
|
|
||||||
*/
|
|
||||||
@ThreadSafe
|
|
||||||
public class VulnerabilityComparator implements Comparator<Vulnerability>, Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The serial version UID.
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the comparison of vulnerabilities.
|
|
||||||
*
|
|
||||||
* @param o1 a vulnerability
|
|
||||||
* @param o2 a second vulnerability
|
|
||||||
* @return the comparison
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int compare(Vulnerability o1, Vulnerability o2) {
|
|
||||||
return o2.getName().compareTo(o1.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ Copyright (c) 2017 Jeremy Long. All Rights Reserved.
|
|||||||
"Project","ScanDate","DependencyName","DependencyPath","Description","License","Md5","Sha1","Identifiers","CPE","CVE","CWE","Vulnerability","Source","Severity","CVSSv2","GAV","CPE Confidence","Evidence Count"
|
"Project","ScanDate","DependencyName","DependencyPath","Description","License","Md5","Sha1","Identifiers","CPE","CVE","CWE","Vulnerability","Source","Severity","CVSSv2","GAV","CPE Confidence","Evidence Count"
|
||||||
#macro(writeSev $score)#if($score<4.0)"Low"#elseif($score>=7.0)"High"#else"Medium"#end#end
|
#macro(writeSev $score)#if($score<4.0)"Low"#elseif($score>=7.0)"High"#else"Medium"#end#end
|
||||||
#foreach($dependency in $dependencies)#if($dependency.getVulnerabilities().size()>0)
|
#foreach($dependency in $dependencies)#if($dependency.getVulnerabilities().size()>0)
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())
|
#foreach($vuln in $dependency.getVulnerabilities(true))
|
||||||
$enc.csv($applicationName),$enc.csv($scanDate),$enc.csv($dependency.DisplayFileName),#if($dependency.FilePath)$enc.csv($dependency.FilePath)#end,#if($dependency.description)$enc.csv($dependency.description)#end,#if($dependency.license)$enc.csv($dependency.license)#end,#if($dependency.Md5sum)$enc.csv($dependency.Md5sum)#end,#if($dependency.Sha1sum)$enc.csv($dependency.Sha1sum)#end,#if($dependency.identifiers)$enc.csvIdentifiers($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpe($dependency.identifiers)#end,#if($vuln.name)$enc.csv($vuln.name)#end,#if($dependency.cwe)$enc.csv($vuln.cwe)#end,#if($vuln.description)$enc.csv($vuln.description)#end,#if($vuln.getSource().name())$enc.csv($vuln.getSource().name())#end,#writeSev($vuln.cvssScore),$vuln.cvssScore,#if($dependency.identifiers)$enc.csvGav($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpeConfidence($dependency.identifiers)#end,$dependency.size()
|
$enc.csv($applicationName),$enc.csv($scanDate),$enc.csv($dependency.DisplayFileName),#if($dependency.FilePath)$enc.csv($dependency.FilePath)#end,#if($dependency.description)$enc.csv($dependency.description)#end,#if($dependency.license)$enc.csv($dependency.license)#end,#if($dependency.Md5sum)$enc.csv($dependency.Md5sum)#end,#if($dependency.Sha1sum)$enc.csv($dependency.Sha1sum)#end,#if($dependency.identifiers)$enc.csvIdentifiers($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpe($dependency.identifiers)#end,#if($vuln.name)$enc.csv($vuln.name)#end,#if($dependency.cwe)$enc.csv($vuln.cwe)#end,#if($vuln.description)$enc.csv($vuln.description)#end,#if($vuln.getSource().name())$enc.csv($vuln.getSource().name())#end,#writeSev($vuln.cvssScore),$vuln.cvssScore,#if($dependency.identifiers)$enc.csvGav($dependency.identifiers)#end,#if($dependency.identifiers)$enc.csvCpeConfidence($dependency.identifiers)#end,$dependency.size()
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|||||||
@@ -843,7 +843,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
|||||||
#set($cnt=$cnt+1)
|
#set($cnt=$cnt+1)
|
||||||
<h4 id="header$cnt" class="subsectionheader expandable collaspablesubsection white">Published Vulnerabilities</h4>
|
<h4 id="header$cnt" class="subsectionheader expandable collaspablesubsection white">Published Vulnerabilities</h4>
|
||||||
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())
|
#foreach($vuln in $dependency.getVulnerabilities(true))
|
||||||
#set($vsctr=$vsctr+1)
|
#set($vsctr=$vsctr+1)
|
||||||
#if($vuln.getSource().name().equals("NVD"))
|
#if($vuln.getSource().name().equals("NVD"))
|
||||||
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b> <button class="copybutton" title="Generate Suppression XML for this CCE for this file" onclick="copyText('$enc.javascript($dependency.DisplayFileName)', '$enc.javascript($dependency.Sha1sum)', '$enc.javascript($suppressGav)', 'cve', '$enc.javascript($vuln.name)')">suppress</button></p>
|
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b> <button class="copybutton" title="Generate Suppression XML for this CCE for this file" onclick="copyText('$enc.javascript($dependency.DisplayFileName)', '$enc.javascript($dependency.Sha1sum)', '$enc.javascript($suppressGav)', 'cve', '$enc.javascript($vuln.name)')">suppress</button></p>
|
||||||
@@ -1015,7 +1015,7 @@ Getting Help: <a href="https://groups.google.com/forum/#!forum/dependency-check"
|
|||||||
#set($cnt=$cnt+1)
|
#set($cnt=$cnt+1)
|
||||||
<h4 id="header$cnt" class="subsectionheader expandable collaspablesubsection white">Suppressed Vulnerabilities</h4>
|
<h4 id="header$cnt" class="subsectionheader expandable collaspablesubsection white">Suppressed Vulnerabilities</h4>
|
||||||
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
<div id="content$cnt" class="subsectioncontent standardsubsection">
|
||||||
#foreach($vuln in $dependency.getSuppressedVulnerabilities())
|
#foreach($vuln in $dependency.getSuppressedVulnerabilities(true))
|
||||||
#set($vsctr=$vsctr+1)
|
#set($vsctr=$vsctr+1)
|
||||||
#if($vuln.getSource().name().equals("NVD"))
|
#if($vuln.getSource().name().equals("NVD"))
|
||||||
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b> <span class="suppressedLabel" >suppressed</span></p>
|
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$enc.url($vuln.name)">$enc.html($vuln.name)</a></b> <span class="suppressedLabel" >suppressed</span></p>
|
||||||
|
|||||||
@@ -132,7 +132,7 @@
|
|||||||
|
|
||||||
#if($dependency.getVulnerabilities().size()>0)
|
#if($dependency.getVulnerabilities().size()>0)
|
||||||
,"vulnerabilities": [
|
,"vulnerabilities": [
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())#if($foreach.count > 1),#end {
|
#foreach($vuln in $dependency.getVulnerabilities(true))#if($foreach.count > 1),#end {
|
||||||
"source": "$enc.json($vuln.getSource().name())",
|
"source": "$enc.json($vuln.getSource().name())",
|
||||||
"name": "$enc.json($vuln.name)",
|
"name": "$enc.json($vuln.name)",
|
||||||
"cvssScore": "$vuln.cvssScore",
|
"cvssScore": "$vuln.cvssScore",
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
|
|
||||||
#if($dependency.getSuppressedVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
#if($dependency.getSuppressedVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
||||||
,"suppressedVulnerabilities": [
|
,"suppressedVulnerabilities": [
|
||||||
#foreach($vuln in $dependency.getSuppressedVulnerabilities())#if($foreach.count > 1),#end {
|
#foreach($vuln in $dependency.getSuppressedVulnerabilities(true))#if($foreach.count > 1),#end {
|
||||||
"source": "$enc.json($vuln.getSource().name())",
|
"source": "$enc.json($vuln.getSource().name())",
|
||||||
"name": "$enc.json($vuln.name)",
|
"name": "$enc.json($vuln.name)",
|
||||||
"cvssScore": "$vuln.cvssScore",
|
"cvssScore": "$vuln.cvssScore",
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ have been reported. Additionally, the HTML report provides many features not fou
|
|||||||
<tbody>
|
<tbody>
|
||||||
#foreach($dependency in $dependencies)
|
#foreach($dependency in $dependencies)
|
||||||
#if($dependency.getVulnerabilities().size()>0)
|
#if($dependency.getVulnerabilities().size()>0)
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())
|
#foreach($vuln in $dependency.getVulnerabilities(true))
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
#if($vuln.getSource().name().equals("NVD"))
|
#if($vuln.getSource().name().equals("NVD"))
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
#end
|
#end
|
||||||
#if($dependency.getVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
#if($dependency.getVulnerabilities().size()>0 || $dependency.getSuppressedVulnerabilities().size()>0)
|
||||||
<vulnerabilities>
|
<vulnerabilities>
|
||||||
#foreach($vuln in $dependency.getVulnerabilities())
|
#foreach($vuln in $dependency.getVulnerabilities(true))
|
||||||
<vulnerability source="$enc.xml($vuln.getSource().name())">
|
<vulnerability source="$enc.xml($vuln.getSource().name())">
|
||||||
<name>$enc.xml($vuln.name)</name>
|
<name>$enc.xml($vuln.name)</name>
|
||||||
<cvssScore>$vuln.cvssScore</cvssScore>
|
<cvssScore>$vuln.cvssScore</cvssScore>
|
||||||
@@ -180,7 +180,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
</vulnerableSoftware>
|
</vulnerableSoftware>
|
||||||
</vulnerability>
|
</vulnerability>
|
||||||
#end
|
#end
|
||||||
#foreach($vuln in $dependency.getSuppressedVulnerabilities())
|
#foreach($vuln in $dependency.getSuppressedVulnerabilities(true))
|
||||||
<suppressedVulnerability source="$enc.xml($vuln.getSource().name())">
|
<suppressedVulnerability source="$enc.xml($vuln.getSource().name())">
|
||||||
<name>$enc.xml($vuln.name)</name>
|
<name>$enc.xml($vuln.name)</name>
|
||||||
<cvssScore>$vuln.cvssScore</cvssScore>
|
<cvssScore>$vuln.cvssScore</cvssScore>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import edu.emory.mathcs.backport.java.util.Arrays;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
@@ -157,7 +158,7 @@ public class RubyBundleAuditAnalyzerIT extends BaseDBTestCase {
|
|||||||
"ruby/vulnerable/gems/sinatra/Gemfile.lock"));
|
"ruby/vulnerable/gems/sinatra/Gemfile.lock"));
|
||||||
analyzer.analyze(result, engine);
|
analyzer.analyze(result, engine);
|
||||||
Dependency dependency = engine.getDependencies()[0];
|
Dependency dependency = engine.getDependencies()[0];
|
||||||
Vulnerability vulnerability = dependency.getVulnerabilities().first();
|
Vulnerability vulnerability = ((SortedSet<Vulnerability>)dependency.getVulnerabilities(true)).first();
|
||||||
assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
|
assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
|
||||||
|
|
||||||
} catch (InitializationException | DatabaseException | AnalysisException | UpdateException e) {
|
} catch (InitializationException | DatabaseException | AnalysisException | UpdateException e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user