1 8 9 package mx4j.remote.rmi; 10 11 import java.io.IOException ; 12 import java.rmi.MarshalledObject ; 13 import java.security.AccessController ; 14 import java.security.PrivilegedAction ; 15 import java.security.PrivilegedActionException ; 16 import java.security.PrivilegedExceptionAction ; 17 import java.security.SecureClassLoader ; 18 import java.util.ArrayList ; 19 import java.util.Map ; 20 import java.util.Set ; 21 import javax.management.Attribute ; 22 import javax.management.AttributeList ; 23 import javax.management.AttributeNotFoundException ; 24 import javax.management.InstanceAlreadyExistsException ; 25 import javax.management.InstanceNotFoundException ; 26 import javax.management.IntrospectionException ; 27 import javax.management.InvalidAttributeValueException ; 28 import javax.management.ListenerNotFoundException ; 29 import javax.management.MBeanException ; 30 import javax.management.MBeanInfo ; 31 import javax.management.MBeanRegistrationException ; 32 import javax.management.MBeanServer ; 33 import javax.management.NotCompliantMBeanException ; 34 import javax.management.NotificationFilter ; 35 import javax.management.NotificationListener ; 36 import javax.management.ObjectInstance ; 37 import javax.management.ObjectName ; 38 import javax.management.QueryExp ; 39 import javax.management.ReflectionException ; 40 import javax.management.loading.ClassLoaderRepository ; 41 import javax.management.remote.NotificationResult ; 42 import javax.management.remote.rmi.RMIConnection ; 43 import javax.security.auth.Subject ; 44 45 import mx4j.remote.NotificationTuple; 46 import mx4j.remote.RemoteNotificationServerHandler; 47 48 55 public class RMIConnectionInvoker implements RMIConnection 56 { 57 private final MBeanServer server; 58 private final ClassLoader defaultLoader; 59 private final RemoteNotificationServerHandler notificationHandler; 60 61 public RMIConnectionInvoker(MBeanServer server, ClassLoader defaultLoader, Map environment) 62 { 63 this.server = server; 64 this.defaultLoader = defaultLoader; 65 this.notificationHandler = new RMIRemoteNotificationServerHandler(environment); 67 } 68 69 public String getConnectionId() throws IOException 70 { 71 throw new Error ("getConnectionId() must not be propagated along the invocation chain"); 72 } 73 74 public ObjectInstance createMBean(String className, ObjectName name, Subject delegate) 75 throws ReflectionException , 76 InstanceAlreadyExistsException , 77 MBeanRegistrationException , 78 MBeanException , 79 NotCompliantMBeanException , 80 IOException 81 { 82 return server.createMBean(className, name); 83 } 84 85 public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Subject delegate) 86 throws ReflectionException , 87 InstanceAlreadyExistsException , 88 MBeanRegistrationException , 89 MBeanException , 90 NotCompliantMBeanException , 91 InstanceNotFoundException , 92 IOException 93 { 94 return server.createMBean(className, name, loaderName); 95 } 96 97 public ObjectInstance createMBean(String className, ObjectName name, MarshalledObject params, String [] signature, Subject delegate) 98 throws ReflectionException , 99 InstanceAlreadyExistsException , 100 MBeanRegistrationException , 101 MBeanException , 102 NotCompliantMBeanException , 103 IOException 104 { 105 RepositoryClassLoader loader = (RepositoryClassLoader)AccessController.doPrivileged(new PrivilegedAction () 106 { 107 public Object run() 108 { 109 return new RepositoryClassLoader(server.getClassLoaderRepository()); 110 } 111 }); 112 Object [] args = (Object [])RMIMarshaller.unmarshal(params, loader, defaultLoader); 113 return server.createMBean(className, name, args, signature); 114 } 115 116 public ObjectInstance createMBean(String className, ObjectName name, final ObjectName loaderName, MarshalledObject params, String [] signature, Subject delegate) 117 throws ReflectionException , 118 InstanceAlreadyExistsException , 119 MBeanRegistrationException , 120 MBeanException , 121 NotCompliantMBeanException , 122 InstanceNotFoundException , 123 IOException 124 { 125 try 126 { 127 ClassLoader loader = (ClassLoader )AccessController.doPrivileged(new PrivilegedExceptionAction () 128 { 129 public Object run() throws InstanceNotFoundException 130 { 131 return server.getClassLoader(loaderName); 132 } 133 }); 134 Object [] args = (Object [])RMIMarshaller.unmarshal(params, loader, defaultLoader); 135 return server.createMBean(className, name, loaderName, args, signature); 136 } 137 catch (PrivilegedActionException x) 138 { 139 throw (InstanceNotFoundException )x.getException(); 140 } 141 } 142 143 public void unregisterMBean(ObjectName name, Subject delegate) throws InstanceNotFoundException , MBeanRegistrationException , IOException 144 { 145 server.unregisterMBean(name); 146 } 147 148 public ObjectInstance getObjectInstance(ObjectName name, Subject delegate) throws InstanceNotFoundException , IOException 149 { 150 return server.getObjectInstance(name); 151 } 152 153 public Set queryMBeans(ObjectName name, MarshalledObject query, Subject delegate) throws IOException 154 { 155 QueryExp filter = (QueryExp )RMIMarshaller.unmarshal(query, null, defaultLoader); 156 return server.queryMBeans(name, filter); 157 } 158 159 public Set queryNames(ObjectName name, MarshalledObject query, Subject delegate) throws IOException 160 { 161 QueryExp filter = (QueryExp )RMIMarshaller.unmarshal(query, null, defaultLoader); 162 return server.queryNames(name, filter); 163 } 164 165 public boolean isRegistered(ObjectName name, Subject delegate) throws IOException 166 { 167 return server.isRegistered(name); 168 } 169 170 public Integer getMBeanCount(Subject delegate) throws IOException 171 { 172 return server.getMBeanCount(); 173 } 174 175 public Object getAttribute(ObjectName name, String attribute, Subject delegate) 176 throws MBeanException , 177 AttributeNotFoundException , 178 InstanceNotFoundException , 179 ReflectionException , 180 IOException 181 { 182 return server.getAttribute(name, attribute); 183 } 184 185 public AttributeList getAttributes(ObjectName name, String [] attributes, Subject delegate) 186 throws InstanceNotFoundException , ReflectionException , IOException 187 { 188 return server.getAttributes(name, attributes); 189 } 190 191 public void setAttribute(ObjectName name, MarshalledObject attribute, Subject delegate) 192 throws InstanceNotFoundException , 193 AttributeNotFoundException , 194 InvalidAttributeValueException , 195 MBeanException , 196 ReflectionException , 197 IOException 198 { 199 Attribute attrib = (Attribute )RMIMarshaller.unmarshal(attribute, getClassLoaderFor(name), defaultLoader); 200 server.setAttribute(name, attrib); 201 } 202 203 public AttributeList setAttributes(ObjectName name, MarshalledObject attributes, Subject delegate) 204 throws InstanceNotFoundException , 205 ReflectionException , 206 IOException 207 { 208 AttributeList attribs = (AttributeList )RMIMarshaller.unmarshal(attributes, getClassLoaderFor(name), defaultLoader); 209 return server.setAttributes(name, attribs); 210 } 211 212 public Object invoke(ObjectName name, String operationName, MarshalledObject params, String [] signature, Subject delegate) 213 throws InstanceNotFoundException , 214 MBeanException , 215 ReflectionException , 216 IOException 217 { 218 Object [] args = (Object [])RMIMarshaller.unmarshal(params, getClassLoaderFor(name), defaultLoader); 219 return server.invoke(name, operationName, args, signature); 220 } 221 222 public String getDefaultDomain(Subject delegate) throws IOException 223 { 224 return server.getDefaultDomain(); 225 } 226 227 public String [] getDomains(Subject delegate) throws IOException 228 { 229 return server.getDomains(); 230 } 231 232 public MBeanInfo getMBeanInfo(ObjectName name, Subject delegate) throws InstanceNotFoundException , IntrospectionException , ReflectionException , IOException 233 { 234 return server.getMBeanInfo(name); 235 } 236 237 public boolean isInstanceOf(ObjectName name, String className, Subject delegate) throws InstanceNotFoundException , IOException 238 { 239 return server.isInstanceOf(name, className); 240 } 241 242 public void addNotificationListener(ObjectName name, ObjectName listener, MarshalledObject filter, MarshalledObject handback, Subject delegate) 243 throws InstanceNotFoundException , IOException 244 { 245 ClassLoader loader = getClassLoaderFor(name); 246 NotificationFilter f = (NotificationFilter )RMIMarshaller.unmarshal(filter, loader, defaultLoader); 247 Object h = RMIMarshaller.unmarshal(handback, loader, defaultLoader); 248 server.addNotificationListener(name, listener, f, h); 249 } 250 251 public void removeNotificationListener(ObjectName name, ObjectName listener, Subject delegate) 252 throws InstanceNotFoundException , ListenerNotFoundException , IOException 253 { 254 server.removeNotificationListener(name, listener); 255 } 256 257 public void removeNotificationListener(ObjectName name, ObjectName listener, MarshalledObject filter, MarshalledObject handback, Subject delegate) 258 throws InstanceNotFoundException , ListenerNotFoundException , IOException 259 { 260 ClassLoader loader = getClassLoaderFor(name); 261 NotificationFilter f = (NotificationFilter )RMIMarshaller.unmarshal(filter, loader, defaultLoader); 262 Object h = RMIMarshaller.unmarshal(handback, loader, defaultLoader); 263 server.removeNotificationListener(name, listener, f, h); 264 } 265 266 public Integer [] addNotificationListeners(ObjectName [] names, MarshalledObject [] filters, Subject [] delegates) throws InstanceNotFoundException , IOException 267 { 268 ArrayList ids = new ArrayList (); 269 for (int i = 0; i < names.length; ++i) 270 { 271 ObjectName name = names[i]; 272 MarshalledObject filter = filters[i]; 273 NotificationFilter f = (NotificationFilter )RMIMarshaller.unmarshal(filter, getClassLoaderFor(name), defaultLoader); 274 Integer id = notificationHandler.generateListenerID(name, f); 275 NotificationListener listener = notificationHandler.getServerNotificationListener(); 276 server.addNotificationListener(name, listener, f, id); 277 notificationHandler.addNotificationListener(id, new NotificationTuple(name, listener, f, id)); 278 ids.add(id); 279 } 280 return (Integer [])ids.toArray(new Integer [ids.size()]); 281 } 282 283 public void removeNotificationListeners(ObjectName name, Integer [] listenerIDs, Subject delegate) throws InstanceNotFoundException , ListenerNotFoundException , IOException 284 { 285 for (int i = 0; i < listenerIDs.length; ++i) 286 { 287 Integer id = listenerIDs[i]; 288 NotificationTuple tuple = notificationHandler.removeNotificationListener(id); 290 if (tuple != null) server.removeNotificationListener(name, tuple.getNotificationListener(), tuple.getNotificationFilter(), tuple.getHandback()); 291 } 292 } 293 294 public void close() throws IOException 295 { 296 NotificationTuple[] tuples = notificationHandler.close(); 297 for (int i = 0; i < tuples.length; ++i) 298 { 299 NotificationTuple tuple = tuples[i]; 300 try 301 { 302 server.removeNotificationListener(tuple.getObjectName(), tuple.getNotificationListener(), tuple.getNotificationFilter(), tuple.getHandback()); 303 } 304 catch (InstanceNotFoundException ignored) 305 { 306 } 307 catch (ListenerNotFoundException ignored) 308 { 309 } 310 } 311 } 312 313 public NotificationResult fetchNotifications(long clientSequenceNumber, int maxNotifications, long timeout) throws IOException 314 { 315 return notificationHandler.fetchNotifications(clientSequenceNumber, maxNotifications, timeout); 316 } 317 318 private ClassLoader getClassLoaderFor(final ObjectName name) throws InstanceNotFoundException 319 { 320 if (System.getSecurityManager() == null) 321 { 322 return server.getClassLoaderFor(name); 323 } 324 else 325 { 326 try 327 { 328 return (ClassLoader )AccessController.doPrivileged(new PrivilegedExceptionAction () 329 { 330 public Object run() throws InstanceNotFoundException 331 { 332 return server.getClassLoaderFor(name); 333 } 334 }); 335 } 336 catch (PrivilegedActionException x) 337 { 338 throw (InstanceNotFoundException )x.getException(); 339 } 340 } 341 } 342 343 private static class RepositoryClassLoader extends SecureClassLoader 344 { 345 private final ClassLoaderRepository repository; 346 347 private RepositoryClassLoader(ClassLoaderRepository repository) 348 { 349 this.repository = repository; 350 } 351 352 public Class loadClass(String name) throws ClassNotFoundException 353 { 354 return repository.loadClass(name); 355 } 356 } 357 } 358 | Popular Tags |