Fix: Verwende Saxon s9api statt Transform.main() um System.exit() zu vermeiden
Problem: Transform.main() ruft System.exit() auf, was den gesamten Worker-Prozess beendet Lösung: Umstellung auf Saxon s9api (programmatische API): - Verwendet Processor, XsltCompiler, XsltExecutable, Xslt30Transformer - Wirft SaxonApiException statt System.exit() aufzurufen - Processor wird einmalig erstellt und wiederverwendet (Performance!) - Parameter-Handling mit QName und XdmValue - Serializer für Ausgabe statt Kommandozeilen-Args Dies sollte die Worker-Crashes vollständig beheben. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+51
-42
@@ -17,7 +17,8 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# Java-Worker-Code (wird zur Laufzeit kompiliert)
|
# Java-Worker-Code (wird zur Laufzeit kompiliert)
|
||||||
SAXON_WORKER_JAVA = """
|
SAXON_WORKER_JAVA = """
|
||||||
import net.sf.saxon.Transform;
|
import net.sf.saxon.s9api.*;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -26,7 +27,10 @@ public class SaxonWorker {
|
|||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
System.err.println("SaxonWorker started and ready");
|
// Create Saxon Processor (reusable)
|
||||||
|
Processor processor = new Processor(false);
|
||||||
|
|
||||||
|
System.err.println("SaxonWorker started and ready (using s9api)");
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -58,62 +62,67 @@ public class SaxonWorker {
|
|||||||
String xslStylesheet = parts[1];
|
String xslStylesheet = parts[1];
|
||||||
String outputFo = parts[2];
|
String outputFo = parts[2];
|
||||||
|
|
||||||
System.err.println("DEBUG: Building Saxon args...");
|
System.err.println("DEBUG: Files - XML: " + sourceXml);
|
||||||
|
System.err.println("DEBUG: Files - XSL: " + xslStylesheet);
|
||||||
|
System.err.println("DEBUG: Files - OUT: " + outputFo);
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
|
|
||||||
// Build Saxon arguments
|
// Parse parameters if present
|
||||||
List<String> saxonArgs = new ArrayList<>();
|
Map<String, String> xsltParams = new HashMap<>();
|
||||||
saxonArgs.add("-s:" + sourceXml);
|
|
||||||
saxonArgs.add("-xsl:" + xslStylesheet);
|
|
||||||
saxonArgs.add("-o:" + outputFo);
|
|
||||||
|
|
||||||
// Add parameters if present
|
|
||||||
if (parts.length > 3 && !parts[3].isEmpty()) {
|
if (parts.length > 3 && !parts[3].isEmpty()) {
|
||||||
String[] params = parts[3].split("\\\\|\\\\|\\\\|");
|
String[] params = parts[3].split("\\\\|\\\\|\\\\|");
|
||||||
for (String param : params) {
|
for (String param : params) {
|
||||||
if (!param.isEmpty()) {
|
if (!param.isEmpty() && param.contains("=")) {
|
||||||
saxonArgs.add(param);
|
String[] kv = param.split("=", 2);
|
||||||
|
xsltParams.put(kv[0], kv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
System.err.println("DEBUG: Parameters: " + xsltParams.size());
|
||||||
System.err.println("DEBUG: Running Saxon transformation...");
|
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
|
|
||||||
// Redirect Saxon output to stderr to avoid polluting stdout
|
System.err.println("DEBUG: Compiling stylesheet...");
|
||||||
PrintStream oldOut = System.out;
|
System.err.flush();
|
||||||
PrintStream oldErr = System.err;
|
|
||||||
ByteArrayOutputStream saxonOut = new ByteArrayOutputStream();
|
|
||||||
ByteArrayOutputStream saxonErr = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
try {
|
// Compile stylesheet (s9api)
|
||||||
System.setOut(new PrintStream(saxonOut));
|
XsltCompiler compiler = processor.newXsltCompiler();
|
||||||
System.setErr(new PrintStream(saxonErr));
|
XsltExecutable executable = compiler.compile(new StreamSource(new File(xslStylesheet)));
|
||||||
|
|
||||||
// Run Saxon transformation
|
System.err.println("DEBUG: Creating transformer...");
|
||||||
Transform.main(saxonArgs.toArray(new String[0]));
|
System.err.flush();
|
||||||
|
|
||||||
// Restore streams
|
// Create transformer
|
||||||
System.setOut(oldOut);
|
Xslt30Transformer transformer = executable.load30();
|
||||||
System.setErr(oldErr);
|
|
||||||
|
|
||||||
oldErr.println("DEBUG: Saxon transformation completed");
|
// Set parameters
|
||||||
oldErr.flush();
|
if (!xsltParams.isEmpty()) {
|
||||||
|
Map<QName, XdmValue> params = new HashMap<>();
|
||||||
// Send success response
|
for (Map.Entry<String, String> param : xsltParams.entrySet()) {
|
||||||
System.out.println("OK");
|
params.put(new QName(param.getKey()), XdmValue.makeValue(param.getValue()));
|
||||||
System.out.flush();
|
}
|
||||||
|
transformer.setStylesheetParameters(params);
|
||||||
} catch (Exception e) {
|
|
||||||
System.setOut(oldOut);
|
|
||||||
System.setErr(oldErr);
|
|
||||||
oldErr.println("DEBUG: Saxon exception: " + e.getClass().getName());
|
|
||||||
oldErr.flush();
|
|
||||||
e.printStackTrace(oldErr);
|
|
||||||
System.out.println("ERROR: " + (e.getMessage() != null ? e.getMessage() : e.getClass().getName()));
|
|
||||||
System.out.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.err.println("DEBUG: Running transformation...");
|
||||||
|
System.err.flush();
|
||||||
|
|
||||||
|
// Run transformation
|
||||||
|
Serializer serializer = processor.newSerializer(new File(outputFo));
|
||||||
|
transformer.transform(new StreamSource(new File(sourceXml)), serializer);
|
||||||
|
|
||||||
|
System.err.println("DEBUG: Transformation completed successfully");
|
||||||
|
System.err.flush();
|
||||||
|
|
||||||
|
// Send success response
|
||||||
|
System.out.println("OK");
|
||||||
|
System.out.flush();
|
||||||
|
|
||||||
|
} catch (SaxonApiException e) {
|
||||||
|
System.err.println("DEBUG: Saxon API exception: " + e.getClass().getName());
|
||||||
|
System.err.flush();
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
System.out.println("ERROR: " + (e.getMessage() != null ? e.getMessage() : e.getClass().getName()));
|
||||||
|
System.out.flush();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("DEBUG: Job processing exception: " + e.getClass().getName());
|
System.err.println("DEBUG: Job processing exception: " + e.getClass().getName());
|
||||||
System.err.flush();
|
System.err.flush();
|
||||||
|
|||||||
Reference in New Issue
Block a user