From 225f80532cbeb1597c7f5d660e67d4fa4248c83f Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Wed, 1 Feb 2023 09:14:25 +0000 Subject: [PATCH] 8299891: JMX ObjectInputFilter additional classes needed Reviewed-by: dfuchs, sspitsyn, cjplummer --- .../share/conf/management.properties | 23 ++- .../connection/DefaultAgentFilterTest.java | 148 ++++++++++++++++-- 2 files changed, 158 insertions(+), 13 deletions(-) diff --git a/src/jdk.management.agent/share/conf/management.properties b/src/jdk.management.agent/share/conf/management.properties index 6f4d77cfc2249..6df414e922466 100644 --- a/src/jdk.management.agent/share/conf/management.properties +++ b/src/jdk.management.agent/share/conf/management.properties @@ -302,5 +302,26 @@ # If the pattern ends with "*", it matches any class with the pattern as a prefix. # If the pattern is equal to the class name, it matches. # Otherwise, the status is UNDECIDED. -com.sun.management.jmxremote.serial.filter.pattern=java.lang.*;java.math.BigInteger;java.math.BigDecimal;java.util.*;javax.management.openmbean.*;javax.management.ObjectName;java.rmi.MarshalledObject;javax.security.auth.Subject;!* +# +# Ending with !* ensures we reject classes which are otherwise unmatched. +com.sun.management.jmxremote.serial.filter.pattern=\ +java.lang.*;\ +java.lang.reflect.Proxy;\ +java.math.BigInteger;\ +java.math.BigDecimal;\ +java.util.*;\ +javax.management.*;\ +javax.management.modelmbean.*;\ +javax.management.monitor.*;\ +javax.management.openmbean.*;\ +javax.management.relation.*;\ +javax.management.remote.*;\ +javax.management.remote.rmi.*;\ +javax.management.timer.*;\ +javax.rmi.ssl.*;\ +java.rmi.MarshalledObject;\ +java.rmi.dgc.*;\ +java.rmi.server.*;\ +javax.security.auth.Subject;\ +!* diff --git a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java index 71d8477358abb..603e2890a0e4f 100644 --- a/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java +++ b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8159377 8283093 + * @bug 8159377 8283093 8299891 * @library /test/lib * @summary Tests ObjectFilter on default agent * @author Harsha Wardhana B @@ -48,9 +48,20 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeChangeNotification; import javax.management.MBeanServerConnection; import javax.management.ObjectName; +import javax.management.ObjectInstance; +import javax.management.MBeanNotificationInfo; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; +import javax.management.Query; +import javax.management.QueryExp; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; @@ -73,9 +84,22 @@ public interface TestMBean { public void op2(String s, HashSet params); public void op3(MyTestObject obj, String s, HashMap param); + + public void setMyAttribute(boolean b); + + public boolean getMyAttribute(); + + public void setMyAttribute2(String s); + + public String getMyAttribute2(); } - public static class Test implements TestMBean { + public static class Test extends NotificationBroadcasterSupport implements TestMBean { + + boolean myAttribute; + String myAttribute2; + + private long sequenceNumber = 1; @Override public void op1(HashSet params) { @@ -91,6 +115,41 @@ public void op2(String s, HashSet params) { public void op3(MyTestObject obj, String s, HashMap param) { System.out.println("Invoked op3"); } + + public void setMyAttribute(boolean b) { + this.myAttribute = b; + System.out.println("Invoked setMyAttribute"); + } + + public boolean getMyAttribute() { + System.out.println("Invoked getMyAttribute"); + return myAttribute; + } + + public void setMyAttribute2(String s) { + String old = myAttribute2; + this.myAttribute2 = s; + Notification n = new AttributeChangeNotification(this, sequenceNumber++, System.currentTimeMillis(), + "String attribute changed", "myAttribute2", "String", + old, this.myAttribute2); + sendNotification(n); + System.out.println("Invoked setMyAttribute2"); + } + + public String getMyAttribute2() { + System.out.println("Invoked getMyAttribute2"); + return myAttribute2; + } + + @Override + public MBeanNotificationInfo[] getNotificationInfo() { + System.out.println("Invoked getNotificationInfo"); + String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }; + String name = AttributeChangeNotification.class.getName(); + String description = "An attribute of this MBean has changed"; + MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description); + return new MBeanNotificationInfo[] {info}; + } } private static class TestAppRun implements AutoCloseable { @@ -172,17 +231,22 @@ public void close() throws Exception { private static final int FREE_PORT_ATTEMPTS = 10; private static void testDefaultAgent(String propertyFile) throws Exception { - testDefaultAgent(propertyFile, null); + testDefaultAgent(propertyFile, null, true /* test operations */); } - private static void testDefaultAgent(String propertyFile, String additionalArgument) throws Exception { + private static void testDefaultAgent(String propertyFile, boolean testOperations) throws Exception { + testDefaultAgent(propertyFile, null, testOperations); + } + + private static void testDefaultAgent(String propertyFile, String additionalArgument, boolean testOperations) throws Exception { for (int i = 1; i <= FREE_PORT_ATTEMPTS; i++) { int port = Utils.getFreePort(); - System.out.println("Attempting testDefaultAgent(" + - (propertyFile != null ? propertyFile : "no properties") + System.out.println("Attempting testDefaultAgent(" + + (propertyFile != null ? propertyFile : "no properties") + + " testOperations=" + testOperations + ") with port: " + port); try { - testDefaultAgent(propertyFile, additionalArgument, port); + testDefaultAgent(propertyFile, additionalArgument, port, testOperations); break; // return succesfully } catch (BindException b) { // Retry with new port. Throw if last iteration: @@ -193,7 +257,11 @@ private static void testDefaultAgent(String propertyFile, String additionalArgum } } - private static void testDefaultAgent(String propertyFile, String additionalArgument, int port) throws Exception { + /** + * Run the test app and connect. Test MBean Operations if the boolean testOperations is true, otherwise + * test other usages (Attributes, Query) + */ + private static void testDefaultAgent(String propertyFile, String additionalArgument, int port, boolean testOperations) throws Exception { List pbArgs = new ArrayList<>(Arrays.asList( "-cp", System.getProperty("test.class.path"), @@ -219,7 +287,11 @@ private static void testDefaultAgent(String propertyFile, String additionalArgum try (TestAppRun s = new TestAppRun(pb, DefaultAgentFilterTest.class.getSimpleName())) { s.start(); JMXServiceURL url = testConnect(port); - testMBeanOperations(url); + if (testOperations) { + testMBeanOperations(url); + } else { + testMBeanOtherClasses(url); + } } } @@ -266,7 +338,7 @@ public static void main(String[] args) throws Exception { System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: starting ..."); try { - // filter DefaultAgentFilterTest$MyTestObject + // Properties file filter blocks DefaultAgentFilterTest$MyTestObject testDefaultAgent("mgmt1.properties"); System.out.println("----\tTest FAILED !!"); throw new RuntimeException("---" + DefaultAgentFilterTest.class.getName() + " - No exception reported"); @@ -304,11 +376,20 @@ public static void main(String[] args) throws Exception { throw ex; } } + try { + // Test Attributes and Query work by default: + testDefaultAgent(null /* no properties file */, false /* not testing operations */); + } catch (Exception ex) { + System.out.println(ex); + System.out.println("----\tTest FAILED !!"); + throw ex; + } try { // Add custom filter on command-line. testDefaultAgent(null, "-Dcom.sun.management.jmxremote.serial.filter.pattern=\"java.lang.*;java.math.BigInteger;" + "java.math.BigDecimal;java.util.*;javax.management.openmbean.*;javax.management.ObjectName;" - + "java.rmi.MarshalledObject;javax.security.auth.Subject;DefaultAgentFilterTest$MyTestObject;!*\""); + + "java.rmi.MarshalledObject;javax.security.auth.Subject;DefaultAgentFilterTest$MyTestObject;!*\"", + true /* test operations */); System.out.println("----\tTest PASSED: with custom filter on command-line"); } catch (Exception ex) { System.out.println(ex); @@ -346,6 +427,49 @@ private static void testMBeanOperations(JMXServiceURL serverUrl) throws Exceptio String[] sig3 = {MyTestObject.class.getName(), String.class.getName(), HashMap.class.getName()}; conn.invoke(name, "op3", params3, sig3); + + System.out.println("Done testMBeanOperations"); + } + } + + private static void testMBeanOtherClasses(JMXServiceURL serverUrl) throws Exception { + Map clientEnv = new HashMap<>(1); + ObjectName name = new ObjectName("jtreg:type=Test"); + try (JMXConnector client = JMXConnectorFactory.connect(serverUrl, clientEnv)) { + MBeanServerConnection conn = client.getMBeanServerConnection(); + + // Set operations send types to the server and can conflict with the filter. + // Attribute set operations require javax.management.Attribute. + conn.setAttribute(name, new Attribute("MyAttribute", Boolean.TRUE)); + boolean b = (Boolean) conn.getAttribute(name, "MyAttribute"); + if (b != true) { + throw new RuntimeException("Attribute not as expected, got: " + b); + } + conn.setAttribute(name, new Attribute("MyAttribute2", "my string value")); + String s = (String) conn.getAttribute(name, "MyAttribute2"); + if (!s.equals("my string value")) { + throw new RuntimeException("Attribute not as expected, got: " + s); + } + + // Use javax.management.AttributeList: + AttributeList attrs = conn.getAttributes(name, new String [] { "MyAttribute", "MyAttribute2" }); + attrs = conn.setAttributes(name, attrs); // Setting fails if filter too restrictive + + // Sending a Query uses several classes from javax.management: + QueryExp exp = Query.isInstanceOf(Query.value("notImportantClassName")); + Set queryResult = conn.queryMBeans(name, exp); + + // Notification: + conn.addNotificationListener(name, new NotificationListener() { + public void handleNotification(Notification notification, Object handback) { + System.out.println("Received notification: " + notification); + } }, null, null); + // Trigger a Notification: + conn.setAttribute(name, new Attribute("MyAttribute2", "my new string value")); + // Receiving the AttributeChangeNotification is not truly important for this test: + try { Thread.sleep(5000); } catch (InterruptedException ie) { } + + System.out.println("Done testMBeanOtherClasses"); } } }