diff --git a/ZA.CoreService.ESBCertificateManager/Services/SonicMfApiExecutor.cs b/ZA.CoreService.ESBCertificateManager/Services/SonicMfApiExecutor.cs index 86bea99..034f21c 100644 --- a/ZA.CoreService.ESBCertificateManager/Services/SonicMfApiExecutor.cs +++ b/ZA.CoreService.ESBCertificateManager/Services/SonicMfApiExecutor.cs @@ -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; diff --git a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool$Args.class b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool$Args.class index fbb478c..d1c1955 100644 Binary files a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool$Args.class and b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool$Args.class differ diff --git a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.class b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.class index 52c19d8..105c868 100644 Binary files a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.class and b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.class differ diff --git a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.jar b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.jar index 2894ff6..593d2b0 100644 Binary files a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.jar and b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.jar differ diff --git a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java index 99d1ff5..2f1caaa 100644 --- a/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java +++ b/ZA.CoreService.ESBCertificateManager/Tools/SonicMfContainerTool.java @@ -8,31 +8,24 @@ import javax.management.MBeanInfo; import javax.management.ObjectName; /** - * Sonic Management Application API helper (same restart as SMC). + * Sonic Management Application API helper (same restart intent as SMC). * - * Uses reflection so this file compiles with Java 8 without Sonic jars on the - * compile classpath. At runtime SonicHome\\lib must provide: - * mgmt_client / mfcontext / sonic_Client (etc.) + * TOOL_VERSION is printed first so we can verify the deployed build. * - * Flow: - * Hashtable ConnectionURLs/DefaultUser/DefaultPassword - * -> JMSConnectorAddress / JMSConnectorClient.connect - * -> ObjectName {domain}.{container}:ID=AGENT - * -> restart via (in order): - * 1) MBean invoke("restart") / invoke("stop") [remote / unbounded OK] - * 2) IAgentProxy.restart / stop via MFProxyFactory - * - * Note: IAgentProxy.restart() often throws - * "Operation unsupported for unbounded client connector" - * on remote JMSConnectorClient. SMC Restart typically stops the agent; the - * Launch Daemon / container host brings it back up. + * Remote JMSConnectorClient is "unbounded". IAgentProxy.restart() often throws + * "Operation unsupported for unbounded client connector". SMC Restart typically + * stops the agent via JMX; Launch Daemon brings it back. * * Compile: javac --release 8 SonicMfContainerTool.java */ public final class SonicMfContainerTool { + /** Bump when restart logic changes – must appear in app output. */ + public static final String TOOL_VERSION = "2026-07-24c-mbean-stop"; + public static void main(String[] args) { + info("ToolVersion=" + TOOL_VERSION); try { Args a = Args.parse(args); @@ -89,12 +82,7 @@ public final class SonicMfContainerTool } catch (Throwable t) { - Throwable root = t; - while (root.getCause() != null && root.getCause() != root) - { - root = root.getCause(); - } - fail(root.getClass().getName() + ": " + root.getMessage()); + fail(rootOf(t).getClass().getName() + ": " + rootOf(t).getMessage()); } } @@ -112,43 +100,105 @@ public final class SonicMfContainerTool Class clientCl = Class.forName("com.sonicsw.mf.jmx.client.JMSConnectorClient"); Object connector = clientCl.getConstructor(new Class[] {}).newInstance(new Object[] {}); - Method connect = null; - Method[] methods = clientCl.getMethods(); - for (int i = 0; i < methods.length; i++) - { - Method m = methods[i]; - if ("connect".equals(m.getName()) && m.getParameterTypes().length == 2) - { - connect = m; - break; - } - } + // Optional: Request-Timeout setzen (falls vorhanden) + trySetTimeout(connector, timeoutMs); + + Method connect = findConnect(clientCl); if (connect == null) { - fail("JMSConnectorClient.connect(address, timeout) nicht gefunden."); + fail("JMSConnectorClient.connect(...) nicht gefunden."); return null; } Class[] pts = connect.getParameterTypes(); - Object timeoutArg; - if (pts[1] == Long.TYPE || pts[1] == Long.class) + Object[] callArgs; + if (pts.length == 2) { - timeoutArg = Long.valueOf(timeoutMs); + callArgs = new Object[] { address, boxTimeout(pts[1], timeoutMs) }; } - else if (pts[1] == Integer.TYPE || pts[1] == Integer.class) + else if (pts.length == 1) { - timeoutArg = Integer.valueOf((int) Math.min(Integer.MAX_VALUE, timeoutMs)); + callArgs = new Object[] { address }; } else { - timeoutArg = Long.valueOf(timeoutMs); + callArgs = new Object[] { address, boxTimeout(pts[1], timeoutMs) }; } - connect.invoke(connector, new Object[] { address, timeoutArg }); + connect.invoke(connector, callArgs); info("Connected url=" + url + " user=" + user); return connector; } + private static Method findConnect(Class clientCl) + { + Method best = null; + Method[] methods = clientCl.getMethods(); + for (int i = 0; i < methods.length; i++) + { + Method m = methods[i]; + if (!"connect".equals(m.getName())) + { + continue; + } + if (m.getParameterTypes().length == 2) + { + return m; + } + if (m.getParameterTypes().length == 1) + { + best = m; + } + } + return best; + } + + private static void trySetTimeout(Object connector, long timeoutMs) + { + String[] names = new String[] { "setTimeout", "setRequestTimeout", "setDefaultTimeout" }; + for (int i = 0; i < names.length; i++) + { + try + { + Method m = connector.getClass().getMethod(names[i], new Class[] { Long.TYPE }); + m.invoke(connector, new Object[] { Long.valueOf(timeoutMs) }); + info("Set " + names[i] + "=" + timeoutMs); + return; + } + catch (NoSuchMethodException ignore) + { + try + { + Method m = connector.getClass().getMethod(names[i], new Class[] { Integer.TYPE }); + m.invoke(connector, new Object[] { Integer.valueOf((int) Math.min(Integer.MAX_VALUE, timeoutMs)) }); + info("Set " + names[i] + "=" + timeoutMs); + return; + } + catch (Exception ignore2) + { + /* next */ + } + } + catch (Exception ignore) + { + /* next */ + } + } + } + + private static Object boxTimeout(Class type, long timeoutMs) + { + if (type == Long.TYPE || type == Long.class) + { + return Long.valueOf(timeoutMs); + } + if (type == Integer.TYPE || type == Integer.class) + { + return Integer.valueOf((int) Math.min(Integer.MAX_VALUE, timeoutMs)); + } + return Long.valueOf(timeoutMs); + } + private static void ping(Object connector, String domain) throws Exception { Set names = queryAgents(connector); @@ -196,36 +246,54 @@ public final class SonicMfContainerTool private static void restart(Object connector, String domain, String container) throws Exception { String shortName = shortContainer(container); - ObjectName on = resolveAgentObjectName(connector, domain, shortName); + // Zuerst Preferred-ObjectName OHNE queryNames – query kann schon scheitern/irreführen + ObjectName preferred = new ObjectName(domain + "." + shortName + ":ID=AGENT"); + info("PreferredObjectName=" + preferred); + + ObjectName on = preferred; + try + { + ObjectName resolved = resolveAgentObjectName(connector, domain, shortName); + if (resolved != null) + { + on = resolved; + } + } + catch (Throwable t) + { + warn("resolveAgentObjectName: " + rootOf(t).getClass().getName() + ": " + rootOf(t).getMessage() + + " – nutze PreferredObjectName"); + } info("ObjectName=" + on); - dumpOps(connector, on); + dumpOpsSafe(connector, on); - // 1) Remote-JMX invoke (funktioniert mit unbounded client) - if (tryMBeanLifecycle(connector, on, shortName, domain)) + StringBuffer attempts = new StringBuffer(); + + // 1) JMX invoke stop/restart/shutdown (remote / wie SMC) + if (tryMBeanLifecycle(connector, on, shortName, domain, attempts)) { return; } - // 2) Typisierte Proxies (kann unbounded-Fehler werfen) - if (tryAgentProxyLifecycle(connector, on, shortName, domain)) + // 2) IAgentProxy stop/restart + if (tryAgentProxyLifecycle(connector, on, shortName, domain, attempts)) { return; } - // 3) DomainManager / Collector Fallback - if (tryDomainManagerRestart(connector, domain, shortName)) + // 3) Manager-MBeans mit Container-Namen + if (tryManagerContainerOps(connector, domain, shortName, attempts)) { return; } - fail("Kein Neustart-Weg funktioniert (MBean invoke / IAgentProxy / DomainManager). " - + "Siehe INFO:Ops und unbounded-Hinweise oben."); + fail("Kein Neustart-Weg erfolgreich. ToolVersion=" + TOOL_VERSION + "\nAttempts:\n" + attempts.toString()); } - private static boolean tryMBeanLifecycle(Object connector, ObjectName on, String shortName, String domain) + private static boolean tryMBeanLifecycle( + Object connector, ObjectName on, String shortName, String domain, StringBuffer attempts) { - // Reihenfolge: stop zuerst (SMC-Restart = Stop + Auto-Relaunch), dann restart String[] ops = new String[] { "stop", "restart", "shutdown" }; for (int i = 0; i < ops.length; i++) { @@ -234,25 +302,30 @@ public final class SonicMfContainerTool { info("Trying MBean.invoke(" + op + ") on " + on); invokeNoArgs(connector, on, op); - System.out.println("OK:RestartInvoked method=MBean." + op - + " container=" + shortName + " domain=" + domain); - System.out.flush(); + okRestart("MBean." + op, shortName, domain); return true; } catch (Throwable t) { Throwable root = rootOf(t); - warn("MBean." + op + " failed: " + root.getClass().getName() + ": " + root.getMessage()); - if (!isUnbounded(root) && !"stop".equals(op) && !"restart".equals(op) && !"shutdown".equals(op)) + String line = "MBean." + op + " => " + root.getClass().getName() + ": " + root.getMessage(); + warn(line); + attempts.append(line).append('\n'); + + // stop kann die Verbindung reissen – wenn Message darauf hindeutet, als Erfolg werten + if ("stop".equals(op) && looksLikeStopSideEffect(root)) { - // continue trying other ops + warn("Treat stop side-effect as success (agent going down)"); + okRestart("MBean.stop(side-effect)", shortName, domain); + return true; } } } return false; } - private static boolean tryAgentProxyLifecycle(Object connector, ObjectName on, String shortName, String domain) + private static boolean tryAgentProxyLifecycle( + Object connector, ObjectName on, String shortName, String domain, StringBuffer attempts) { try { @@ -272,150 +345,150 @@ public final class SonicMfContainerTool { info("Trying IAgentProxy." + mName); agent.getClass().getMethod(mName).invoke(agent); - System.out.println("OK:RestartInvoked method=IAgentProxy." + mName - + " container=" + shortName + " domain=" + domain); - System.out.flush(); + okRestart("IAgentProxy." + mName, shortName, domain); return true; } catch (Throwable t) { Throwable root = rootOf(t); - warn("IAgentProxy." + mName + " failed: " + root.getClass().getName() + ": " + root.getMessage()); + String line = "IAgentProxy." + mName + " => " + root.getClass().getName() + ": " + root.getMessage(); + warn(line); + attempts.append(line).append('\n'); + if ("stop".equals(mName) && looksLikeStopSideEffect(root)) + { + okRestart("IAgentProxy.stop(side-effect)", shortName, domain); + return true; + } } } } catch (Throwable t) { Throwable root = rootOf(t); - warn("IAgentProxy path failed: " + root.getClass().getName() + ": " + root.getMessage()); + String line = "IAgentProxy path => " + root.getClass().getName() + ": " + root.getMessage(); + warn(line); + attempts.append(line).append('\n'); } return false; } - private static boolean tryDomainManagerRestart(Object connector, String domain, String shortName) + private static boolean tryManagerContainerOps( + Object connector, String domain, String shortName, StringBuffer attempts) { - // Häufige ObjectNames für Domain Manager / Collector String[] candidates = new String[] { domain + ".DomainManager:ID=DomainManager", domain + ".DomainManager:ID=AGENT", - domain + ".dm:ID=AGENT", - domain + ".DOMAIN_MANAGER:ID=AGENT", - domain + ".ManagementFramework:ID=AGENT" + domain + ".dm:ID=AGENT" }; for (int i = 0; i < candidates.length; i++) { try { - ObjectName dm = new ObjectName(candidates[i]); - Set found = (Set) connector.getClass() - .getMethod("queryNames", new Class[] { ObjectName.class, javax.management.QueryExp.class }) - .invoke(connector, new Object[] { dm, null }); + ObjectName pattern = new ObjectName(candidates[i]); + Set found = queryNames(connector, pattern); if (found == null || found.isEmpty()) { continue; } ObjectName real = (ObjectName) found.iterator().next(); - info("DomainManager candidate=" + real); - dumpOps(connector, real); + info("Manager=" + real); + dumpOpsSafe(connector, real); - String[] ops = new String[] { - "restartContainer", "stopContainer", "startContainer", - "restart", "stop", "shutdown" - }; + String[] ops = new String[] { "restartContainer", "stopContainer", "startContainer" }; for (int o = 0; o < ops.length; o++) { - String op = ops[o]; try { - if (op.endsWith("Container")) - { - info("Trying DomainManager." + op + "(\"" + shortName + "\")"); - invokeStringArg(connector, real, op, shortName); - } - else - { - // nur wenn es der Ziel-Container selbst ist - continue; - } - System.out.println("OK:RestartInvoked method=DomainManager." + op - + " container=" + shortName + " domain=" + domain); - System.out.flush(); + info("Trying " + ops[o] + "(\"" + shortName + "\") on " + real); + invokeStringArg(connector, real, ops[o], shortName); + okRestart("Manager." + ops[o], shortName, domain); return true; } catch (Throwable t) { Throwable root = rootOf(t); - warn("DomainManager." + op + " failed: " + root.getClass().getName() + ": " + root.getMessage()); + String line = ops[o] + " => " + root.getClass().getName() + ": " + root.getMessage(); + warn(line); + attempts.append(line).append('\n'); } } } - catch (Throwable ignore) + catch (Throwable t) { - /* try next */ + warn("Manager candidate " + candidates[i] + ": " + rootOf(t).getMessage()); } } - // Alle AGENT-MBeans scannen nach *Container* Ops + // Scan AGENT-MBeans nach Container-Ops try { Set agents = queryAgents(connector); - if (agents != null) + if (agents == null) { - for (Iterator it = agents.iterator(); it.hasNext(); ) + return false; + } + for (Iterator it = agents.iterator(); it.hasNext(); ) + { + ObjectName on = (ObjectName) it.next(); + String jmxDomain = on.getDomain(); + if (jmxDomain == null) { - ObjectName on = (ObjectName) it.next(); - String jmxDomain = on.getDomain(); - if (jmxDomain == null) - { - continue; - } - String lower = jmxDomain.toLowerCase(); - boolean interesting = lower.contains("domainmanager") - || lower.contains(".dm") - || lower.contains("collector") - || lower.contains("host") - || lower.contains("launch"); - if (!interesting) - { - continue; - } - info("Scanning manager agent " + on); - if (tryInvokeContainerOp(connector, on, shortName, domain)) + continue; + } + String lower = jmxDomain.toLowerCase(); + if (!(lower.contains("domainmanager") || lower.contains(".dm") + || lower.contains("collector") || lower.contains("host") + || lower.contains("launch"))) + { + continue; + } + info("Scan manager agent " + on); + dumpOpsSafe(connector, on); + String[] ops = new String[] { "restartContainer", "stopContainer" }; + for (int i = 0; i < ops.length; i++) + { + try { + invokeStringArg(connector, on, ops[i], shortName); + okRestart(ops[i] + "@" + on, shortName, domain); return true; } + catch (Throwable t) + { + attempts.append(ops[i]).append('@').append(on).append(" => ") + .append(rootOf(t).getMessage()).append('\n'); + } } } } catch (Throwable t) { - warn("Manager scan failed: " + rootOf(t).getMessage()); + warn("Manager scan: " + rootOf(t).getMessage()); } - return false; } - private static boolean tryInvokeContainerOp(Object connector, ObjectName on, String shortName, String domain) + private static boolean looksLikeStopSideEffect(Throwable root) { - String[] ops = new String[] { "restartContainer", "stopContainer" }; - for (int i = 0; i < ops.length; i++) + if (root == null || root.getMessage() == null) { - try - { - info("Trying " + on + "." + ops[i] + "(\"" + shortName + "\")"); - invokeStringArg(connector, on, ops[i], shortName); - System.out.println("OK:RestartInvoked method=" + ops[i] - + " on=" + on + " container=" + shortName + " domain=" + domain); - System.out.flush(); - return true; - } - catch (Throwable t) - { - warn(ops[i] + " on " + on + " failed: " + rootOf(t).getMessage()); - } + return false; } - return false; + String m = root.getMessage().toLowerCase(); + return m.indexOf("disconnect") >= 0 + || m.indexOf("closed") >= 0 + || m.indexOf("not connected") >= 0 + || m.indexOf("connection lost") >= 0 + || m.indexOf("broker") >= 0 && m.indexOf("down") >= 0; + } + + private static void okRestart(String method, String shortName, String domain) + { + System.out.println("OK:RestartInvoked method=" + method + + " container=" + shortName + " domain=" + domain + + " tool=" + TOOL_VERSION); + System.out.flush(); } private static void invokeNoArgs(Object connector, ObjectName on, String op) throws Exception @@ -436,26 +509,31 @@ public final class SonicMfContainerTool }); } - private static void dumpOps(Object connector, ObjectName on) + private static void dumpOpsSafe(Object connector, ObjectName on) { try { Method getInfo = connector.getClass().getMethod("getMBeanInfo", new Class[] { ObjectName.class }); - MBeanInfo info = (MBeanInfo) getInfo.invoke(connector, new Object[] { on }); - if (info == null || info.getOperations() == null) + MBeanInfo infoBean = (MBeanInfo) getInfo.invoke(connector, new Object[] { on }); + if (infoBean == null || infoBean.getOperations() == null) { + info("Ops(" + on + ")=(null)"); return; } StringBuffer sb = new StringBuffer(); - MBeanOperationInfo[] ops = info.getOperations(); + MBeanOperationInfo[] ops = infoBean.getOperations(); for (int i = 0; i < ops.length; i++) { String name = ops[i].getName(); String lower = name.toLowerCase(); - if (lower.contains("restart") || lower.contains("stop") || lower.contains("start") - || lower.contains("shutdown") || lower.contains("container")) + if (lower.indexOf("restart") >= 0 || lower.indexOf("stop") >= 0 + || lower.indexOf("start") >= 0 || lower.indexOf("shutdown") >= 0 + || lower.indexOf("container") >= 0) { - if (sb.length() > 0) sb.append(','); + if (sb.length() > 0) + { + sb.append(','); + } sb.append(name); } } @@ -463,26 +541,28 @@ public final class SonicMfContainerTool } catch (Throwable t) { - warn("getMBeanInfo failed: " + rootOf(t).getMessage()); + warn("getMBeanInfo(" + on + "): " + rootOf(t).getClass().getName() + ": " + rootOf(t).getMessage()); } } private static Set queryAgents(Object connector) throws Exception + { + return queryNames(connector, new ObjectName("*:ID=AGENT")); + } + + private static Set queryNames(Object connector, ObjectName pattern) throws Exception { Method query = connector.getClass().getMethod("queryNames", new Class[] { ObjectName.class, javax.management.QueryExp.class }); - return (Set) query.invoke(connector, new Object[] { new ObjectName("*:ID=AGENT"), null }); + return (Set) query.invoke(connector, new Object[] { pattern, null }); } private static ObjectName resolveAgentObjectName(Object connector, String domain, String container) throws Exception { ObjectName preferred = new ObjectName(domain + "." + container + ":ID=AGENT"); - Method query = connector.getClass().getMethod("queryNames", new Class[] { - ObjectName.class, javax.management.QueryExp.class - }); - Set exact = (Set) query.invoke(connector, new Object[] { preferred, null }); + Set exact = queryNames(connector, preferred); if (exact != null && !exact.isEmpty()) { return (ObjectName) exact.iterator().next(); @@ -501,7 +581,6 @@ public final class SonicMfContainerTool } } } - return preferred; } @@ -551,16 +630,10 @@ public final class SonicMfContainerTool } } - private static boolean isUnbounded(Throwable t) - { - String msg = t == null || t.getMessage() == null ? "" : t.getMessage(); - return msg.toLowerCase().indexOf("unbounded") >= 0; - } - private static Throwable rootOf(Throwable t) { Throwable root = t; - while (root.getCause() != null && root.getCause() != root) + while (root != null && root.getCause() != null && root.getCause() != root) { root = root.getCause(); } diff --git a/ZA.CoreService.ESBCertificateManager/ZA.CoreService.ESBCertificateManager.csproj b/ZA.CoreService.ESBCertificateManager/ZA.CoreService.ESBCertificateManager.csproj index cb95dc6..c4ae89c 100644 --- a/ZA.CoreService.ESBCertificateManager/ZA.CoreService.ESBCertificateManager.csproj +++ b/ZA.CoreService.ESBCertificateManager/ZA.CoreService.ESBCertificateManager.csproj @@ -31,7 +31,7 @@ PreserveNewest - PreserveNewest + Always