Force new MfApi tool build and MBean stop restart path.

Reject stale SonicMfContainerTool.class, print ToolVersion, prefer tool on classpath.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-24 10:22:39 +02:00
co-authored by Cursor
parent ada6b6ca83
commit 7a9cdb6ecf
6 changed files with 276 additions and 164 deletions
@@ -186,7 +186,32 @@ public sealed class SonicMfApiExecutor
"Hinweis: Container-Kurzname laut SMC ist 'ct-ZADBService' (nicht der Verbindungs-Alias DE-Test).";
}
return (false, combined.Length > 0 ? combined : null, err);
if (!combined.Contains("ToolVersion=", StringComparison.OrdinalIgnoreCase))
{
err +=
"\n\nWARN: Ausgabe enthält kein INFO:ToolVersion=… vermutlich alte SonicMfContainerTool.class.\n" +
"App neu bauen (Debug+Release), Tools-Ordner im Output prüfen, Temp esb-sonic-mf* löschen.";
}
// Volle Ausgabe mitliefern (INFO/WARN), nicht nur die ERROR-Zeile
string detail = string.IsNullOrWhiteSpace(combined) ? err : err + "\n\n--- Tool-Output ---\n" + combined;
return (false, combined.Length > 0 ? combined : null, detail);
}
private static void TryDeleteTempToolCache()
{
try
{
string dir = Path.Combine(Path.GetTempPath(), "esb-sonic-mf-j8");
if (Directory.Exists(dir))
{
Directory.Delete(dir, recursive: true);
}
}
catch
{
/* ignore */
}
}
private async Task<(bool Ok, string? JavaExe, string? ClassDir, string? Classpath, string? Error)>
@@ -246,11 +271,14 @@ public sealed class SonicMfApiExecutor
return (false, null, null, null, libError);
}
// Vorcompilierte .class/.jar nur nutzen, wenn Class-Version zur Runtime passt.
// Vorcompilierte .class nur nutzen, wenn Class-Version passt.
// Tool-Verzeichnis ZUERST im Classpath, damit keine alte Klasse aus Temp/JAR gewinnt.
if (TryResolvePrebuiltTool(runtimeMajor, out string? prebuiltDir, out string? prebuiltEntry, out string? prebuiltError)
&& prebuiltDir is not null && prebuiltEntry is not null)
{
string classpath = libClasspath + Path.PathSeparator + prebuiltEntry;
// Veraltete Temp-Kopien entfernen (früheres Compile-Cache).
TryDeleteTempToolCache();
string classpath = prebuiltEntry + Path.PathSeparator + libClasspath;
return (true, javaExe, prebuiltDir, classpath, null);
}
@@ -264,6 +292,7 @@ public sealed class SonicMfApiExecutor
$"Runtime-Java: {javaExe} (class major max={runtimeMajor}).");
}
TryDeleteTempToolCache();
string workDir = Path.Combine(Path.GetTempPath(), "esb-sonic-mf-j8");
Directory.CreateDirectory(workDir);
@@ -273,7 +302,8 @@ public sealed class SonicMfApiExecutor
File.Copy(sourcePath, javaTarget, overwrite: true);
string compileClasspath = libClasspath;
string runtimeClasspath = libClasspath + Path.PathSeparator + workDir;
// workDir zuerst
string runtimeClasspath = workDir + Path.PathSeparator + libClasspath;
bool classOk = File.Exists(classFile)
&& ReadClassFileMajorVersion(classFile) is int existingMajor
@@ -375,13 +405,22 @@ public sealed class SonicMfApiExecutor
if (File.Exists(classFile))
{
int? major = ReadClassFileMajorVersion(classFile);
if (major is not null && major <= runtimeMajor)
// Alte Builds waren ~7KB; MBean-Stop-Tool ist >10KB.
long len = new FileInfo(classFile).Length;
if (major is not null && major <= runtimeMajor && len >= 10_000)
{
workDir = dir;
classpathEntry = dir;
return true;
}
if (major is not null && major <= runtimeMajor && len < 10_000)
{
error =
$"Tools\\SonicMfContainerTool.class ist veraltet ({len} Bytes). Bitte neu bauen/pullen (erwartet >=10000).";
continue;
}
error =
$"Tools\\SonicMfContainerTool.class ist zu neu (major={major}, braucht <={runtimeMajor} / Java 8).";
continue;