Prefer Java 8+ runtime for MfApi; Sonic JRE is often too old.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -178,8 +178,28 @@ public sealed class SonicMfApiExecutor
|
||||
private async Task<(bool Ok, string? JavaExe, string? ClassDir, string? Classpath, string? Error)>
|
||||
PrepareToolAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Tool-Bytecode ist Java 8 (major 52). Sonic-mitgelieferte JREs sind oft Java 6/7 → unbrauchbar.
|
||||
// Deshalb: Runtime mit major>=52 bevorzugen (PATH/JAVA_HOME/Registry), Libs weiter aus SonicHome.
|
||||
const int minClassMajor = 52;
|
||||
|
||||
JavaDiscoveryResult javaResult = DiscoverJava();
|
||||
string? javaExe = javaResult.JavaExe;
|
||||
int runtimeMajor = javaExe is null
|
||||
? 0
|
||||
: await GetJavaClassMajorAsync(javaExe, cancellationToken);
|
||||
|
||||
if (javaExe is null || runtimeMajor < minClassMajor)
|
||||
{
|
||||
(string? newerJava, int newerMajor, List<string> probed) =
|
||||
await FindJavaWithMinimumMajorAsync(minClassMajor, cancellationToken);
|
||||
if (newerJava is not null)
|
||||
{
|
||||
javaExe = newerJava;
|
||||
runtimeMajor = newerMajor;
|
||||
javaResult.CheckedPaths.Add($"UPGRADE:RuntimeJava8+={newerJava} major={newerMajor}");
|
||||
}
|
||||
}
|
||||
|
||||
if (javaExe is null)
|
||||
{
|
||||
string sonicHome = string.IsNullOrWhiteSpace(_connection.SonicHome)
|
||||
@@ -188,20 +208,22 @@ public sealed class SonicMfApiExecutor
|
||||
string checkedList = javaResult.CheckedPaths.Count == 0
|
||||
? "(keine Kandidaten gesammelt)"
|
||||
: string.Join("\n - ", javaResult.CheckedPaths.Take(MaxCheckedPathsInError));
|
||||
if (javaResult.CheckedPaths.Count > MaxCheckedPathsInError)
|
||||
{
|
||||
checkedList += $"\n - … (+{javaResult.CheckedPaths.Count - MaxCheckedPathsInError} weitere)";
|
||||
}
|
||||
|
||||
return (false, null, null, null,
|
||||
"Java nicht gefunden.\n" +
|
||||
$"Verwendetes SonicHome: '{sonicHome}'\n" +
|
||||
$"SonicHome existiert: {(Directory.Exists(sonicHome) ? "ja" : "nein")}\n" +
|
||||
"Konfiguration: SonicConnection.JavaHome / JavaPath, sonst Auto-Suche " +
|
||||
"(JAVA_HOME/JRE_HOME, setenv.bat, rekursiv unter SonicHome, MQ/ESB-Nachbarn, Registry, where).\n" +
|
||||
"Geprüfte Pfade:\n - " + checkedList + "\n" +
|
||||
"Tipp: JavaHome oder JavaPath in appsettings auf die echte java.exe setzen " +
|
||||
"(z.B. C:\\Sonic\\MQ10.0\\jre\\bin\\java.exe).");
|
||||
"Konfiguration: JavaPath/JavaHome auf eine Java-8+-Runtime setzen.\n" +
|
||||
"Geprüfte Pfade:\n - " + checkedList);
|
||||
}
|
||||
|
||||
if (runtimeMajor < minClassMajor)
|
||||
{
|
||||
return (false, null, null, null,
|
||||
"Gefundene Java-Runtime ist zu alt für SonicMfContainerTool (braucht Java 8 / major 52).\n" +
|
||||
$"Aktuell: {javaExe} (class major={runtimeMajor}).\n" +
|
||||
"Die JRE unter SonicHome ist oft Java 6/7 – bitte Java 8+ installieren und in appsettings setzen:\n" +
|
||||
" \"JavaPath\": \"C:\\\\Program Files\\\\Java\\\\jre1.8.0_xxx\\\\bin\\\\java.exe\"\n" +
|
||||
"Sonic-Client-JARs bleiben unter SonicHome\\lib.");
|
||||
}
|
||||
|
||||
(string? libDir, string? libError) = ResolveLibDirectoryDetailed();
|
||||
@@ -210,9 +232,6 @@ public sealed class SonicMfApiExecutor
|
||||
return (false, null, null, null, libError);
|
||||
}
|
||||
|
||||
int runtimeMajor = await GetJavaClassMajorAsync(javaExe, cancellationToken);
|
||||
// Sonic/SMC nutzt typisch Java 8 (major 52). Nie mit höherer Class-Version starten.
|
||||
|
||||
// Vorcompilierte .class/.jar nur nutzen, wenn Class-Version zur Runtime passt.
|
||||
if (TryResolvePrebuiltTool(runtimeMajor, out string? prebuiltDir, out string? prebuiltEntry, out string? prebuiltError)
|
||||
&& prebuiltDir is not null && prebuiltEntry is not null)
|
||||
@@ -385,32 +404,119 @@ public sealed class SonicMfApiExecutor
|
||||
using Process p = new() { StartInfo = psi };
|
||||
if (!p.Start())
|
||||
{
|
||||
return 52; // Sonic-Default Java 8
|
||||
return 0;
|
||||
}
|
||||
|
||||
string err = await p.StandardError.ReadToEndAsync(cancellationToken);
|
||||
string output = await p.StandardOutput.ReadToEndAsync(cancellationToken);
|
||||
await p.WaitForExitAsync(cancellationToken);
|
||||
string text = (err + "\n" + output).ToLowerInvariant();
|
||||
|
||||
if (text.Contains("version \"1.8") || text.Contains("version \"8"))
|
||||
{
|
||||
return 52;
|
||||
}
|
||||
|
||||
Match m = Regex.Match(text, @"version ""(\d+)");
|
||||
if (m.Success && int.TryParse(m.Groups[1].Value, out int major) && major >= 9)
|
||||
{
|
||||
// Java 9+ class major = 44 + version => 9→53, 11→55, 17→61, 21→65
|
||||
return 44 + major;
|
||||
}
|
||||
return ParseJavaVersionToClassMajor(err + "\n" + output);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static int ParseJavaVersionToClassMajor(string versionText)
|
||||
{
|
||||
string text = versionText.ToLowerInvariant();
|
||||
|
||||
// 1.8.x → 52, 1.7.x → 51, 1.6.x → 50
|
||||
Match legacy = Regex.Match(text, @"version\s+""1\.(\d+)");
|
||||
if (legacy.Success && int.TryParse(legacy.Groups[1].Value, out int minor))
|
||||
{
|
||||
return 44 + minor; // 1.6→50, 1.7→51, 1.8→52
|
||||
}
|
||||
|
||||
return 52;
|
||||
Match modern = Regex.Match(text, @"version\s+""(\d+)");
|
||||
if (modern.Success && int.TryParse(modern.Groups[1].Value, out int major) && major >= 9)
|
||||
{
|
||||
return 44 + major; // 9→53 … 21→65
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sucht eine java.exe mit mindestens der gewünschten Class-Major-Version
|
||||
/// (für Tool-Bytecode Java 8 = 52), unabhängig von der alten Sonic-JRE.
|
||||
/// </summary>
|
||||
private async Task<(string? JavaExe, int Major, List<string> Probed)> FindJavaWithMinimumMajorAsync(
|
||||
int minMajor,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
List<string> probed = [];
|
||||
List<string> candidates = [];
|
||||
|
||||
void AddCandidate(string? path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string full = Path.GetFullPath(path);
|
||||
if (!candidates.Contains(full, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
candidates.Add(full);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string? configured in new[] { _connection.JavaPath, _connection.JavaHome })
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(configured)) continue;
|
||||
AddCandidate(ResolveToolFromConfiguredPath(configured, JavaExeName, probed));
|
||||
}
|
||||
|
||||
foreach (string envName in new[] { "JAVA_HOME", "JRE_HOME", "JDK_HOME" })
|
||||
{
|
||||
AddCandidate(ResolveJavaFromHomeDir(Environment.GetEnvironmentVariable(envName), probed, envName));
|
||||
}
|
||||
|
||||
AddCandidate(FindOnPath(JavaExeName, probed));
|
||||
AddCandidate(FindOnPath("java", probed));
|
||||
AddCandidate(FindJavaInWindowsRegistry(probed));
|
||||
AddCandidate(FindJavaViaWhereExe(probed));
|
||||
AddCandidate(FindJavaInCommonInstallLocations(probed));
|
||||
|
||||
// Program Files Java/Adoptium/Temurin grob scannen
|
||||
foreach (string root in new[]
|
||||
{
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
|
||||
@"C:\Program Files\Eclipse Adoptium",
|
||||
@"C:\Program Files\Java",
|
||||
@"C:\Program Files\Microsoft",
|
||||
@"C:\Program Files\Amazon Corretto"
|
||||
})
|
||||
{
|
||||
if (!Directory.Exists(root)) continue;
|
||||
try
|
||||
{
|
||||
foreach (string javaExe in Directory.EnumerateFiles(root, "java.exe", SearchOption.AllDirectories)
|
||||
.Take(40))
|
||||
{
|
||||
AddCandidate(javaExe);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string candidate in candidates)
|
||||
{
|
||||
int major = await GetJavaClassMajorAsync(candidate, cancellationToken);
|
||||
probed.Add($"{candidate} => major={major}");
|
||||
if (major >= minMajor)
|
||||
{
|
||||
return (candidate, major, probed);
|
||||
}
|
||||
}
|
||||
|
||||
return (null, 0, probed);
|
||||
}
|
||||
|
||||
private static bool SupportsJavacRelease8(string javacPath)
|
||||
|
||||
Reference in New Issue
Block a user