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