Fix MfApi ClassNotFound by passing Java classpath via ArgumentList.

Use ct-ZADBService and explicit MfClientLibPath so SMC restart finds client JARs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-24 10:16:01 +02:00
co-authored by Cursor
parent d27e721475
commit a89a7ad4b6
5 changed files with 349 additions and 109 deletions
@@ -1,12 +1,12 @@
[ [
{ {
"Id": 1, "Id": 1,
"Name": "DE-Test Container", "Name": "DE-Test / ct-ZADBService",
"Environment": "TEST", "Environment": "TEST",
"IsActive": true, "IsActive": true,
"TargetDirectory": "DeploySandbox/target-esb", "TargetDirectory": "DeploySandbox/target-esb",
"CertificateFileName": "esb-cert.cer", "CertificateFileName": "esb-cert.cer",
"ContainerName": "DE-Test", "ContainerName": "ct-ZADBService",
"RestartType": "SonicContainer", "RestartType": "SonicContainer",
"RestartCommand": "", "RestartCommand": "",
"RestartArguments": "", "RestartArguments": "",
@@ -345,16 +345,21 @@ public sealed class SonicManagementClient : IDisposable
$"Domain={_connection.DomainName}; ConnectionUrl={_connection.ConnectionUrl}\n{output}"); $"Domain={_connection.DomainName}; ConnectionUrl={_connection.ConnectionUrl}\n{output}");
} }
string libHint = string.IsNullOrWhiteSpace(_connection.MfClientLibPath)
? _connection.SonicHome
: _connection.MfClientLibPath;
return (false, "Neustart fehlgeschlagen (MfApi)", return (false, "Neustart fehlgeschlagen (MfApi)",
"Laut Doku (Management Application API / wie SMC-Restart):\n" + "Laut Doku (Management Application API / wie SMC-Restart):\n" +
"JMSConnectorClient + MFProxyFactory.createAgentProxy + IAgentProxy.restart\n\n" + "JMSConnectorClient + MFProxyFactory.createAgentProxy + IAgentProxy.restart\n\n" +
$"Container '{containerName}', Domain '{_connection.DomainName}', URL {_connection.ConnectionUrl}\n" + $"Container '{containerName}', Domain '{_connection.DomainName}', URL {_connection.ConnectionUrl}\n" +
$"Fehler: {error}\nAusgabe: {output}\n\n" + $"Fehler: {error}\nAusgabe: {output}\n\n" +
"Benötigt (SMC-Installation):\n" + "Benötigt (SMC-Installation):\n" +
$"- SonicHome={_connection.SonicHome} mit lib\\*.jar (mgmt_client / mfcontext / sonic_Client)\n" + $"- MfClientLibPath/SonicHome={libHint} (mgmt_client.jar, mfcontext.jar, sonic_Client.jar)\n" +
"- Java (JavaHome/JavaPath oder JRE unter SonicHome)\n" + $"- JavaPath={_connection.JavaPath}\n" +
"- Dieselben ConnectionUrl/User/Pass wie beim SMC-Login\n" + "- Dieselben ConnectionUrl/User/Pass wie beim SMC-Login\n" +
"Hinweis: stopcontainer.bat wird nicht verwendet (in SMC-only Versionen oft nicht vorhanden)."); "SMC-ObjectName Beispiel: proalpha-test.ct-ZADBService:ID=AGENT → ContainerName=ct-ZADBService\n" +
"Hinweis: stopcontainer.bat wird nicht verwendet (SMC-only).");
} }
private static async Task<bool> IsTcpReachableAsync(string connectionUrl, CancellationToken cancellationToken) private static async Task<bool> IsTcpReachableAsync(string connectionUrl, CancellationToken cancellationToken)
@@ -105,27 +105,11 @@ public sealed class SonicMfApiExecutor
return (false, null, prepareError); return (false, null, prepareError);
} }
List<string> args = // ArgumentList statt manueller Quotes: sonst landet \"...\" im Classpath
[ // und Java findet JMSConnectorAddress trotz vorhandener JARs nicht.
"-cp", Quote(classpath!),
"SonicMfContainerTool",
command,
"--domain", _connection.DomainName,
"--url", _connection.ConnectionUrl,
"--user", _connection.Username,
"--timeout", Math.Clamp(_connection.TimeoutSeconds, 5, 600).ToString()
];
if (!string.IsNullOrWhiteSpace(container))
{
args.Add("--container");
args.Add(container);
}
ProcessStartInfo psi = new() ProcessStartInfo psi = new()
{ {
FileName = javaExe!, FileName = javaExe!,
Arguments = string.Join(" ", args.Select(EscapeArg)),
UseShellExecute = false, UseShellExecute = false,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
@@ -135,6 +119,25 @@ public sealed class SonicMfApiExecutor
WorkingDirectory = classDir! WorkingDirectory = classDir!
}; };
psi.ArgumentList.Add("-cp");
psi.ArgumentList.Add(classpath!);
psi.ArgumentList.Add("SonicMfContainerTool");
psi.ArgumentList.Add(command);
psi.ArgumentList.Add("--domain");
psi.ArgumentList.Add(_connection.DomainName);
psi.ArgumentList.Add("--url");
psi.ArgumentList.Add(_connection.ConnectionUrl);
psi.ArgumentList.Add("--user");
psi.ArgumentList.Add(_connection.Username);
psi.ArgumentList.Add("--timeout");
psi.ArgumentList.Add(Math.Clamp(_connection.TimeoutSeconds, 5, 600).ToString());
if (!string.IsNullOrWhiteSpace(container))
{
psi.ArgumentList.Add("--container");
psi.ArgumentList.Add(container);
}
psi.Environment["ESB_SONIC_PASSWORD"] = _connection.Password ?? string.Empty; psi.Environment["ESB_SONIC_PASSWORD"] = _connection.Password ?? string.Empty;
using Process process = new() { StartInfo = psi }; using Process process = new() { StartInfo = psi };
@@ -172,6 +175,17 @@ public sealed class SonicMfApiExecutor
string err = ExtractError(combined) string err = ExtractError(combined)
?? $"SonicMfContainerTool ExitCode={process.ExitCode}"; ?? $"SonicMfContainerTool ExitCode={process.ExitCode}";
if (err.Contains("ClassNotFoundException", StringComparison.OrdinalIgnoreCase)
|| combined.Contains("JMSConnectorAddress", StringComparison.OrdinalIgnoreCase))
{
err +=
"\n\nClasspath unvollständig: com.sonicsw.mf.jmx.client.JMSConnectorAddress fehlt.\n" +
"Bitte in appsettings MfClientLibPath auf den Ordner mit mgmt_client.jar / mfcontext.jar / sonic_Client.jar setzen\n" +
$"(aktuell SonicHome='{_connection.SonicHome}').\n" +
"Hinweis: Container-Kurzname laut SMC ist 'ct-ZADBService' (nicht der Verbindungs-Alias DE-Test).";
}
return (false, combined.Length > 0 ? combined : null, err); return (false, combined.Length > 0 ? combined : null, err);
} }
@@ -226,8 +240,8 @@ public sealed class SonicMfApiExecutor
"Sonic-Client-JARs bleiben unter SonicHome\\lib."); "Sonic-Client-JARs bleiben unter SonicHome\\lib.");
} }
(string? libDir, string? libError) = ResolveLibDirectoryDetailed(); (string? libClasspath, string? libError) = ResolveSonicClasspathDetailed();
if (libDir is null) if (libClasspath is null)
{ {
return (false, null, null, null, libError); return (false, null, null, null, libError);
} }
@@ -236,7 +250,7 @@ public sealed class SonicMfApiExecutor
if (TryResolvePrebuiltTool(runtimeMajor, out string? prebuiltDir, out string? prebuiltEntry, out string? prebuiltError) if (TryResolvePrebuiltTool(runtimeMajor, out string? prebuiltDir, out string? prebuiltEntry, out string? prebuiltError)
&& prebuiltDir is not null && prebuiltEntry is not null) && prebuiltDir is not null && prebuiltEntry is not null)
{ {
string classpath = BuildClasspath(libDir, prebuiltEntry); string classpath = libClasspath + Path.PathSeparator + prebuiltEntry;
return (true, javaExe, prebuiltDir, classpath, null); return (true, javaExe, prebuiltDir, classpath, null);
} }
@@ -258,8 +272,8 @@ public sealed class SonicMfApiExecutor
File.Copy(sourcePath, javaTarget, overwrite: true); File.Copy(sourcePath, javaTarget, overwrite: true);
string compileClasspath = BuildClasspath(libDir, null); string compileClasspath = libClasspath;
string runtimeClasspath = BuildClasspath(libDir, workDir); string runtimeClasspath = libClasspath + Path.PathSeparator + workDir;
bool classOk = File.Exists(classFile) bool classOk = File.Exists(classFile)
&& ReadClassFileMajorVersion(classFile) is int existingMajor && ReadClassFileMajorVersion(classFile) is int existingMajor
@@ -285,8 +299,6 @@ public sealed class SonicMfApiExecutor
ProcessStartInfo compilePsi = new() ProcessStartInfo compilePsi = new()
{ {
FileName = javac, FileName = javac,
Arguments =
$"{releaseArgs} -encoding UTF-8 -cp {Quote(compileClasspath)} -d {Quote(workDir)} {Quote(javaTarget)}",
UseShellExecute = false, UseShellExecute = false,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
@@ -295,6 +307,27 @@ public sealed class SonicMfApiExecutor
StandardErrorEncoding = Encoding.UTF8 StandardErrorEncoding = Encoding.UTF8
}; };
if (releaseArgs.StartsWith("--release", StringComparison.Ordinal))
{
compilePsi.ArgumentList.Add("--release");
compilePsi.ArgumentList.Add("8");
}
else
{
compilePsi.ArgumentList.Add("-source");
compilePsi.ArgumentList.Add("1.8");
compilePsi.ArgumentList.Add("-target");
compilePsi.ArgumentList.Add("1.8");
}
compilePsi.ArgumentList.Add("-encoding");
compilePsi.ArgumentList.Add("UTF-8");
compilePsi.ArgumentList.Add("-cp");
compilePsi.ArgumentList.Add(compileClasspath);
compilePsi.ArgumentList.Add("-d");
compilePsi.ArgumentList.Add(workDir);
compilePsi.ArgumentList.Add(javaTarget);
using Process compile = new() { StartInfo = compilePsi }; using Process compile = new() { StartInfo = compilePsi };
if (!compile.Start()) if (!compile.Start())
{ {
@@ -312,7 +345,7 @@ public sealed class SonicMfApiExecutor
"Kompilieren von SonicMfContainerTool für Java 8 fehlgeschlagen.\n" + "Kompilieren von SonicMfContainerTool für Java 8 fehlgeschlagen.\n" +
Truncate((cErr + "\n" + cOut).Trim()) + Truncate((cErr + "\n" + cOut).Trim()) +
$"\nErzeugt major={builtMajor?.ToString() ?? "?"}, Runtime erlaubt <={runtimeMajor}.\n" + $"\nErzeugt major={builtMajor?.ToString() ?? "?"}, Runtime erlaubt <={runtimeMajor}.\n" +
$"Classpath-Lib: {libDir}"); $"Classpath: {Truncate(compileClasspath, 240)}");
} }
} }
@@ -543,13 +576,17 @@ public sealed class SonicMfApiExecutor
} }
} }
private (string? Dir, string? Error) ResolveLibDirectoryDetailed() /// <summary>
/// Baut einen Classpath mit echten Sonic-Management-Client-JARs
/// (inkl. com.sonicsw.mf.jmx.client.JMSConnectorAddress).
/// </summary>
private (string? Classpath, string? Error) ResolveSonicClasspathDetailed()
{ {
List<(string Path, string Label)> candidates = []; List<(string Path, string Label)> searchRoots = [];
if (!string.IsNullOrWhiteSpace(_connection.MfClientLibPath)) if (!string.IsNullOrWhiteSpace(_connection.MfClientLibPath))
{ {
candidates.Add((_connection.MfClientLibPath.Trim(), "MfClientLibPath")); searchRoots.Add((_connection.MfClientLibPath.Trim().Trim('"'), "MfClientLibPath"));
} }
string? mqHome = Environment.GetEnvironmentVariable("MQ_HOME"); string? mqHome = Environment.GetEnvironmentVariable("MQ_HOME");
@@ -559,92 +596,262 @@ public sealed class SonicMfApiExecutor
if (!string.IsNullOrWhiteSpace(mqHome)) if (!string.IsNullOrWhiteSpace(mqHome))
{ {
candidates.Add((Path.Combine(mqHome.Trim().Trim('"'), "lib"), "MQ_HOME\\lib")); searchRoots.Add((mqHome.Trim().Trim('"'), "MQ_HOME"));
} }
if (!string.IsNullOrWhiteSpace(esbHome)) if (!string.IsNullOrWhiteSpace(esbHome))
{ {
string esb = esbHome.Trim().Trim('"'); searchRoots.Add((esbHome.Trim().Trim('"'), "ESB_HOME/SONIC_HOME"));
candidates.Add((Path.Combine(esb, "lib"), "ESB_HOME\\lib"));
candidates.Add((Path.Combine(esb, "MQ", "lib"), "ESB_HOME\\MQ\\lib"));
candidates.Add((Path.Combine(esb, "mq", "lib"), "ESB_HOME\\mq\\lib"));
} }
if (!string.IsNullOrWhiteSpace(_connection.SonicHome)) if (!string.IsNullOrWhiteSpace(_connection.SonicHome))
{ {
string sonicHome = _connection.SonicHome.Trim(); string sonicHome = _connection.SonicHome.Trim().Trim('"');
candidates.Add((Path.Combine(sonicHome, "lib"), "SonicHome\\lib")); searchRoots.Add((sonicHome, "SonicHome"));
candidates.Add((sonicHome, "SonicHome"));
// ESB-Home zeigt oft auf Broker/ESB; Client-JARs liegen unter MQ*/lib oder sibling MQ.
foreach (string nested in EnumerateLikelyLibRoots(sonicHome))
{
candidates.Add((nested, "SonicHome-nested\\lib"));
}
string? parent = Directory.GetParent(sonicHome)?.FullName; string? parent = Directory.GetParent(sonicHome)?.FullName;
if (!string.IsNullOrWhiteSpace(parent)) if (!string.IsNullOrWhiteSpace(parent))
{ {
candidates.Add((Path.Combine(parent, "lib"), "SonicHome-Parent\\lib")); searchRoots.Add((parent, "SonicHome-Parent"));
foreach (string nested in EnumerateLikelyLibRoots(parent))
{
candidates.Add((nested, "SonicHome-Parent-nested\\lib"));
}
} }
} }
List<string> checkedPaths = []; List<string> checkedPaths = [];
HashSet<string> seen = new(StringComparer.OrdinalIgnoreCase); HashSet<string> seenDirs = new(StringComparer.OrdinalIgnoreCase);
foreach ((string path, string label) in candidates) List<string> markerHits = [];
foreach ((string root, string label) in searchRoots)
{ {
if (string.IsNullOrWhiteSpace(path) || !seen.Add(path)) if (string.IsNullOrWhiteSpace(root) || !Directory.Exists(root))
{
checkedPaths.Add($"{label}='{root}' (fehlt)");
continue;
}
checkedPaths.Add($"{label}='{root}'");
// 1) Bekannte Lib-Ordner
List<string> libCandidates = [root, Path.Combine(root, "lib"), .. EnumerateLikelyLibRoots(root)];
// 2) Rekursiv nach Marker-JARs (SMC-only oft unter MQ*/lib oder Client/lib)
foreach (string jar in EnumerateMarkerJars(root, maxDepth: 5, maxFiles: 400))
{
string? dir = Path.GetDirectoryName(jar);
if (!string.IsNullOrWhiteSpace(dir))
{
libCandidates.Add(dir);
markerHits.Add(jar);
}
}
foreach (string libDir in libCandidates)
{
if (string.IsNullOrWhiteSpace(libDir) || !seenDirs.Add(libDir) || !Directory.Exists(libDir))
{ {
continue; continue;
} }
checkedPaths.Add($"{label}='{path}'"); if (!DirectoryHasRequiredSonicClientJars(libDir, out string? detail))
if (!Directory.Exists(path))
{ {
if (!string.IsNullOrWhiteSpace(detail))
{
checkedPaths.Add($" skip '{libDir}': {detail}");
}
continue; continue;
} }
if (DirectoryHasSonicClientJars(path)) string? classpath = BuildClasspathFromLibDirs(CollectRelatedLibDirs(libDir, root));
if (!string.IsNullOrWhiteSpace(classpath))
{ {
return (path, null); return (classpath, null);
}
} }
} }
string sonicHomeVal = _connection.SonicHome ?? string.Empty; string sonicHomeVal = _connection.SonicHome ?? string.Empty;
bool sonicHomeExists = !string.IsNullOrWhiteSpace(sonicHomeVal) && Directory.Exists(sonicHomeVal); string markerHint = markerHits.Count == 0
string libPath = string.IsNullOrWhiteSpace(sonicHomeVal) ? "Keine Marker-JARs (mgmt_client/mfcontext/sonic_Client) gefunden."
? "(SonicHome leer)" : "Marker-Treffer (unvollständig):\n - " + string.Join("\n - ", markerHits.Distinct(StringComparer.OrdinalIgnoreCase).Take(12));
: Path.Combine(sonicHomeVal, "lib");
if (sonicHomeExists && Directory.Exists(libPath)
&& !Directory.EnumerateFiles(libPath, "*.jar", SearchOption.TopDirectoryOnly).Any())
{
return (null,
$"Sonic-Client-JARs fehlen unter '{libPath}' (Ordner existiert, aber keine *.jar).\n" +
$"Verwendetes SonicHome: '{sonicHomeVal}'\n" +
"MfApi braucht u.a. mgmt_client.jar / mfcontext.jar / sonic_Client.jar.\n" +
"Falls SonicHome auf ESB zeigt: auf MQ-Home setzen oder MfClientLibPath auf den MQ\\lib-Ordner.\n" +
$"Geprüft: {string.Join("; ", checkedPaths)}");
}
if (sonicHomeExists && !Directory.Exists(libPath))
{
return (null,
$"SonicHome='{sonicHomeVal}' gefunden, aber Lib-Ordner fehlt: '{libPath}'.\n" +
"Sonic-Client-Installation prüfen oder MfClientLibPath setzen " +
"(erwartet *.jar, u.a. mgmt_client.jar).\n" +
$"Geprüft: {string.Join("; ", checkedPaths)}");
}
return (null, return (null,
"Sonic-Client-JARs nicht gefunden. SonicHome\\lib, MQ_HOME\\lib, ESB_HOME\\lib oder MfClientLibPath setzen.\n" + "Sonic-Client-JARs für MfApi fehlen (Class JMSConnectorAddress).\n" +
$"Verwendetes SonicHome: '{(string.IsNullOrWhiteSpace(sonicHomeVal) ? "(leer)" : sonicHomeVal)}'\n" + $"Verwendetes SonicHome: '{(string.IsNullOrWhiteSpace(sonicHomeVal) ? "(leer)" : sonicHomeVal)}'\n" +
$"Geprüft:\n - {string.Join("\n - ", checkedPaths)}\n" + "Benötigt u.a.: mgmt_client.jar, mfcontext.jar, sonic_Client.jar (Ordner mit *.jar).\n" +
"Benötigt u.a. mgmt_client.jar / mfcontext.jar / sonic_Client.jar."); "Lösung: MfClientLibPath auf den Ordner setzen, in dem diese JARs liegen\n" +
" (oft ...\\MQ10.0\\lib oder SMC-Client\\lib nicht nur das JRE).\n" +
markerHint + "\n" +
"Geprüft:\n - " + string.Join("\n - ", checkedPaths.Take(40)));
}
private static IEnumerable<string> EnumerateMarkerJars(string root, int maxDepth, int maxFiles)
{
if (!Directory.Exists(root))
{
yield break;
}
string[] markers =
[
"mgmt_client", "mfcontext", "sonic_Client", "sonic_client",
"mf_client", "mf-client", "mgmt-client", "sonic_Crypto", "sonic_XA"
];
Queue<(string Dir, int Depth)> queue = new();
queue.Enqueue((root, 0));
int yielded = 0;
HashSet<string> seen = new(StringComparer.OrdinalIgnoreCase);
while (queue.Count > 0 && yielded < maxFiles)
{
(string dir, int depth) = queue.Dequeue();
if (!seen.Add(dir))
{
continue;
}
IEnumerable<string> files;
try
{
files = Directory.EnumerateFiles(dir, "*.jar", SearchOption.TopDirectoryOnly);
}
catch
{
continue;
}
foreach (string file in files)
{
string name = Path.GetFileNameWithoutExtension(file);
if (markers.Any(m => name.Contains(m, StringComparison.OrdinalIgnoreCase)))
{
yielded++;
yield return file;
if (yielded >= maxFiles)
{
yield break;
}
}
}
if (depth >= maxDepth)
{
continue;
}
IEnumerable<string> children;
try
{
children = Directory.EnumerateDirectories(dir);
}
catch
{
continue;
}
foreach (string child in children)
{
string leaf = Path.GetFileName(child);
// Skip große / irrelevante Bäume
if (leaf.Equals("docs", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("documentation", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("samples", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("log", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("logs", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("tmp", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("temp", StringComparison.OrdinalIgnoreCase)
|| leaf.StartsWith("jre", StringComparison.OrdinalIgnoreCase)
|| leaf.Equals("jdk", StringComparison.OrdinalIgnoreCase))
{
continue;
}
queue.Enqueue((child, depth + 1));
}
}
}
private static List<string> CollectRelatedLibDirs(string primaryLibDir, string searchRoot)
{
HashSet<string> dirs = new(StringComparer.OrdinalIgnoreCase) { primaryLibDir };
// Sibling-Libs oft: MQ/lib + ESB/lib + common/lib
string? parent = Directory.GetParent(primaryLibDir)?.FullName;
if (!string.IsNullOrWhiteSpace(parent))
{
foreach (string sibling in new[]
{
Path.Combine(parent, "lib"),
Path.Combine(parent, "common", "lib"),
Path.Combine(parent, "client", "lib")
})
{
if (Directory.Exists(sibling))
{
dirs.Add(sibling);
}
}
string? grand = Directory.GetParent(parent)?.FullName;
if (!string.IsNullOrWhiteSpace(grand))
{
foreach (string nested in EnumerateLikelyLibRoots(grand))
{
dirs.Add(nested);
}
}
}
if (Directory.Exists(searchRoot))
{
foreach (string nested in EnumerateLikelyLibRoots(searchRoot))
{
dirs.Add(nested);
}
}
return dirs.Where(Directory.Exists).ToList();
}
private static string? BuildClasspathFromLibDirs(IEnumerable<string> libDirs)
{
HashSet<string> jarFiles = new(StringComparer.OrdinalIgnoreCase);
foreach (string dir in libDirs)
{
if (!Directory.Exists(dir))
{
continue;
}
try
{
foreach (string jar in Directory.EnumerateFiles(dir, "*.jar", SearchOption.TopDirectoryOnly))
{
jarFiles.Add(jar);
}
}
catch
{
// ignore unreadable dirs
}
}
List<string> entries = jarFiles
.OrderBy(j => j, StringComparer.OrdinalIgnoreCase)
.ToList();
if (entries.Count == 0)
{
return null;
}
// Classpath-Länge begrenzen: zu viele Einträge → CreateProcess-Fehler
if (entries.Count > 250)
{
entries = entries.Take(250).ToList();
}
return string.Join(Path.PathSeparator, entries);
} }
private static IEnumerable<string> EnumerateLikelyLibRoots(string root) private static IEnumerable<string> EnumerateLikelyLibRoots(string root)
@@ -698,44 +905,44 @@ public sealed class SonicMfApiExecutor
} }
} }
private static bool DirectoryHasSonicClientJars(string path) /// <summary>
/// Strikt: mindestens ein MF/Management-Client-JAR (nicht irgendein JAR-Ordner).
/// </summary>
private static bool DirectoryHasRequiredSonicClientJars(string path, out string? detail)
{ {
detail = null;
try try
{ {
string[] jars = Directory.EnumerateFiles(path, "*.jar", SearchOption.TopDirectoryOnly).ToArray(); string[] jars = Directory.EnumerateFiles(path, "*.jar", SearchOption.TopDirectoryOnly).ToArray();
if (jars.Length == 0) if (jars.Length == 0)
{ {
detail = "keine *.jar";
return false; return false;
} }
// Bevorzugt echte Sonic-Client-Libs; sonst jeder JAR-Ordner als Fallback. string[] strong =
string[] markers =
[ [
"mgmt_client", "mfcontext", "sonic_Client", "sonic_client", "mf_client", "Sonic" "mgmt_client", "mfcontext", "sonic_Client", "sonic_client", "mf_client", "mf-client"
]; ];
if (jars.Any(j => markers.Any(m =>
Path.GetFileName(j).Contains(m, StringComparison.OrdinalIgnoreCase)))) bool hasStrong = jars.Any(j =>
strong.Any(m => Path.GetFileName(j).Contains(m, StringComparison.OrdinalIgnoreCase)));
if (!hasStrong)
{ {
detail = $"{jars.Length} JARs, aber ohne mgmt_client/mfcontext/sonic_Client";
return false;
}
return true; return true;
} }
catch (Exception ex)
return jars.Length > 0;
}
catch
{ {
detail = ex.Message;
return false; return false;
} }
} }
private static string BuildClasspath(string libDir, string? extraEntry)
{
// Java-Classpath-Wildcard für alle JARs im Lib-Ordner
string jars = Path.Combine(libDir, "*");
return string.IsNullOrWhiteSpace(extraEntry)
? jars
: jars + Path.PathSeparator + extraEntry;
}
private static string? ResolveToolSourcePath() private static string? ResolveToolSourcePath()
{ {
string[] candidates = string[] candidates =
@@ -0,0 +1,28 @@
@echo off
REM Prueft ob JMSConnectorAddress mit den Sonic-Client-JARs ladbar ist.
set LIB=C:\DEV\MQ10.0\lib
set JAVA=C:\Program Files (x86)\Java\jre1.8.0_501\bin\java.exe
if not exist "%JAVA%" (
echo Java nicht gefunden: %JAVA%
exit /b 1
)
if not exist "%LIB%\mfcontext.jar" (
echo mfcontext.jar fehlt unter %LIB%
exit /b 1
)
set CP=%LIB%\mgmt_client.jar;%LIB%\mgmt_config.jar;%LIB%\sonic_mgmt_client.jar;%LIB%\mfcontext.jar;%LIB%\sonic_Client.jar;%LIB%\sonic_Client_ext.jar
echo Java: %JAVA%
echo CP: %CP%
echo.
"%JAVA%" -cp "%CP%" -version
echo.
"%JAVA%" -cp "%CP%" com.sonicsw.mf.jmx.client.JMSConnectorAddress 2>&1
echo ExitCode=%ERRORLEVEL%
echo.
echo Erwartet: oft "main method" / NoSuchMethodError ODER Usage - Hauptsache KEIN ClassNotFoundException.
exit /b 0
@@ -16,9 +16,9 @@
"SonicHome": "C:\\DEV\\MQ10.0", "SonicHome": "C:\\DEV\\MQ10.0",
"JavaHome": "C:\\Program Files (x86)\\Java\\jre1.8.0_501", "JavaHome": "C:\\Program Files (x86)\\Java\\jre1.8.0_501",
"JavaPath": "C:\\Program Files (x86)\\Java\\jre1.8.0_501\\bin\\java.exe", "JavaPath": "C:\\Program Files (x86)\\Java\\jre1.8.0_501\\bin\\java.exe",
"MfClientLibPath": "", "MfClientLibPath": "C:\\DEV\\MQ10.0\\lib",
"KnownContainers": [ "KnownContainers": [
"DE-Test" "ct-ZADBService"
], ],
"WinRmUsername": "", "WinRmUsername": "",
"WinRmPassword": "", "WinRmPassword": "",