This is an automated email from the ASF dual-hosted git repository.

ndipiazza pushed a commit to branch TIKA-4581-plugin-roots-cli
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/TIKA-4581-plugin-roots-cli by 
this push:
     new ebafdaf10 TIKA-4581: Add --plugin-roots CLI parameter for tika-grpc
ebafdaf10 is described below

commit ebafdaf1001853a159e4c69cfd88a12233b1885b
Author: Nicholas DiPiazza <[email protected]>
AuthorDate: Fri Dec 26 16:17:03 2025 -0600

    TIKA-4581: Add --plugin-roots CLI parameter for tika-grpc
    
    Adds --plugin-roots command-line parameter to override plugin-roots from 
config file.
    
    Problem:
    Users had to include 'plugin-roots' in tika-config.json file, which made
    Docker deployments less flexible. Different environments might need 
different
    plugin locations.
    
    Solution:
    - Added --plugin-roots CLI parameter to TikaGrpcServer
    - Parameter accepts comma-separated list of plugin directories
    - CLI parameter overrides config file if specified
    - Falls back to config file if not specified
    
    Changes:
    - TikaGrpcServer: Added --plugin-roots parameter
    - TikaGrpcServerImpl: Updated constructor to accept pluginRootsOverride
    - TikaPluginManager: Added loadFromPaths() method for string-based paths
    
    Usage:
    java -jar tika-grpc.jar -c config.json --plugin-roots /tmp/tika-plugins
    
    Or Docker:
    docker run apache/tika-grpc:latest -c /config/config.json --plugin-roots 
/tmp/tika-plugins
    
    Benefits:
    - No need to modify config files for different environments
    - Simplifies Docker/Kubernetes deployments
    - Backward compatible - config file still works if CLI not specified
---
 .../org/apache/tika/pipes/grpc/TikaGrpcServer.java |  5 +++-
 .../apache/tika/pipes/grpc/TikaGrpcServerImpl.java | 12 ++++++++-
 .../org/apache/tika/plugins/TikaPluginManager.java | 31 ++++++++++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git 
a/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServer.java 
b/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServer.java
index 2b350e382..810f58961 100644
--- a/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServer.java
+++ b/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServer.java
@@ -49,6 +49,9 @@ public class TikaGrpcServer {
     @Parameter(names = {"-l", "--plugins"}, description = "The tika pipes 
plugins config file", help = true)
     private File tikaPlugins;
 
+    @Parameter(names = {"--plugin-roots"}, description = "Comma-separated list 
of plugin root directories (overrides config file)", help = true)
+    private String pluginRoots;
+
     @Parameter(names = {"-s", "--secure"}, description = "Enable credentials 
required to access this grpc server")
     private boolean secure;
 
@@ -93,7 +96,7 @@ public class TikaGrpcServer {
         healthStatusManager.setStatus(TikaGrpcServer.class.getSimpleName(), 
ServingStatus.SERVING);
         server = Grpc
                 .newServerBuilderForPort(port, creds)
-                .addService(new 
TikaGrpcServerImpl(tikaConfigFile.getAbsolutePath()))
+                .addService(new 
TikaGrpcServerImpl(tikaConfigFile.getAbsolutePath(), pluginRoots))
                 .addService(healthStatusManager.getHealthService())
                 .addService(ProtoReflectionServiceV1.newInstance())
                 .build()
diff --git 
a/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServerImpl.java 
b/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServerImpl.java
index de318e3fb..aa102a42a 100644
--- a/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServerImpl.java
+++ b/tika-grpc/src/main/java/org/apache/tika/pipes/grpc/TikaGrpcServerImpl.java
@@ -83,6 +83,10 @@ class TikaGrpcServerImpl extends TikaGrpc.TikaImplBase {
     PluginManager pluginManager;
 
     TikaGrpcServerImpl(String tikaConfigPath) throws TikaConfigException, 
IOException {
+        this(tikaConfigPath, null);
+    }
+
+    TikaGrpcServerImpl(String tikaConfigPath, String pluginRootsOverride) 
throws TikaConfigException, IOException {
         File tikaConfigFile = new File(tikaConfigPath);
         if (!tikaConfigFile.exists()) {
             throw new TikaConfigException("Tika config file does not exist: " 
+ tikaConfigPath);
@@ -102,7 +106,13 @@ class TikaGrpcServerImpl extends TikaGrpc.TikaImplBase {
         pipesClient = new PipesClient(pipesConfig, configPath);
         
         try {
-            pluginManager = TikaPluginManager.load(tikaJsonConfig);
+            if (pluginRootsOverride != null && 
!pluginRootsOverride.trim().isEmpty()) {
+                // Use command-line plugin roots
+                pluginManager = 
TikaPluginManager.loadFromPaths(pluginRootsOverride);
+            } else {
+                // Use plugin roots from config file
+                pluginManager = TikaPluginManager.load(tikaJsonConfig);
+            }
             pluginManager.loadPlugins();
             pluginManager.startPlugins();
         } catch (TikaConfigException e) {
diff --git 
a/tika-plugins-core/src/main/java/org/apache/tika/plugins/TikaPluginManager.java
 
b/tika-plugins-core/src/main/java/org/apache/tika/plugins/TikaPluginManager.java
index 638ed5b59..423b84b97 100644
--- 
a/tika-plugins-core/src/main/java/org/apache/tika/plugins/TikaPluginManager.java
+++ 
b/tika-plugins-core/src/main/java/org/apache/tika/plugins/TikaPluginManager.java
@@ -134,6 +134,37 @@ public class TikaPluginManager extends 
DefaultPluginManager {
         return new TikaPluginManager(roots);
     }
 
+    /**
+     * Loads plugin manager from a comma-separated string of paths.
+     *
+     * @param pathsString comma-separated list of plugin root directories
+     * @return the plugin manager
+     * @throws TikaConfigException if configuration is invalid
+     * @throws IOException if reading or plugin initialization fails
+     */
+    public static TikaPluginManager loadFromPaths(String pathsString) 
+            throws TikaConfigException, IOException {
+        if (pathsString == null || pathsString.trim().isEmpty()) {
+            throw new TikaConfigException("plugin-roots must not be empty");
+        }
+        
+        configurePf4jRuntimeMode();
+        
+        List<Path> roots = new java.util.ArrayList<>();
+        for (String path : pathsString.split(",")) {
+            String trimmed = path.trim();
+            if (!trimmed.isEmpty()) {
+                roots.add(java.nio.file.Paths.get(trimmed));
+            }
+        }
+        
+        if (roots.isEmpty()) {
+            throw new TikaConfigException("plugin-roots must not be empty");
+        }
+        
+        return new TikaPluginManager(roots);
+    }
+
     /**
      * Loads plugin manager from a configuration file.
      *

Reply via email to