diff --git a/Core/build.xml b/Core/build.xml
index 32fff13e6e..bbf612c3d9 100644
--- a/Core/build.xml
+++ b/Core/build.xml
@@ -48,6 +48,11 @@
+
+
+
+
+
diff --git a/Core/ivy.xml b/Core/ivy.xml
index 32438b5971..bce73a903d 100644
--- a/Core/ivy.xml
+++ b/Core/ivy.xml
@@ -46,6 +46,9 @@
+
+
+
diff --git a/Core/manifest.mf b/Core/manifest.mf
index a2c2843839..da946df7b8 100644
--- a/Core/manifest.mf
+++ b/Core/manifest.mf
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
OpenIDE-Module: org.sleuthkit.autopsy.core/10
OpenIDE-Module-Localizing-Bundle: org/sleuthkit/autopsy/core/Bundle.properties
OpenIDE-Module-Layer: org/sleuthkit/autopsy/core/layer.xml
-OpenIDE-Module-Implementation-Version: 33
+OpenIDE-Module-Implementation-Version: 34
OpenIDE-Module-Requires: org.openide.windows.WindowManager
AutoUpdate-Show-In-Client: true
AutoUpdate-Essential-Module: true
diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties
index 30ca03d03b..8e0aabafaf 100644
--- a/Core/nbproject/project.properties
+++ b/Core/nbproject/project.properties
@@ -11,6 +11,8 @@ file.reference.bcpkix-jdk15on-1.54.jar=release\\modules\\ext\\bcpkix-jdk15on-1.5
file.reference.bcprov-ext-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-ext-jdk15on-1.54.jar
file.reference.bcprov-jdk15on-1.52.jar=release\\modules\\ext\\bcprov-jdk15on-1.52.jar
file.reference.bcprov-jdk15on-1.54.jar=release\\modules\\ext\\bcprov-jdk15on-1.54.jar
+file.reference.byte-buddy-1.10.13.jar=release\\modules\\ext\\byte-buddy-1.10.13.jar
+file.reference.byte-buddy-agent-1.10.13.jar=release\\modules\\ext\\byte-buddy-agent-1.10.13.jar
file.reference.c3p0-0.9.5.jar=release\\modules\\ext\\c3p0-0.9.5.jar
file.reference.checker-compat-qual-2.5.3.jar=release\\modules\\ext\\checker-compat-qual-2.5.3.jar
file.reference.commons-beanutils-1.9.2.jar=release\\modules\\ext\\commons-beanutils-1.9.2.jar
@@ -70,9 +72,11 @@ file.reference.jai_core-1.1.3.jar=release\\modules\\ext\\jai_core-1.1.3.jar
file.reference.jai_imageio-1.1.jar=release\\modules\\ext\\jai_imageio-1.1.jar
file.reference.javax.annotation-api-1.3.2.jar=release\\modules\\ext\\javax.annotation-api-1.3.2.jar
file.reference.javax.ws.rs-api-2.0.jar=release\\modules\\ext\\javax.ws.rs-api-2.0.jar
+file.reference.jcommon-1.0.23.jar=release/modules/ext/jcommon-1.0.23.jar
file.reference.jdom-2.0.5-contrib.jar=release\\modules\\ext\\jdom-2.0.5-contrib.jar
file.reference.jdom-2.0.5.jar=release\\modules\\ext\\jdom-2.0.5.jar
file.reference.jericho-html-3.3.jar=release\\modules\\ext\\jericho-html-3.3.jar
+file.reference.jfreechart-1.0.19.jar=release/modules/ext/jfreechart-1.0.19.jar
file.reference.jgraphx-4.1.0.jar=release\\modules\\ext\\jgraphx-4.1.0.jar
file.reference.jline-0.9.94.jar=release\\modules\\ext\\jline-0.9.94.jar
file.reference.jsoup-1.10.3.jar=release\\modules\\ext\\jsoup-1.10.3.jar
@@ -86,7 +90,9 @@ file.reference.listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar=re
file.reference.log4j-1.2.16.jar=release\\modules\\ext\\log4j-1.2.16.jar
file.reference.mchange-commons-java-0.2.9.jar=release\\modules\\ext\\mchange-commons-java-0.2.9.jar
file.reference.metadata-extractor-2.11.0.jar=release\\modules\\ext\\metadata-extractor-2.11.0.jar
+file.reference.mockito-core-3.5.7.jar=release\\modules\\ext\\mockito-core-3.5.7.jar
file.reference.netty-3.7.0.Final.jar=release\\modules\\ext\\netty-3.7.0.Final.jar
+file.reference.objenesis-3.1.jar=release\\modules\\ext\\objenesis-3.1.jar
file.reference.okhttp-2.7.5.jar=release\\modules\\ext\\okhttp-2.7.5.jar
file.reference.okio-1.6.0.jar=release\\modules\\ext\\okio-1.6.0.jar
file.reference.opencensus-api-0.19.2.jar=release\\modules\\ext\\opencensus-api-0.19.2.jar
@@ -102,8 +108,8 @@ file.reference.protobuf-java-util-3.7.0.jar=release\\modules\\ext\\protobuf-java
file.reference.Rejistry-1.1-SNAPSHOT.jar=release\\modules\\ext\\Rejistry-1.1-SNAPSHOT.jar
file.reference.sevenzipjbinding-AllPlatforms.jar=release\\modules\\ext\\sevenzipjbinding-AllPlatforms.jar
file.reference.sevenzipjbinding.jar=release\\modules\\ext\\sevenzipjbinding.jar
-file.reference.sleuthkit-4.10.0.jar=release\\modules\\ext\\sleuthkit-4.10.0.jar
-file.reference.sleuthkit-caseuco-4.10.0.jar=release\\modules\\ext\\sleuthkit-caseuco-4.10.0.jar
+file.reference.sleuthkit-4.10.1.jar=release/modules/ext/sleuthkit-4.10.1.jar
+file.reference.sleuthkit-caseuco-4.10.1.jar=release/modules/ext/sleuthkit-caseuco-4.10.1.jar
file.reference.slf4j-api-1.7.6.jar=release\\modules\\ext\\slf4j-api-1.7.6.jar
file.reference.slf4j-log4j12-1.7.6.jar=release\\modules\\ext\\slf4j-log4j12-1.7.6.jar
file.reference.SparseBitSet-1.1.jar=release\\modules\\ext\\SparseBitSet-1.1.jar
@@ -120,5 +126,4 @@ nbm.homepage=http://www.sleuthkit.org/
nbm.module.author=Brian Carrier
nbm.needs.restart=true
source.reference.curator-recipes-2.8.0.jar=release/modules/ext/curator-recipes-2.8.0-sources.jar
-spec.version.base=10.21
-
+spec.version.base=10.22
diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index 1945cdeff4..30cbbc7aa5 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -399,6 +399,10 @@
ext/proto-google-cloud-translate-v3beta1-0.53.0.jar
release\modules\ext\proto-google-cloud-translate-v3beta1-0.53.0.jar
+
+ ext/byte-buddy-1.10.13.jar
+ release\modules\ext\byte-buddy-1.10.13.jar
+
ext/error_prone_annotations-2.3.2.jar
release\modules\ext\error_prone_annotations-2.3.2.jar
@@ -439,14 +443,6 @@
ext/jxmapviewer2-2.4.jar
release\modules\ext\jxmapviewer2-2.4.jar
-
- ext/jfreechart-1.0.19.jar
- release/modules/ext/jfreechart-1.0.19.jar
-
-
- ext/jcommon-1.0.23.jar
- release/modules/ext/jcommon-1.0.23.jar
-
ext/jdom-2.0.5-contrib.jar
release\modules\ext\jdom-2.0.5-contrib.jar
@@ -552,24 +548,16 @@
release\modules\ext\checker-compat-qual-2.5.3.jar
- ext/sleuthkit-4.10.0.jar
- release\modules\ext\sleuthkit-4.10.0.jar
+ ext/sleuthkit-4.10.1.jar
+ release/modules/ext/sleuthkit-4.10.1.jar
ext/animal-sniffer-annotations-1.17.jar
release\modules\ext\animal-sniffer-annotations-1.17.jar
- ext/sleuthkit-caseuco-4.10.0.jar
- release\modules\ext\sleuthkit-caseuco-4.10.0.jar
-
-
- ext/sleuthkit-4.10.0.jar
- release/modules/ext/sleuthkit-4.10.0.jar
-
-
- ext/sleuthkit-caseuco-4.10.0.jar
- release/modules/ext/sleuthkit-caseuco-4.10.0.jar
+ ext/sleuthkit-caseuco-4.10.1.jar
+ release/modules/ext/sleuthkit-caseuco-4.10.1.jar
ext/gax-1.44.0.jar
@@ -611,6 +599,10 @@
ext/decodetect-core-0.3.jar
release\modules\ext\decodetect-core-0.3.jar
+
+ ext/mockito-core-3.5.7.jar
+ release\modules\ext\mockito-core-3.5.7.jar
+
ext/httpclient-4.5.5.jar
release\modules\ext\httpclient-4.5.5.jar
@@ -623,6 +615,10 @@
ext/jackson-annotations-2.9.0.jar
release\modules\ext\jackson-annotations-2.9.0.jar
+
+ ext/objenesis-3.1.jar
+ release\modules\ext\objenesis-3.1.jar
+
ext/jackson-core-2.9.7.jar
release\modules\ext\jackson-core-2.9.7.jar
@@ -715,6 +711,10 @@
ext/netty-3.7.0.Final.jar
release\modules\ext\netty-3.7.0.Final.jar
+
+ ext/jfreechart-1.0.19.jar
+ release/modules/ext/jfreechart-1.0.19.jar
+
ext/opencensus-contrib-grpc-metrics-0.19.2.jar
release\modules\ext\opencensus-contrib-grpc-metrics-0.19.2.jar
@@ -743,6 +743,10 @@
ext/javax.ws.rs-api-2.0.jar
release\modules\ext\javax.ws.rs-api-2.0.jar
+
+ ext/jcommon-1.0.23.jar
+ release/modules/ext/jcommon-1.0.23.jar
+
ext/icepdf-core-6.2.2.jar
release\modules\ext\icepdf-core-6.2.2.jar
@@ -795,6 +799,10 @@
ext/jutf7-1.0.0.jar
release\modules\ext\jutf7-1.0.0.jar
+
+ ext/byte-buddy-agent-1.10.13.jar
+ release\modules\ext\byte-buddy-agent-1.10.13.jar
+
ext/batik-awt-util-1.6.jar
release\modules\ext\batik-awt-util-1.6.jar
diff --git a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
index a3a13c0cff..507e079cad 100755
--- a/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/actions/Bundle.properties-MERGED
@@ -14,6 +14,7 @@ AddContentTagAction.taggingErr=Tagging Error
AddContentTagAction.unableToTag.msg=Unable to tag {0}, not a regular file.
# {0} - fileName
AddContentTagAction.unableToTag.msg2=Unable to tag {0}.
+CTL_DumpThreadAction=Thread Dump
CTL_ShowIngestProgressSnapshotAction=Ingest Status Details
DeleteBlackboardArtifactTagAction.deleteTag=Remove Selected Tag(s)
DeleteBlackboardArtifactTagAction.tagDelErr=Tag Deletion Error
diff --git a/Core/src/org/sleuthkit/autopsy/actions/OpenLogFolderAction.java b/Core/src/org/sleuthkit/autopsy/actions/OpenLogFolderAction.java
index fb178c797d..92b04140c3 100644
--- a/Core/src/org/sleuthkit/autopsy/actions/OpenLogFolderAction.java
+++ b/Core/src/org/sleuthkit/autopsy/actions/OpenLogFolderAction.java
@@ -44,7 +44,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
* This action should only be invoked in the event dispatch thread (EDT).
*/
@ActionRegistration(displayName = "#CTL_OpenLogFolder", iconInMenu = true)
-@ActionReference(path = "Menu/Help", position = 1750)
+@ActionReference(path = "Menu/Help", position = 2000)
@ActionID(id = "org.sleuthkit.autopsy.actions.OpenLogFolderAction", category = "Help")
public final class OpenLogFolderAction implements ActionListener {
diff --git a/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java b/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java
new file mode 100755
index 0000000000..d74511996c
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/actions/ThreadDumpAction.java
@@ -0,0 +1,156 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2020 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * 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.
+ */
+package org.sleuthkit.autopsy.actions;
+
+import java.awt.Desktop;
+import java.awt.event.ActionListener;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+import java.util.stream.Collectors;
+import javax.swing.SwingWorker;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle.Messages;
+import org.openide.util.actions.CallableSystemAction;
+import org.sleuthkit.autopsy.casemodule.Case;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+
+/**
+ * Action class for the Thread Dump help menu item. If there is no case open the
+ * dump file will be created in PlatformUtil.getLogDirectory() otherwise the
+ * file will be created in Case.getCurrentCase().getLogDirectoryPath()
+ */
+@ActionID(category = "Help", id = "org.sleuthkit.autopsy.actions.ThreadDumpAction")
+@ActionRegistration(displayName = "#CTL_DumpThreadAction", lazy = false)
+@ActionReference(path = "Menu/Help", position = 1750)
+@Messages({
+ "CTL_DumpThreadAction=Thread Dump"
+})
+public final class ThreadDumpAction extends CallableSystemAction implements ActionListener {
+
+ private static final long serialVersionUID = 1L;
+ private static final Logger logger = Logger.getLogger(ThreadDumpAction.class.getName());
+
+ private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss-SSSS");
+
+ @Override
+ public void performAction() {
+ (new ThreadDumper()).run();
+ }
+
+ @Override
+ public String getName() {
+ return Bundle.CTL_DumpThreadAction();
+ }
+
+ @Override
+ public HelpCtx getHelpCtx() {
+ return HelpCtx.DEFAULT_HELP;
+ }
+
+ /**
+ * SwingWorker to that will create the thread dump file. Once the file is
+ * created it will be opened in an external viewer.
+ */
+ private final class ThreadDumper extends SwingWorker {
+
+ @Override
+ protected File doInBackground() throws Exception {
+ return createThreadDump();
+ }
+
+ @Override
+ protected void done() {
+ File dumpFile = null;
+ try {
+ dumpFile = get();
+ Desktop.getDesktop().open(dumpFile);
+ } catch (ExecutionException | InterruptedException ex) {
+ logger.log(Level.SEVERE, "Failure occurred while creating thread dump file", ex);
+ } catch (IOException ex) {
+ if (dumpFile != null) {
+ logger.log(Level.WARNING, "Failed to open thread dump file in external viewer: " + dumpFile.getAbsolutePath(), ex);
+ } else {
+ logger.log(Level.SEVERE, "Failed to create thread dump file.", ex);
+ }
+ }
+ }
+
+ /**
+ * Create the thread dump file.
+ *
+ * @throws IOException
+ */
+ private File createThreadDump() throws IOException {
+ File dumpFile = createFilePath().toFile();
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(dumpFile, true))) {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100);
+ for (ThreadInfo threadInfo : threadInfos) {
+ writer.write(threadInfo.toString());
+ writer.write("\n");
+ }
+
+ long[] deadlockThreadIds = threadMXBean.findDeadlockedThreads();
+ if (deadlockThreadIds != null) {
+ writer.write("-------------------List of Deadlocked Thread IDs ---------------------");
+ String idsList = (Arrays
+ .stream(deadlockThreadIds)
+ .boxed()
+ .collect(Collectors.toList()))
+ .stream().map(n -> String.valueOf(n))
+ .collect(Collectors.joining("-", "{", "}"));
+ writer.write(idsList);
+ }
+ }
+
+ return dumpFile;
+ }
+
+ /**
+ * Create the dump file path.
+ *
+ * @return Path for dump file.
+ */
+ private Path createFilePath() {
+ String fileName = "ThreadDump_" + DATE_FORMAT.format(new Date()) + ".txt";
+ if (Case.isCaseOpen()) {
+ return Paths.get(Case.getCurrentCase().getLogDirectoryPath(), fileName);
+ }
+ return Paths.get(PlatformUtil.getLogDirectory(), fileName);
+ }
+ }
+
+}
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index 1e05403dd8..395310e600 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -107,7 +107,7 @@ import org.sleuthkit.autopsy.coreutils.Version;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.events.AutopsyEventException;
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
-import org.sleuthkit.autopsy.discovery.OpenDiscoveryAction;
+import org.sleuthkit.autopsy.discovery.ui.OpenDiscoveryAction;
import org.sleuthkit.autopsy.ingest.IngestJob;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestServices;
@@ -1468,9 +1468,16 @@ public class Case {
*/
public boolean hasData() {
boolean hasDataSources = false;
- try {
- hasDataSources = (getDataSources().size() > 0);
- } catch (TskCoreException ex) {
+ String query = "SELECT count(*) AS count FROM tsk_objects WHERE par_obj_id IS NULL";
+ try (SleuthkitCase.CaseDbQuery dbQuery = caseDb.executeQuery(query)) {
+ ResultSet resultSet = dbQuery.getResultSet();
+ if (resultSet.next()) {
+ long numDataSources = resultSet.getLong("count");
+ if (numDataSources > 0) {
+ hasDataSources = true;
+ }
+ }
+ } catch (TskCoreException | SQLException ex) {
logger.log(Level.SEVERE, "Error accessing case database", ex); //NON-NLS
}
return hasDataSources;
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
index a67b768492..c183e0de36 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/IngestJobInfoPanel.form
@@ -1,6 +1,11 @@