diff --git a/tika-grpc/pom.xml b/tika-grpc/pom.xml
index a30fb0c3fe..88d919936f 100644
--- a/tika-grpc/pom.xml
+++ b/tika-grpc/pom.xml
@@ -299,6 +299,83 @@
zip
true
+
+ org.apache.tika
+ tika-pipes-az-blob
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-csv
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-gcs
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-ignite
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-jdbc
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-json
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-kafka
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-microsoft-graph
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-opensearch
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-s3
+ ${project.version}
+ zip
+ true
+
+
+ org.apache.tika
+ tika-pipes-solr
+ ${project.version}
+ zip
+ true
+
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 2b350e3824..810f58961c 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 void start() throws Exception {
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 de318e3fbb..aa102a42ac 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-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/assembly/assembly.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/assembly/assembly.xml
index 0b8fe6e794..35755f0d13 100644
--- a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/assembly/assembly.xml
+++ b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/assembly/assembly.xml
@@ -1,45 +1,64 @@
-
- plugin
-
- zip
-
- true
- ${project.artifactId}-${project.version}
-
-
- ${project.build.directory}
- /
-
- ${project.artifactId}-${project.version}.jar
-
-
-
- ${project.build.directory}/lib
- /lib
-
- *.jar
-
-
-
+
+ dependencies-zip
+
+ zip
+
+ false
+
+
+ /
+ true
+ true
+ runtime
+
+ ${project.groupId}:${project.artifactId}
+
+
+
+ META-INF/MANIFEST.MF
+ META-INF/extensions.idx
+
+
+
+
+
+
+ ${project.build.directory}/lib
+ /lib
+
+
+ ${project.build.directory}
+ /lib
+
+ ${project.artifactId}-${project.version}.jar
+
+
+
+ ${project.basedir}/src/main/resources
+ /
+
+ plugin.properties
+
+
+
diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/assembly/assembly.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/assembly/assembly.xml
index 0b8fe6e794..35755f0d13 100644
--- a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/assembly/assembly.xml
+++ b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/assembly/assembly.xml
@@ -1,45 +1,64 @@
-
- plugin
-
- zip
-
- true
- ${project.artifactId}-${project.version}
-
-
- ${project.build.directory}
- /
-
- ${project.artifactId}-${project.version}.jar
-
-
-
- ${project.build.directory}/lib
- /lib
-
- *.jar
-
-
-
+
+ dependencies-zip
+
+ zip
+
+ false
+
+
+ /
+ true
+ true
+ runtime
+
+ ${project.groupId}:${project.artifactId}
+
+
+
+ META-INF/MANIFEST.MF
+ META-INF/extensions.idx
+
+
+
+
+
+
+ ${project.build.directory}/lib
+ /lib
+
+
+ ${project.build.directory}
+ /lib
+
+ ${project.artifactId}-${project.version}.jar
+
+
+
+ ${project.basedir}/src/main/resources
+ /
+
+ plugin.properties
+
+
+
diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/resources/plugin.properties b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/resources/plugin.properties
index fa83efcfb7..0102ccbe20 100644
--- a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/resources/plugin.properties
+++ b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/resources/plugin.properties
@@ -15,7 +15,7 @@
# limitations under the License.
plugin.id=tika-pipes-gcs-plugin
-plugin.class=org.apache.tika.pipes.emitter.gcs.GCSEmitterPlugin
+plugin.class=org.apache.tika.pipes.plugin.gcs.GCSPipesPlugin
plugin.version=4.0.0-SNAPSHOT
plugin.provider=Apache Tika
plugin.description=Pipes for the Google Cloud Storage
diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/assembly/assembly.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/assembly/assembly.xml
index 0b8fe6e794..35755f0d13 100644
--- a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/assembly/assembly.xml
+++ b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/assembly/assembly.xml
@@ -1,45 +1,64 @@
-
- plugin
-
- zip
-
- true
- ${project.artifactId}-${project.version}
-
-
- ${project.build.directory}
- /
-
- ${project.artifactId}-${project.version}.jar
-
-
-
- ${project.build.directory}/lib
- /lib
-
- *.jar
-
-
-
+
+ dependencies-zip
+
+ zip
+
+ false
+
+
+ /
+ true
+ true
+ runtime
+
+ ${project.groupId}:${project.artifactId}
+
+
+
+ META-INF/MANIFEST.MF
+ META-INF/extensions.idx
+
+
+
+
+
+
+ ${project.build.directory}/lib
+ /lib
+
+
+ ${project.build.directory}
+ /lib
+
+ ${project.artifactId}-${project.version}.jar
+
+
+
+ ${project.basedir}/src/main/resources
+ /
+
+ plugin.properties
+
+
+
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 638ed5b59a..423b84b97f 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 static TikaPluginManager load(TikaJsonConfig tikaJsonConfig)
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 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.
*