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:
@@ -1,12 +1,12 @@
|
||||
[
|
||||
{
|
||||
"Id": 1,
|
||||
"Name": "DE-Test Container",
|
||||
"Name": "DE-Test / ct-ZADBService",
|
||||
"Environment": "TEST",
|
||||
"IsActive": true,
|
||||
"TargetDirectory": "DeploySandbox/target-esb",
|
||||
"CertificateFileName": "esb-cert.cer",
|
||||
"ContainerName": "DE-Test",
|
||||
"ContainerName": "ct-ZADBService",
|
||||
"RestartType": "SonicContainer",
|
||||
"RestartCommand": "",
|
||||
"RestartArguments": "",
|
||||
|
||||
@@ -345,16 +345,21 @@ public sealed class SonicManagementClient : IDisposable
|
||||
$"Domain={_connection.DomainName}; ConnectionUrl={_connection.ConnectionUrl}\n{output}");
|
||||
}
|
||||
|
||||
string libHint = string.IsNullOrWhiteSpace(_connection.MfClientLibPath)
|
||||
? _connection.SonicHome
|
||||
: _connection.MfClientLibPath;
|
||||
|
||||
return (false, "Neustart fehlgeschlagen (MfApi)",
|
||||
"Laut Doku (Management Application API / wie SMC-Restart):\n" +
|
||||
"JMSConnectorClient + MFProxyFactory.createAgentProxy + IAgentProxy.restart\n\n" +
|
||||
$"Container '{containerName}', Domain '{_connection.DomainName}', URL {_connection.ConnectionUrl}\n" +
|
||||
$"Fehler: {error}\nAusgabe: {output}\n\n" +
|
||||
"Benötigt (SMC-Installation):\n" +
|
||||
$"- SonicHome={_connection.SonicHome} mit lib\\*.jar (mgmt_client / mfcontext / sonic_Client)\n" +
|
||||
"- Java (JavaHome/JavaPath oder JRE unter SonicHome)\n" +
|
||||
$"- MfClientLibPath/SonicHome={libHint} (mgmt_client.jar, mfcontext.jar, sonic_Client.jar)\n" +
|
||||
$"- JavaPath={_connection.JavaPath}\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)
|
||||
|
||||
@@ -105,27 +105,11 @@ public sealed class SonicMfApiExecutor
|
||||
return (false, null, prepareError);
|
||||
}
|
||||
|
||||
List<string> args =
|
||||
[
|
||||
"-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);
|
||||
}
|
||||
|
||||
// ArgumentList statt manueller Quotes: sonst landet \"...\" im Classpath
|
||||
// und Java findet JMSConnectorAddress trotz vorhandener JARs nicht.
|
||||
ProcessStartInfo psi = new()
|
||||
{
|
||||
FileName = javaExe!,
|
||||
Arguments = string.Join(" ", args.Select(EscapeArg)),
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
@@ -135,6 +119,25 @@ public sealed class SonicMfApiExecutor
|
||||
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;
|
||||
|
||||
using Process process = new() { StartInfo = psi };
|
||||
@@ -172,6 +175,17 @@ public sealed class SonicMfApiExecutor
|
||||
|
||||
string err = ExtractError(combined)
|
||||
?? $"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);
|
||||
}
|
||||
|
||||
@@ -226,8 +240,8 @@ public sealed class SonicMfApiExecutor
|
||||
"Sonic-Client-JARs bleiben unter SonicHome\\lib.");
|
||||
}
|
||||
|
||||
(string? libDir, string? libError) = ResolveLibDirectoryDetailed();
|
||||
if (libDir is null)
|
||||
(string? libClasspath, string? libError) = ResolveSonicClasspathDetailed();
|
||||
if (libClasspath is null)
|
||||
{
|
||||
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)
|
||||
&& 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);
|
||||
}
|
||||
|
||||
@@ -258,8 +272,8 @@ public sealed class SonicMfApiExecutor
|
||||
|
||||
File.Copy(sourcePath, javaTarget, overwrite: true);
|
||||
|
||||
string compileClasspath = BuildClasspath(libDir, null);
|
||||
string runtimeClasspath = BuildClasspath(libDir, workDir);
|
||||
string compileClasspath = libClasspath;
|
||||
string runtimeClasspath = libClasspath + Path.PathSeparator + workDir;
|
||||
|
||||
bool classOk = File.Exists(classFile)
|
||||
&& ReadClassFileMajorVersion(classFile) is int existingMajor
|
||||
@@ -285,8 +299,6 @@ public sealed class SonicMfApiExecutor
|
||||
ProcessStartInfo compilePsi = new()
|
||||
{
|
||||
FileName = javac,
|
||||
Arguments =
|
||||
$"{releaseArgs} -encoding UTF-8 -cp {Quote(compileClasspath)} -d {Quote(workDir)} {Quote(javaTarget)}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
@@ -295,6 +307,27 @@ public sealed class SonicMfApiExecutor
|
||||
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 };
|
||||
if (!compile.Start())
|
||||
{
|
||||
@@ -312,7 +345,7 @@ public sealed class SonicMfApiExecutor
|
||||
"Kompilieren von SonicMfContainerTool für Java 8 fehlgeschlagen.\n" +
|
||||
Truncate((cErr + "\n" + cOut).Trim()) +
|
||||
$"\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))
|
||||
{
|
||||
candidates.Add((_connection.MfClientLibPath.Trim(), "MfClientLibPath"));
|
||||
searchRoots.Add((_connection.MfClientLibPath.Trim().Trim('"'), "MfClientLibPath"));
|
||||
}
|
||||
|
||||
string? mqHome = Environment.GetEnvironmentVariable("MQ_HOME");
|
||||
@@ -559,92 +596,262 @@ public sealed class SonicMfApiExecutor
|
||||
|
||||
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))
|
||||
{
|
||||
string esb = esbHome.Trim().Trim('"');
|
||||
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"));
|
||||
searchRoots.Add((esbHome.Trim().Trim('"'), "ESB_HOME/SONIC_HOME"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_connection.SonicHome))
|
||||
{
|
||||
string sonicHome = _connection.SonicHome.Trim();
|
||||
candidates.Add((Path.Combine(sonicHome, "lib"), "SonicHome\\lib"));
|
||||
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 sonicHome = _connection.SonicHome.Trim().Trim('"');
|
||||
searchRoots.Add((sonicHome, "SonicHome"));
|
||||
string? parent = Directory.GetParent(sonicHome)?.FullName;
|
||||
if (!string.IsNullOrWhiteSpace(parent))
|
||||
{
|
||||
candidates.Add((Path.Combine(parent, "lib"), "SonicHome-Parent\\lib"));
|
||||
foreach (string nested in EnumerateLikelyLibRoots(parent))
|
||||
{
|
||||
candidates.Add((nested, "SonicHome-Parent-nested\\lib"));
|
||||
}
|
||||
searchRoots.Add((parent, "SonicHome-Parent"));
|
||||
}
|
||||
}
|
||||
|
||||
List<string> checkedPaths = [];
|
||||
HashSet<string> seen = new(StringComparer.OrdinalIgnoreCase);
|
||||
foreach ((string path, string label) in candidates)
|
||||
HashSet<string> seenDirs = new(StringComparer.OrdinalIgnoreCase);
|
||||
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}='{path}'");
|
||||
if (!Directory.Exists(path))
|
||||
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))
|
||||
{
|
||||
continue;
|
||||
string? dir = Path.GetDirectoryName(jar);
|
||||
if (!string.IsNullOrWhiteSpace(dir))
|
||||
{
|
||||
libCandidates.Add(dir);
|
||||
markerHits.Add(jar);
|
||||
}
|
||||
}
|
||||
|
||||
if (DirectoryHasSonicClientJars(path))
|
||||
foreach (string libDir in libCandidates)
|
||||
{
|
||||
return (path, null);
|
||||
if (string.IsNullOrWhiteSpace(libDir) || !seenDirs.Add(libDir) || !Directory.Exists(libDir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DirectoryHasRequiredSonicClientJars(libDir, out string? detail))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(detail))
|
||||
{
|
||||
checkedPaths.Add($" skip '{libDir}': {detail}");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
string? classpath = BuildClasspathFromLibDirs(CollectRelatedLibDirs(libDir, root));
|
||||
if (!string.IsNullOrWhiteSpace(classpath))
|
||||
{
|
||||
return (classpath, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string sonicHomeVal = _connection.SonicHome ?? string.Empty;
|
||||
bool sonicHomeExists = !string.IsNullOrWhiteSpace(sonicHomeVal) && Directory.Exists(sonicHomeVal);
|
||||
string libPath = string.IsNullOrWhiteSpace(sonicHomeVal)
|
||||
? "(SonicHome leer)"
|
||||
: 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)}");
|
||||
}
|
||||
string markerHint = markerHits.Count == 0
|
||||
? "Keine Marker-JARs (mgmt_client/mfcontext/sonic_Client) gefunden."
|
||||
: "Marker-Treffer (unvollständig):\n - " + string.Join("\n - ", markerHits.Distinct(StringComparer.OrdinalIgnoreCase).Take(12));
|
||||
|
||||
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" +
|
||||
$"Geprüft:\n - {string.Join("\n - ", checkedPaths)}\n" +
|
||||
"Benötigt u.a. mgmt_client.jar / mfcontext.jar / sonic_Client.jar.");
|
||||
"Benötigt u.a.: mgmt_client.jar, mfcontext.jar, sonic_Client.jar (Ordner mit *.jar).\n" +
|
||||
"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)
|
||||
@@ -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
|
||||
{
|
||||
string[] jars = Directory.EnumerateFiles(path, "*.jar", SearchOption.TopDirectoryOnly).ToArray();
|
||||
if (jars.Length == 0)
|
||||
{
|
||||
detail = "keine *.jar";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bevorzugt echte Sonic-Client-Libs; sonst jeder JAR-Ordner als Fallback.
|
||||
string[] markers =
|
||||
string[] strong =
|
||||
[
|
||||
"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)
|
||||
{
|
||||
return true;
|
||||
detail = $"{jars.Length} JARs, aber ohne mgmt_client/mfcontext/sonic_Client";
|
||||
return false;
|
||||
}
|
||||
|
||||
return jars.Length > 0;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
detail = ex.Message;
|
||||
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()
|
||||
{
|
||||
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",
|
||||
"JavaHome": "C:\\Program Files (x86)\\Java\\jre1.8.0_501",
|
||||
"JavaPath": "C:\\Program Files (x86)\\Java\\jre1.8.0_501\\bin\\java.exe",
|
||||
"MfClientLibPath": "",
|
||||
"MfClientLibPath": "C:\\DEV\\MQ10.0\\lib",
|
||||
"KnownContainers": [
|
||||
"DE-Test"
|
||||
"ct-ZADBService"
|
||||
],
|
||||
"WinRmUsername": "",
|
||||
"WinRmPassword": "",
|
||||
|
||||
Reference in New Issue
Block a user