Fix UnsupportedClassVersionError: ship Java 8 SonicMfContainerTool.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-24 09:33:35 +02:00
co-authored by Cursor
parent 22b8ff4e85
commit d6cf49532b
3 changed files with 251 additions and 74 deletions
@@ -1,33 +1,26 @@
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import javax.management.ObjectName;
import com.sonicsw.mf.jmx.client.JMSConnectorAddress;
import com.sonicsw.mf.jmx.client.JMSConnectorClient;
import com.sonicsw.mf.mgmtapi.runtime.IAgentProxy;
import com.sonicsw.mf.mgmtapi.runtime.MFProxyFactory;
/**
* Sonic MF Management Runtime API helper (Aurea CX Messenger / Progress Sonic).
* Sonic Management Application API helper (same restart as SMC).
*
* Documented path (Management Application API):
* Hashtable env with ConnectionURLs / DefaultUser / DefaultPassword
* 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.)
*
* Flow (CX Messenger Management Application API):
* Hashtable ConnectionURLs/DefaultUser/DefaultPassword
* -> JMSConnectorAddress / JMSConnectorClient.connect
* -> MFProxyFactory.createAgentProxy(connector, ObjectName)
* -> IAgentProxy.restart() (same lifecycle action as SMC Restart)
* -> IAgentProxy.restart()
*
* ObjectName pattern: {domain}.{container}:ID=AGENT
* ObjectName: {domain}.{container}:ID=AGENT
*
* Usage:
* java -cp "...libs...;." SonicMfContainerTool ping|list|restart
* --domain proalpha-test
* --url tcp://host:13070
* --user Administrator
* --password *** (or env ESB_SONIC_PASSWORD)
* [--container DE-Test] (required for restart)
* [--timeout 120]
* Compile: javac --release 8 SonicMfContainerTool.java
*/
public final class SonicMfContainerTool
{
@@ -55,7 +48,7 @@ public final class SonicMfContainerTool
}
long timeoutMs = Math.max(5_000L, a.timeoutSec * 1000L);
JMSConnectorClient connector = connect(a.url, a.user, a.password, timeoutMs);
Object connector = connect(a.url, a.user, a.password, timeoutMs);
try
{
if ("ping".equals(a.command))
@@ -77,16 +70,28 @@ public final class SonicMfContainerTool
}
finally
{
try { connector.disconnect(); } catch (Exception ignore) { /* ignore */ }
try
{
connector.getClass().getMethod("disconnect").invoke(connector);
}
catch (Exception ignore)
{
/* ignore */
}
}
}
catch (Throwable t)
{
fail(t.getClass().getSimpleName() + ": " + t.getMessage());
Throwable root = t;
while (root.getCause() != null && root.getCause() != root)
{
root = root.getCause();
}
fail(root.getClass().getName() + ": " + root.getMessage());
}
}
private static JMSConnectorClient connect(String url, String user, String password, long timeoutMs)
private static Object connect(String url, String user, String password, long timeoutMs)
throws Exception
{
Hashtable env = new Hashtable();
@@ -94,23 +99,59 @@ public final class SonicMfContainerTool
env.put("DefaultUser", user);
env.put("DefaultPassword", password == null ? "" : password);
JMSConnectorAddress address = new JMSConnectorAddress(env);
JMSConnectorClient connector = new JMSConnectorClient();
connector.connect(address, timeoutMs);
Class addressCl = Class.forName("com.sonicsw.mf.jmx.client.JMSConnectorAddress");
Object address = addressCl.getConstructor(new Class[] { Hashtable.class }).newInstance(new Object[] { env });
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;
}
}
if (connect == null)
{
fail("JMSConnectorClient.connect(address, timeout) nicht gefunden.");
return null;
}
Class[] pts = connect.getParameterTypes();
Object timeoutArg;
if (pts[1] == Long.TYPE || pts[1] == Long.class)
{
timeoutArg = Long.valueOf(timeoutMs);
}
else if (pts[1] == Integer.TYPE || pts[1] == Integer.class)
{
timeoutArg = Integer.valueOf((int) Math.min(Integer.MAX_VALUE, timeoutMs));
}
else
{
timeoutArg = Long.valueOf(timeoutMs);
}
connect.invoke(connector, new Object[] { address, timeoutArg });
System.out.println("INFO:Connected url=" + url + " user=" + user);
return connector;
}
private static void ping(JMSConnectorClient connector, String domain) throws Exception
private static void ping(Object connector, String domain) throws Exception
{
Set names = connector.queryNames(new ObjectName("*:ID=AGENT"), null);
Set names = queryAgents(connector);
int matched = 0;
if (names != null)
{
for (Iterator it = names.iterator(); it.hasNext(); )
{
ObjectName on = (ObjectName) it.next();
if (belongsToDomain(on, domain))
if (extractContainer(on, domain) != null)
{
matched++;
}
@@ -119,9 +160,9 @@ public final class SonicMfContainerTool
System.out.println("OK:MfApiPing domain=" + domain + " agents=" + matched);
}
private static void list(JMSConnectorClient connector, String domain) throws Exception
private static void list(Object connector, String domain) throws Exception
{
Set names = connector.queryNames(new ObjectName("*:ID=AGENT"), null);
Set names = queryAgents(connector);
int count = 0;
if (names != null)
{
@@ -143,32 +184,49 @@ public final class SonicMfContainerTool
System.out.println("OK:List count=" + count);
}
private static void restart(JMSConnectorClient connector, String domain, String container) throws Exception
private static void restart(Object connector, String domain, String container) throws Exception
{
String shortName = shortContainer(container);
ObjectName on = resolveAgentObjectName(connector, domain, shortName);
System.out.println("INFO:ObjectName=" + on);
IAgentProxy agent = MFProxyFactory.createAgentProxy(connector, on);
Class factoryCl = Class.forName("com.sonicsw.mf.mgmtapi.runtime.MFProxyFactory");
Method create = factoryCl.getMethod("createAgentProxy", new Class[] {
Class.forName("com.sonicsw.mf.jmx.client.JMSConnectorClient"),
ObjectName.class
});
Object agent = create.invoke(null, new Object[] { connector, on });
String stateBefore = safeState(agent);
System.out.println("INFO:StateBefore=" + stateBefore);
agent.restart();
agent.getClass().getMethod("restart").invoke(agent);
System.out.println("OK:RestartInvoked container=" + shortName + " domain=" + domain
+ " stateBefore=" + stateBefore);
}
private static ObjectName resolveAgentObjectName(JMSConnectorClient connector, String domain, String container)
private static Set queryAgents(Object connector) 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 });
}
private static ObjectName resolveAgentObjectName(Object connector, String domain, String container)
throws Exception
{
ObjectName preferred = new ObjectName(domain + "." + container + ":ID=AGENT");
Set exact = connector.queryNames(preferred, null);
Method query = connector.getClass().getMethod("queryNames", new Class[] {
ObjectName.class, javax.management.QueryExp.class
});
Set exact = (Set) query.invoke(connector, new Object[] { preferred, null });
if (exact != null && !exact.isEmpty())
{
return (ObjectName) exact.iterator().next();
}
Set names = connector.queryNames(new ObjectName("*:ID=AGENT"), null);
Set names = queryAgents(connector);
if (names != null)
{
for (Iterator it = names.iterator(); it.hasNext(); )
@@ -182,15 +240,9 @@ public final class SonicMfContainerTool
}
}
// Fallback: documented canonical name even if not yet in query result
return preferred;
}
private static boolean belongsToDomain(ObjectName on, String domain)
{
return extractContainer(on, domain) != null;
}
private static String extractContainer(ObjectName on, String domain)
{
if (on == null || isBlank(domain))
@@ -224,12 +276,12 @@ public final class SonicMfContainerTool
return container;
}
private static String safeState(IAgentProxy agent)
private static String safeState(Object agent)
{
try
{
String s = agent.getStateString();
return s == null ? "?" : s;
Object s = agent.getClass().getMethod("getStateString").invoke(agent);
return s == null ? "?" : String.valueOf(s);
}
catch (Throwable t)
{
@@ -282,7 +334,7 @@ public final class SonicMfContainerTool
else if ("--container".equals(key)) a.container = val;
else if ("--timeout".equals(key))
{
try { a.timeoutSec = Integer.parseInt(val); } catch (Exception ignore) { /* keep default */ }
try { a.timeoutSec = Integer.parseInt(val); } catch (Exception ignore) { /* keep */ }
}
}