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

ndipiazza pushed a commit to branch pf4j-development-mode
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/pf4j-development-mode by this 
push:
     new e74d3d14d TIKA-4587: Fix development mode to prevent scanning 
subdirectories
e74d3d14d is described below

commit e74d3d14d09f396cd3899ef7dbe1f374a40147cc
Author: Nicholas DiPiazza <[email protected]>
AuthorDate: Sun Dec 21 19:33:38 2025 -0600

    TIKA-4587: Fix development mode to prevent scanning subdirectories
    
    Override createPluginRepository() to prevent pf4j from scanning 
subdirectories
    in development mode. In dev mode, each path in plugin-roots should be 
treated
    as a complete plugin directory (target/classes), not as a container of 
plugins.
    
    This fixes the error:
    'No PluginDescriptorFinder for plugin .../target/classes/org'
    
    The default DevelopmentPluginRepository scans for subdirectories, but we 
want
    each configured path to be the plugin root itself.
---
 .run/TikaGrpcServer.run.xml                        |  3 ++-
 tika-grpc/test-config.json                         | 26 ++++++++++++++++++++++
 .../org/apache/tika/plugins/TikaPluginManager.java | 24 ++++++++++++++++++++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/.run/TikaGrpcServer.run.xml b/.run/TikaGrpcServer.run.xml
index c189e21be..f6862313e 100644
--- a/.run/TikaGrpcServer.run.xml
+++ b/.run/TikaGrpcServer.run.xml
@@ -2,7 +2,8 @@
   <configuration default="false" name="TikaGrpcServer" type="Application" 
factoryName="Application" nameIsGenerated="true">
     <option name="MAIN_CLASS_NAME" 
value="org.apache.tika.pipes.grpc.TikaGrpcServer" />
     <module name="tika-grpc" />
-    <option name="PROGRAM_PARAMETERS" value="--config 
src/test/resources/tika-pipes-test-config.json" />
+    <option name="PROGRAM_PARAMETERS" value="--config test-config.json" />
+    <option name="VM_PARAMETERS" value="-Dtika.plugin.dev.mode=true" />
     <option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
     <extension name="coverage">
       <pattern>
diff --git a/tika-grpc/test-config.json b/tika-grpc/test-config.json
new file mode 100644
index 000000000..bc560dedd
--- /dev/null
+++ b/tika-grpc/test-config.json
@@ -0,0 +1,26 @@
+{
+  "plugin-roots": [
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-csv/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-file-system/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-gcs/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-http/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-ignite/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-json/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-kafka/target/classes",
+    
"../tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-s3/target/classes",
+    "../tika-pipes/tika-pipes-plugins/tika-pipes-solr/target/classes"
+  ],
+  "fetchers": [
+    {
+      "fs": {
+        "myFetcher": {
+          "basePath": "/tmp/input"
+        }
+      }
+    }
+  ]
+}
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 0cd635660..eb500ef50 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
@@ -146,7 +146,10 @@ public class TikaPluginManager extends 
DefaultPluginManager {
 
     public TikaPluginManager(List<Path> pluginRoots) throws IOException {
         super(pluginRoots);
+        // Must configure runtime mode immediately after super() but before 
loading plugins
         configureRuntimeMode();
+        // Note: init() should NOT call loadPlugins() - let the caller do that 
explicitly
+        // This is because in DEPLOYMENT mode we need to unzip first
         init();
     }
     
@@ -186,6 +189,27 @@ public class TikaPluginManager extends 
DefaultPluginManager {
         // This will only discover extensions within the loaded plugin JARs.
         return new DefaultExtensionFinder(this);
     }
+    
+    /**
+     * Override to prevent scanning subdirectories in development mode.
+     * In development mode, the default DevelopmentPluginRepository scans for 
subdirectories,
+     * but we want each path in plugin-roots to be treated as a complete 
plugin directory.
+     */
+    @Override
+    protected org.pf4j.PluginRepository createPluginRepository() {
+        if (getRuntimeMode() == RuntimeMode.DEVELOPMENT) {
+            // In development mode, return a repository that treats each path 
as a plugin
+            return new org.pf4j.BasePluginRepository(getPluginsRoots()) {
+                @Override
+                public List<Path> getPluginPaths() {
+                    // Don't scan subdirectories - each configured path IS a 
plugin
+                    return new java.util.ArrayList<>(pluginsRoots);
+                }
+            };
+        }
+        // In deployment mode, use the default behavior
+        return super.createPluginRepository();
+    }
 
     private void init() throws IOException {
         if (getRuntimeMode() == RuntimeMode.DEPLOYMENT) {

Reply via email to