1 /*
   2  * Copyright (c) 2003, 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 4871761
  27  * @summary Tests that JMXServiceErrorException is correctly emitted.
  28  * @author Daniel Fuchs
  29  * @modules java.management.rmi
  30  *          java.management/com.sun.jmx.remote.security
  31  * @run clean JMXServerErrorTest
  32  * @run build JMXServerErrorTest
  33  * @run main  JMXServerErrorTest
  34  */
  35 
  36 import java.util.HashMap ;
  37 import java.util.Map ;
  38 import java.net.MalformedURLException;
  39 import java.io.IOException ;
  40 
  41 import javax.management.MBeanServerFactory;
  42 import javax.management.MBeanServer;
  43 import javax.management.MBeanServerConnection;
  44 import javax.management.ObjectName;
  45 import javax.management.MBeanServerInvocationHandler;
  46 import javax.management.remote.JMXServiceURL;
  47 import javax.management.remote.JMXConnectorFactory;
  48 import javax.management.remote.JMXConnectorServerFactory;
  49 import javax.management.remote.JMXConnector;
  50 import javax.management.remote.JMXConnectorServer;
  51 import javax.management.remote.JMXServerErrorException;
  52 
  53 import com.sun.jmx.remote.security.MBeanServerAccessController;
  54 
  55 public class JMXServerErrorTest {
  56 
  57     public static String urls[] = {
  58         "service:jmx:rmi://", "service:jmx:iiop://","service:jmx:jmxmp://"
  59     };
  60 
  61     public static class KaefferError extends Error {
  62         public KaefferError(String message, Throwable cause) {
  63             super(message,cause);
  64         }
  65     }
  66 
  67     /**
  68      * generates an error...
  69      **/
  70     public static class MBeanServerKaeffer
  71         extends MBeanServerAccessController {
  72 
  73         MBeanServerKaeffer(MBeanServer srv) {
  74             super();
  75             setMBeanServer(srv);
  76         }
  77 
  78 
  79         /**
  80          * Check if the caller can do read operations. This method does
  81          * nothing if so, otherwise throws SecurityException.
  82          */
  83         protected void checkRead() {
  84             // do nothing
  85         }
  86 
  87         /**
  88          * Check if the caller can do write operations.  This method does
  89          * nothing if so, otherwise throws SecurityException.
  90          */
  91         protected void checkWrite() {
  92             // generate error
  93             throw new KaefferError("Try to catch this!",null);
  94         }
  95     }
  96 
  97     public interface KaefferMBean {
  98         public String getThis() throws IOException;
  99         public void   setThis(String that) throws IOException;
 100         public String doThis(String that) throws IOException;
 101     }
 102 
 103     public static class Kaeffer implements KaefferMBean {
 104         String that = "";
 105         public Kaeffer(String that) {
 106             setThis(that);
 107         }
 108         public String getThis() {return that;}
 109         public void   setThis(String that) { this.that=(that==null)?"":that; }
 110         public String doThis(String that)  { return this.that += " " + that;}
 111     }
 112 
 113     public void test(String url) throws Exception {
 114         final JMXServiceURL jurl     = new JMXServiceURL(url);
 115         final ObjectName    kname    = new ObjectName(":type=Kaeffer");
 116         final MBeanServer   mbs      = MBeanServerFactory.newMBeanServer();
 117         final String        that     = "that";
 118         mbs.registerMBean(new Kaeffer(that),kname);
 119         final MBeanServer   kbs      = new MBeanServerKaeffer(mbs);
 120 
 121         final JMXConnectorServer cs;
 122         try {
 123             cs=JMXConnectorServerFactory.newJMXConnectorServer(jurl,null,kbs);
 124         } catch (MalformedURLException m) {
 125             if ("jmxmp".equals(jurl.getProtocol()) || "iiop".equals(jurl.getProtocol())) {
 126                 // OK, we may not have this in the classpath...
 127                 System.out.println("WARNING: Skipping protocol: " + jurl);
 128                 return;
 129             }
 130             throw m;
 131         }
 132 
 133         final ObjectName    cname    =
 134             new ObjectName(":type=JMXConnectorServer");
 135         mbs.registerMBean(cs,cname);
 136         cs.start();
 137         JMXConnector c = null;
 138         try {
 139             c = JMXConnectorFactory.connect(cs.getAddress(),null);
 140 
 141             final MBeanServerConnection mbsc = c.getMBeanServerConnection();
 142             final KaefferMBean kaeffer = (KaefferMBean)
 143                 MBeanServerInvocationHandler.
 144                 newProxyInstance(mbsc, kname, KaefferMBean.class, false);
 145             final String that1 = kaeffer.getThis();
 146             if (!that.equals(that1))
 147                 throw new Exception("Unexpected string returned by " +
 148                                     kname + ": " + that1);
 149             try {
 150                 kaeffer.setThis("but not that");
 151                 throw new Exception("Expected JMXServerErrorException"+
 152                                     " not thrown"+
 153                                     " for setAttribute \"This\" ");
 154             } catch (JMXServerErrorException jsee) {
 155                 if (!(jsee.getCause() instanceof KaefferError)) {
 156                     final Exception e =
 157                         new Exception("Expected JMXServerErrorException"+
 158                                       " is not an instance of " +
 159                                       KaefferError.class.getName()+
 160                                       ": " + jsee.getCause());
 161                     e.initCause(jsee);
 162                     throw e;
 163                 }
 164                 System.out.println("Got expected error: " +  jsee);
 165             }
 166 
 167             try {
 168                 kaeffer.doThis("but not that");
 169                 throw new Exception("Expected JMXServerErrorException" +
 170                                     " not thrown"+
 171                                     " for invoke \"doThis\" ");
 172             } catch (JMXServerErrorException jsee) {
 173                 if (!(jsee.getCause() instanceof KaefferError)) {
 174                     final Exception e =
 175                         new Exception("Expected JMXServerErrorException"+
 176                                       " is not an instance of " +
 177                                       KaefferError.class.getName()+
 178                                       ": " + jsee.getCause());
 179                     e.initCause(jsee);
 180                     throw e;
 181                 }
 182                 System.out.println("Got expected error: " +  jsee);
 183             }
 184         } finally {
 185             if (c != null) try { c.close(); }
 186             catch (Exception x) {
 187                 System.err.println("Failed to close client: " + x);
 188                 throw x;
 189             }
 190             try { cs.stop(); }
 191             catch (Exception x) {
 192                 System.err.println("Failed to stop server: " + x);
 193                 throw x;
 194             }
 195         }
 196     }
 197 
 198     public static void main(String args[]) {
 199         final JMXServerErrorTest test = new JMXServerErrorTest();
 200         int errCount=0;
 201         for (int i=0; i<urls.length; i++) {
 202             try {
 203                 System.out.println("Trying with url: " + urls[i]);
 204                 test.test(urls[i]);
 205                 System.out.println("PASSED: test passed for: " + urls[i]);
 206             } catch (Exception x) {
 207                 errCount++;
 208                 System.err.println("FAILED: test failed for " + urls[i] +
 209                                    ": " + x);
 210                 x.printStackTrace();
 211             }
 212         }
 213         if (errCount != 0) System.exit(errCount);
 214     }
 215 }