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