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<>();

Reply via email to