This is an automated email from the ASF dual-hosted git repository.
tallison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new c72dbc97c3 improve resource clean up -- directories from PipesClient
(#2532)
c72dbc97c3 is described below
commit c72dbc97c3976acbc5c49fa1d35cd4ad5274c030
Author: Tim Allison <[email protected]>
AuthorDate: Wed Jan 14 09:02:59 2026 -0500
improve resource clean up -- directories from PipesClient (#2532)
---
.../java/org/apache/tika/pipes/core/PipesClient.java | 14 ++++++++++++++
.../org/apache/tika/server/core/IntegrationTestBase.java | 10 ++++++++--
.../java/org/apache/tika/server/core/TikaPipesTest.java | 16 +++++++++++++++-
.../org/apache/tika/server/standard/TikaPipesTest.java | 16 +++++++++++++++-
4 files changed, 52 insertions(+), 4 deletions(-)
diff --git
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
index fda74a01c3..e79c35ccfe 100644
---
a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
+++
b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/PipesClient.java
@@ -95,6 +95,7 @@ public class PipesClient implements Closeable {
private final PipesConfig pipesConfig;
private final Path tikaConfigPath;
private final int pipesClientId;
+ private final Thread shutdownHook;
private ServerTuple serverTuple;
private int filesProcessed = 0;
@@ -102,6 +103,14 @@ public class PipesClient implements Closeable {
this.pipesConfig = pipesConfig;
this.tikaConfigPath = tikaConfigPath;
this.pipesClientId = CLIENT_COUNTER.getAndIncrement();
+ this.shutdownHook = new Thread(this::cleanupOnShutdown,
"PipesClient-shutdown-" + pipesClientId);
+ Runtime.getRuntime().addShutdownHook(shutdownHook);
+ }
+
+ private void cleanupOnShutdown() {
+ if (serverTuple != null && serverTuple.tmpDir != null) {
+ deleteDir(serverTuple.tmpDir);
+ }
}
public int getFilesProcessed() {
@@ -130,6 +139,11 @@ public class PipesClient implements Closeable {
@Override
public void close() throws IOException {
+ try {
+ Runtime.getRuntime().removeShutdownHook(shutdownHook);
+ } catch (IllegalStateException e) {
+ // JVM is already shutting down, ignore
+ }
try {
shutItAllDown();
} catch (InterruptedException e) {
diff --git
a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/IntegrationTestBase.java
b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/IntegrationTestBase.java
index b5b066207d..00173240ee 100644
---
a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/IntegrationTestBase.java
+++
b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/IntegrationTestBase.java
@@ -76,8 +76,14 @@ public class IntegrationTestBase extends TikaTest {
@AfterEach
public void tearDown() throws Exception {
if (process != null) {
- process.destroyForcibly();
- process.waitFor(30, TimeUnit.SECONDS);
+ // Try graceful shutdown first (SIGTERM) to allow shutdown hooks
to run
+ process.destroy();
+ boolean exited = process.waitFor(5, TimeUnit.SECONDS);
+ if (!exited) {
+ // Fall back to forceful shutdown (SIGKILL)
+ process.destroyForcibly();
+ process.waitFor(30, TimeUnit.SECONDS);
+ }
if (process.isAlive()) {
throw new RuntimeException("process still alive!");
}
diff --git
a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaPipesTest.java
b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaPipesTest.java
index ee899ab180..934bc044e4 100644
---
a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaPipesTest.java
+++
b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaPipesTest.java
@@ -44,6 +44,7 @@ import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -86,6 +87,8 @@ public class TikaPipesTest extends CXFTestBase {
private static String[] VALUE_ARRAY = new String[]{"my-value-1",
"my-value-2", "my-value-3"};
+ private PipesResource pipesResource;
+
@BeforeAll
public static void setUpBeforeClass() throws Exception {
TMP_DIR = Files.createTempDirectory("tika-pipes-test-");
@@ -117,6 +120,16 @@ public class TikaPipesTest extends CXFTestBase {
FileUtils.deleteDirectory(TMP_DIR.toFile());
}
+ @Override
+ @AfterEach
+ public void tearDown() throws Exception {
+ if (pipesResource != null) {
+ pipesResource.close();
+ pipesResource = null;
+ }
+ super.tearDown();
+ }
+
@BeforeEach
public void setUpEachTest() throws Exception {
if (Files.exists(TMP_OUTPUT_FILE)) {
@@ -132,7 +145,8 @@ public class TikaPipesTest extends CXFTestBase {
protected void setUpResources(JAXRSServerFactoryBean sf) {
List<ResourceProvider> rCoreProviders = new ArrayList<>();
try {
- rCoreProviders.add(new SingletonResourceProvider(new
PipesResource(TIKA_CONFIG_PATH)));
+ pipesResource = new PipesResource(TIKA_CONFIG_PATH);
+ rCoreProviders.add(new SingletonResourceProvider(pipesResource));
} catch (IOException | TikaConfigException e) {
throw new RuntimeException(e);
}
diff --git
a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaPipesTest.java
b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaPipesTest.java
index 078a83038e..0320ab5a9a 100644
---
a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaPipesTest.java
+++
b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/TikaPipesTest.java
@@ -42,6 +42,7 @@ import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -92,6 +93,8 @@ public class TikaPipesTest extends CXFTestBase {
private static Path TIKA_CONFIG_PATH;
private static FetcherManager FETCHER_MANAGER;
+ private PipesResource pipesResource;
+
@BeforeAll
public static void setUpBeforeClass() throws Exception {
Path inputDir = TMP_WORKING_DIR.resolve("input");
@@ -127,13 +130,24 @@ public class TikaPipesTest extends CXFTestBase {
protected void setUpResources(JAXRSServerFactoryBean sf) {
List<ResourceProvider> rCoreProviders = new ArrayList<>();
try {
- rCoreProviders.add(new SingletonResourceProvider(new
PipesResource(TIKA_CONFIG_PATH)));
+ pipesResource = new PipesResource(TIKA_CONFIG_PATH);
+ rCoreProviders.add(new SingletonResourceProvider(pipesResource));
} catch (IOException | TikaConfigException e) {
throw new RuntimeException(e);
}
sf.setResourceProviders(rCoreProviders);
}
+ @Override
+ @AfterEach
+ public void tearDown() throws Exception {
+ if (pipesResource != null) {
+ pipesResource.close();
+ pipesResource = null;
+ }
+ super.tearDown();
+ }
+
@Override
protected void setUpProviders(JAXRSServerFactoryBean sf) {
List<Object> providers = new ArrayList<>();