1 /* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8058865 27 * @summary Checks that a serialized instance is not transmitted from an MXBean. 28 * All the communication should be done via Open Types 29 * @author Olivier Lagneau 30 * 31 * @library /lib/testlibrary 32 * @modules java.management.rmi 33 * 34 * @compile Basic.java 35 * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest 36 */ 37 38 import java.util.Map; 39 import java.util.List; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 43 import java.lang.Process; 44 import java.lang.management.ManagementFactory; 45 46 import javax.management.MBeanServer; 47 import javax.management.MBeanServerConnection; 48 import javax.management.remote.JMXConnector; 49 import javax.management.remote.JMXConnectorFactory; 50 import javax.management.remote.JMXConnectorServer; 51 import javax.management.remote.JMXConnectorServerFactory; 52 import javax.management.remote.JMXServiceURL; 53 54 import javax.management.ObjectName; 55 import javax.management.openmbean.CompositeType; 56 import javax.management.openmbean.CompositeData; 57 import javax.management.openmbean.CompositeDataSupport; 58 import javax.management.openmbean.OpenType; 59 import javax.management.openmbean.SimpleType; 60 import javax.management.openmbean.TabularDataSupport; 61 import javax.management.openmbean.TabularType; 62 63 import jdk.testlibrary.ProcessTools; 64 import jdk.testlibrary.JDKToolFinder; 65 66 public class MXBeanWeirdParamTest { 67 68 private static String BASIC_MXBEAN_CLASS_NAME = "Basic"; 69 70 private static final String CLIENT_CLASS_MAIN = 71 "MXBeanWeirdParamTest$ClientSide"; 72 73 private JMXConnectorServer cs; 74 75 /* 76 * First Debug properties and arguments are collect in expected 77 * map (argName, value) format, then calls original test's run method. 78 */ 79 public static void main(String args[]) throws Exception { 80 81 System.out.println("================================================="); 82 83 // Parses parameters 84 Utils.parseDebugProperties(); 85 Map<String, Object> map = Utils.parseParameters(args) ; 86 87 // Run test 88 MXBeanWeirdParamTest test = new MXBeanWeirdParamTest(); 89 test.run(map); 90 91 } 92 93 /* 94 * Create the MBeansServe side of the test and returns its address 95 */ 96 private JMXServiceURL createServerSide() throws Exception { 97 final int NINETY_SECONDS = 90; 98 99 // We will use the platform mbean server 100 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 101 102 JMXServiceURL url = new JMXServiceURL("rmi", null, 0); 103 cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); 104 cs.start(); 105 106 Utils.waitReady(cs, NINETY_SECONDS); 107 108 JMXServiceURL addr = cs.getAddress(); 109 return addr; 110 } 111 112 113 /* 114 * Creating command-line for running subprocess JVM: 115 * 116 * JVM command line is like: 117 * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main 118 * 119 * {defaultopts} are the default java options set by the framework. 120 * 121 */ 122 private List<String> buildCommandLine() { 123 List<String> opts = new ArrayList<>(); 124 opts.add(JDKToolFinder.getJDKTool("java")); 125 opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts())); 126 // We need to set WEIRD_PARAM propertty on the client-side 127 opts.add("-DWEIRD_PARAM"); 128 opts.add("-cp"); 129 opts.add(System.getProperty("test.class.path", "test.class.path")); 130 opts.add(CLIENT_CLASS_MAIN); 131 132 return opts; 133 } 134 135 /** 136 * Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects 137 * subprocess standard I/O to the current (parent) process. This provides a 138 * trace of what happens in the subprocess while it is runnning (and before 139 * it terminates). 140 * 141 * @param serviceUrlStr string representing the JMX service Url to connect to. 142 */ 143 private int runClientSide(String serviceUrlStr) throws Exception { 144 145 // Building command-line 146 List<String> opts = buildCommandLine(); 147 opts.add(serviceUrlStr); 148 149 // Launch separate JVM subprocess 150 int exitCode = 0; 151 String[] optsArray = opts.toArray(new String[0]); 152 ProcessBuilder pb = new ProcessBuilder(optsArray); 153 Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb); 154 155 // Handling end of subprocess 156 try { 157 exitCode = p.waitFor(); 158 if (exitCode != 0) { 159 System.out.println( 160 "Subprocess unexpected exit value of [" + exitCode + 161 "]. Expected 0.\n"); 162 } 163 } catch (InterruptedException e) { 164 System.out.println("Parent process interrupted with exception : \n " + e + " :" ); 165 166 // Parent thread unknown state, killing subprocess. 167 p.destroyForcibly(); 168 169 throw new RuntimeException( 170 "Parent process interrupted with exception : \n " + e + " :" ); 171 } finally { 172 return exitCode; 173 } 174 175 } 176 177 public void run(Map<String, Object> args) throws Exception { 178 179 System.out.println("MXBeanWeirdParamTest::run: Start") ; 180 int errorCount = 0; 181 182 try { 183 // Initialise the server side 184 JMXServiceURL urlToUse = createServerSide(); 185 186 // Run client side 187 errorCount = runClientSide(urlToUse.toString()); 188 189 if ( errorCount == 0 ) { 190 System.out.println("MXBeanWeirdParamTest::run: Done without any error") ; 191 } else { 192 System.out.println("MXBeanWeirdParamTest::run: Done with " 193 + errorCount 194 + " error(s)") ; 195 throw new RuntimeException("errorCount = " + errorCount); 196 } 197 198 cs.stop(); 199 200 } catch(Exception e) { 201 throw new RuntimeException(e); 202 } 203 204 } 205 206 private static class ClientSide { 207 public static void main(String args[]) throws Exception { 208 209 int errorCount = 0 ; 210 String msgTag = "ClientSide::main: "; 211 212 try { 213 214 // Get a connection to remote mbean server 215 JMXServiceURL addr = new JMXServiceURL(args[0]); 216 JMXConnector cc = JMXConnectorFactory.connect(addr); 217 MBeanServerConnection mbsc = cc.getMBeanServerConnection(); 218 219 // ---- 220 System.out.println(msgTag + "Create and register the MBean"); 221 ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ; 222 mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName); 223 System.out.println(msgTag +"---- OK\n") ; 224 225 // ---- 226 System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean"); 227 Object result = mbsc.getAttribute(objName, "SqeParameterAtt"); 228 System.out.println(msgTag +"(OK) Got result of class " 229 + result.getClass().getName()); 230 System.out.println(msgTag +"Received CompositeData is " + result); 231 System.out.println(msgTag +"---- OK\n") ; 232 233 // ---- 234 // We use the value returned by getAttribute to perform the invoke. 235 System.out.println(msgTag +"Call operation doWeird on our MXBean [1]"); 236 mbsc.invoke(objName, "doWeird", 237 new Object[]{result}, 238 new String[]{"javax.management.openmbean.CompositeData"}); 239 System.out.println(msgTag +"---- OK\n") ; 240 241 // ---- 242 // We build the CompositeData ourselves that time. 243 System.out.println(msgTag +"Call operation doWeird on our MXBean [2]"); 244 String typeName = "SqeParameter"; 245 String[] itemNames = new String[] {"glop"}; 246 OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING}; 247 CompositeType rowType = new CompositeType(typeName, typeName, 248 itemNames, itemNames, openTypes); 249 Object[] itemValues = {"HECTOR"}; 250 CompositeData data = 251 new CompositeDataSupport(rowType, itemNames, itemValues); 252 TabularType tabType = new TabularType(typeName, typeName, 253 rowType, new String[]{"glop"}); 254 TabularDataSupport tds = new TabularDataSupport(tabType); 255 tds.put(data); 256 System.out.println(msgTag +"Source CompositeData is " + data); 257 mbsc.invoke(objName, "doWeird", 258 new Object[]{data}, 259 new String[]{"javax.management.openmbean.CompositeData"}); 260 System.out.println(msgTag +"---- OK\n") ; 261 262 // ---- 263 System.out.println(msgTag +"Unregister the MBean"); 264 mbsc.unregisterMBean(objName); 265 System.out.println(msgTag +"---- OK\n") ; 266 267 // Terminate the JMX Client 268 cc.close(); 269 270 } catch(Exception e) { 271 Utils.printThrowable(e, true) ; 272 errorCount++; 273 throw new RuntimeException(e); 274 } finally { 275 System.exit(errorCount); 276 } 277 } 278 } 279 }