Path: blob/master/test/jdk/javax/management/mxbean/ExceptionDiagnosisTest.java
41152 views
/*1* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 671377726* @summary Test that exception messages include all relevant information27* @author Eamonn McManus28*/2930import javax.management.ConstructorParameters;31import java.io.File;32import java.lang.reflect.InvocationTargetException;33import java.lang.reflect.Method;34import java.lang.reflect.Type;35import java.util.ArrayList;36import java.util.HashMap;37import java.util.List;38import javax.management.JMX;39import javax.management.MBeanServer;40import javax.management.MBeanServerFactory;41import javax.management.NotCompliantMBeanException;42import javax.management.ObjectName;4344public class ExceptionDiagnosisTest {45private static volatile String failure;4647// ------ Illegal MXBeans ------4849// Test that all of BdelloidMXBean, Rotifer, and File appear in the50// exception messages. File is not an allowed type because of recursive51// getters like "File getParentFile()".52public static interface BdelloidMXBean {53public Rotifer getRotifer();54}5556public static class Bdelloid implements BdelloidMXBean {57public Rotifer getRotifer() {58return null;59}60}6162public static class Rotifer {63public File getFile() {64return null;65}66}6768// Test that all of IndirectHashMapMXBean, HashMapContainer, and69// HashMap<String,String> appear in the exception messages.70// HashMap<String,String> is not an allowed type because only the71// java.util interface such as Map are allowed with generic parameters,72// not their concrete implementations like HashMap.73public static interface IndirectHashMapMXBean {74public HashMapContainer getContainer();75}7677public static class IndirectHashMap implements IndirectHashMapMXBean {78public HashMapContainer getContainer() {79return null;80}81}8283public static class HashMapContainer {84public HashMap<String, String> getHashMap() {return null;}85}8687// ------ MXBeans that are legal but where proxies are not ------8889// Test that all of BlimMXBean, BlimContainer, Blim, and Blam appear90// in the exception messages for a proxy for this MXBean. Blam is91// legal in MXBeans but is not reconstructible so you cannot make92// a proxy for BlimMXBean.93public static interface BlimMXBean {94public BlimContainer getBlimContainer();95}9697public static class BlimImpl implements BlimMXBean {98public BlimContainer getBlimContainer() {99return null;100}101}102103public static class BlimContainer {104public Blim getBlim() {return null;}105public void setBlim(Blim blim) {}106}107108public static class Blim {109public Blam getBlam() {return null;}110public void setBlam(Blam blam) {}111}112113public static class Blam {114public Blam(int x) {}115116public int getX() {return 0;}117}118119120// ------ Property name differing only in case ------121122public static interface CaseProbMXBean {123public CaseProb getCaseProb();124}125126public static class CaseProbImpl implements CaseProbMXBean {127public CaseProb getCaseProb() {return null;}128}129130public static class CaseProb {131@ConstructorParameters({"urlPath"})132public CaseProb(String urlPath) {}133134public String getURLPath() {return null;}135}136137138public static void main(String[] args) throws Exception {139testMXBeans(new Bdelloid(), BdelloidMXBean.class, Rotifer.class, File.class);140testMXBeans(new IndirectHashMap(),141IndirectHashMapMXBean.class, HashMapContainer.class,142HashMapContainer.class.getMethod("getHashMap").getGenericReturnType());143144testProxies(new BlimImpl(), BlimMXBean.class, BlimMXBean.class,145BlimContainer.class, Blim.class, Blam.class);146147testCaseProb();148149if (failure == null)150System.out.println("TEST PASSED");151else152throw new Exception("TEST FAILED: " + failure);153}154155private static void testMXBeans(Object mbean, Type... expectedTypes)156throws Exception {157try {158MBeanServer mbs = MBeanServerFactory.newMBeanServer();159ObjectName name = new ObjectName("a:b=c");160mbs.registerMBean(mbean, name);161fail("No exception from registerMBean for " + mbean);162} catch (NotCompliantMBeanException e) {163checkExceptionChain("MBean " + mbean, e, expectedTypes);164}165}166167private static <T> void testProxies(168Object mbean, Class<T> mxbeanClass, Type... expectedTypes)169throws Exception {170MBeanServer mbs = MBeanServerFactory.newMBeanServer();171ObjectName name = new ObjectName("a:b=c");172mbs.registerMBean(mbean, name);173T proxy = JMX.newMXBeanProxy(mbs, name, mxbeanClass);174List<Method> methods = new ArrayList<Method>();175for (Method m : mxbeanClass.getMethods()) {176if (m.getDeclaringClass() == mxbeanClass)177methods.add(m);178}179if (methods.size() != 1) {180fail("TEST BUG: expected to find exactly one method in " +181mxbeanClass.getName() + ": " + methods);182}183Method getter = methods.get(0);184try {185try {186getter.invoke(proxy);187fail("No exception from proxy method " + getter.getName() +188" in " + mxbeanClass.getName());189} catch (InvocationTargetException e) {190Throwable cause = e.getCause();191if (cause instanceof Exception)192throw (Exception) cause;193else194throw (Error) cause;195}196} catch (IllegalArgumentException e) {197checkExceptionChain(198"Proxy for " + mxbeanClass.getName(), e, expectedTypes);199}200}201202private static void testCaseProb() throws Exception {203MBeanServer mbs = MBeanServerFactory.newMBeanServer();204ObjectName name = new ObjectName("a:b=c");205mbs.registerMBean(new CaseProbImpl(), name);206CaseProbMXBean proxy = JMX.newMXBeanProxy(mbs, name, CaseProbMXBean.class);207try {208CaseProb prob = proxy.getCaseProb();209fail("No exception from proxy method getCaseProb");210} catch (IllegalArgumentException e) {211String messageChain = messageChain(e);212if (messageChain.contains("URLPath")) {213System.out.println("Message chain contains URLPath as required: "214+ messageChain);215} else {216fail("Exception chain for CaseProb does not mention property" +217" URLPath differing only in case");218System.out.println("Full stack trace:");219e.printStackTrace(System.out);220}221}222}223224private static void checkExceptionChain(225String what, Throwable e, Type[] expectedTypes) {226System.out.println("Exceptions in chain for " + what + ":");227for (Throwable t = e; t != null; t = t.getCause())228System.out.println(".." + t);229230String messageChain = messageChain(e);231232// Now check that each of the classes is mentioned in those messages233for (Type type : expectedTypes) {234String name = (type instanceof Class) ?235((Class<?>) type).getName() : type.toString();236if (!messageChain.contains(name)) {237fail("Exception chain for " + what + " does not mention " +238name);239System.out.println("Full stack trace:");240e.printStackTrace(System.out);241}242}243244System.out.println();245}246247private static String messageChain(Throwable t) {248String msg = "//";249for ( ; t != null; t = t.getCause())250msg += " " + t.getMessage() + " //";251return msg;252}253254private static void fail(String why) {255failure = why;256System.out.println("FAIL: " + why);257}258}259260261