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 d8ee89b143 TIKA-4647 - use an argfile to launch PipesServer (#2579)
d8ee89b143 is described below
commit d8ee89b143e0d7277cf2fa50cd1d26ed54871a5d
Author: Tim Allison <[email protected]>
AuthorDate: Tue Feb 3 08:00:25 2026 -0500
TIKA-4647 - use an argfile to launch PipesServer (#2579)
* TIKA-4647 - use an argfile to launch PipesServer
---
.../org/apache/tika/pipes/core/PipesClient.java | 36 ++++++++++++++++++++--
1 file changed, 33 insertions(+), 3 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 5c175208ab..82e37cb31d 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
@@ -533,7 +533,7 @@ public class PipesClient implements Closeable {
}
}
- private String[] getCommandline(int port, Path tmpDir) {
+ private String[] getCommandline(int port, Path tmpDir) throws IOException {
List<String> configArgs = pipesConfig.getForkedJvmArgs();
boolean hasClassPath = false;
boolean hasHeadless = false;
@@ -568,10 +568,14 @@ public class PipesClient implements Closeable {
List<String> commandLine = new ArrayList<>();
String javaPath = pipesConfig.getJavaPath();
commandLine.add(ProcessUtils.escapeCommandLine(javaPath));
+
+ // Use @argfile to avoid Windows command line length limits (~8191
chars)
+ // when the classpath is very long (e.g., with Ignite3 dependencies)
if (!hasClassPath) {
- commandLine.add("-cp");
- commandLine.add(System.getProperty("java.class.path"));
+ Path argFile = writeArgFile(tmpDir);
+ commandLine.add("@" + argFile.toAbsolutePath());
}
+
if (!hasHeadless) {
commandLine.add("-Djava.awt.headless=true");
}
@@ -593,6 +597,32 @@ public class PipesClient implements Closeable {
return commandLine.toArray(new String[0]);
}
+ /**
+ * Writes an argfile containing the classpath for the forked JVM process.
+ * This avoids Windows command line length limits (~8191 chars) which can
+ * be exceeded when using dependencies with many transitive jars (e.g.,
Ignite3).
+ * <p>
+ * Security: The argfile is created in a temp directory with owner-only
permissions (700).
+ * This is more secure than the alternative of passing the classpath on
the command line,
+ * which would be visible to all users via 'ps' or /proc.
+ *
+ * @param tmpDir the temporary directory where the argfile will be created
+ * @return the path to the created argfile
+ * @throws IOException if the argfile cannot be written
+ */
+ private Path writeArgFile(Path tmpDir) throws IOException {
+ Path argFile = tmpDir.resolve("jvm-args.txt");
+ String classpath = System.getProperty("java.class.path");
+ //convert to forward for Windows compatibility
+ String normalizedClasspath = classpath.replace("\\", "/");
+ // Argfile format: each argument on its own line, with proper quoting
for paths with spaces
+ String content = "-cp\n\"" + normalizedClasspath + "\"\n";
+ Files.writeString(argFile, content, StandardCharsets.UTF_8);
+ LOG.debug("pipesClientId={}: wrote argfile with classpath ({} chars)
to {}",
+ pipesClientId, classpath.length(), argFile);
+ return argFile;
+ }
+
private record ServerTuple(Process process, ServerSocket serverSocket,
Socket socket,
DataInputStream input, DataOutputStream output,
Path tmpDir) {