private Object invokeAttribute(PropertyDescriptor pd, MethodInvocation invocation) throws JMException, IOException { String attributeName = JmxUtils.getAttributeName(pd, this.useStrictCasing); MBeanAttributeInfo inf = (MBeanAttributeInfo) this.allowedAttributes.get(attributeName); // If no attribute is returned, we know that it is not defined in the // management interface. if (inf == null) { throw new InvalidInvocationException( "Attribute '" + pd.getName() + "' is not exposed on the management interface"); } if (invocation.getMethod().equals(pd.getReadMethod())) { if (inf.isReadable()) { return this.server.getAttribute(this.objectName, attributeName); } else { throw new InvalidInvocationException("Attribute '" + attributeName + "' is not readable"); } } else if (invocation.getMethod().equals(pd.getWriteMethod())) { if (inf.isWritable()) { server.setAttribute( this.objectName, new Attribute(attributeName, invocation.getArguments()[0])); return null; } else { throw new InvalidInvocationException("Attribute '" + attributeName + "' is not writable"); } } else { throw new IllegalStateException( "Method [" + invocation.getMethod() + "] is neither a bean property getter nor a setter"); } }
public void testAnnotatedMXBean() throws Exception { if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_16) { return; } FooX foo = new FooX(); assertTrue("MXBean annotation not detected correctly", JmxUtils.isMBean(foo.getClass())); }
/** * Loads the management interface info for the configured MBean into the caches. This information * is used by the proxy when determining whether an invocation matches a valid operation or * attribute on the management interface of the managed resource. */ private void retrieveMBeanInfo() throws MBeanServerNotFoundException, MBeanInfoRetrievalException { try { MBeanInfo info = this.server.getMBeanInfo(this.objectName); // get attributes MBeanAttributeInfo[] attributeInfo = info.getAttributes(); this.allowedAttributes = new HashMap(attributeInfo.length); for (int x = 0; x < attributeInfo.length; x++) { this.allowedAttributes.put(attributeInfo[x].getName(), attributeInfo[x]); } // get operations MBeanOperationInfo[] operationInfo = info.getOperations(); this.allowedOperations = new HashMap(operationInfo.length); for (int x = 0; x < operationInfo.length; x++) { MBeanOperationInfo opInfo = operationInfo[x]; this.allowedOperations.put( new MethodCacheKey( opInfo.getName(), JmxUtils.parameterInfoToTypes(opInfo.getSignature())), opInfo); } } catch (ClassNotFoundException ex) { throw new MBeanInfoRetrievalException( "Unable to locate class specified in method signature", ex); } catch (IntrospectionException ex) { throw new MBeanInfoRetrievalException( "Unable to obtain MBean info for bean [" + this.objectName + "]", ex); } catch (InstanceNotFoundException ex) { // if we are this far this shouldn't happen, but... throw new MBeanInfoRetrievalException( "Unable to obtain MBean info for bean [" + this.objectName + "]: it is likely that this bean was unregistered during the proxy creation process", ex); } catch (ReflectionException ex) { throw new MBeanInfoRetrievalException( "Unable to read MBean info for bean [ " + this.objectName + "]", ex); } catch (IOException ex) { throw new MBeanInfoRetrievalException( "An IOException occurred when communicating with the MBeanServer. " + "It is likely that you are communicating with a remote MBeanServer. " + "Check the inner exception for exact details.", ex); } }
/** * Connects to the remote <code>MBeanServer</code> using the configured <code>JMXServiceURL</code> * . * * @see #setServiceUrl(String) * @see #setConnectOnStartup(boolean) */ private void connect() throws MBeanServerNotFoundException { if (this.serviceUrl != null) { if (logger.isDebugEnabled()) { logger.debug("Connecting to remote MBeanServer at URL [" + this.serviceUrl + "]"); } try { this.connector = JMXConnectorFactory.connect(this.serviceUrl); this.server = this.connector.getMBeanServerConnection(); } catch (IOException ex) { throw new MBeanServerNotFoundException( "Could not connect to remote MBeanServer at URL [" + this.serviceUrl + "]", ex); } } else { logger.debug("Attempting to locate local MBeanServer"); this.server = JmxUtils.locateMBeanServer(); } }
/** * Routes a method invocation (not a property get/set) to the corresponding operation on the * managed resource. * * @param method the method corresponding to operation on the managed resource. * @param args the invocation arguments * @return the value returned by the method invocation. */ private Object invokeOperation(Method method, Object[] args) throws JMException, IOException { MethodCacheKey key = new MethodCacheKey(method.getName(), method.getParameterTypes()); MBeanOperationInfo info = (MBeanOperationInfo) this.allowedOperations.get(key); if (info == null) { throw new InvalidInvocationException( "Operation '" + method.getName() + "' is not exposed on the management interface"); } String[] signature = null; synchronized (this.signatureCache) { signature = (String[]) this.signatureCache.get(method); if (signature == null) { signature = JmxUtils.getMethodSignature(method); this.signatureCache.put(method, signature); } } return this.server.invoke(this.objectName, method.getName(), args, signature); }
/** * Registers the component specifying the info that describes it. * * <p>Certain interfaces are automatically detected. If the component implements {@code * Lifecycle}, it will be registered as though using {@link #registerLifecycle(Lifecycle)}. If it * implements {@code ServletContextAware}, then it will be registered as though using {@link * #registerServletContextAware(ServletContextAware)}. If it implements {@code InitializingBean}, * then it will be initialized as though using {@link #initialize(InitializingBean)}. * * <p>If the component implements {@code FactoryBean}, it will be checked for the automatically * detected interfaces before the factory is evaluated. The evaluated factory will then be * registered, and the resulting object will again be checked for automatically detected * interfaces. * * @param info the component info to register, not null * @param instance the component instance to register, not null * @throws IllegalArgumentException if unable to register */ public void registerComponent(final ComponentInfo info, Object instance) { ArgumentChecker.notNull(info, "info"); ArgumentChecker.notNull(instance, "instance"); checkStatus(Status.CREATING); final ComponentKey key = info.toComponentKey(); try { // initialize initialize0(instance); registerInstanceInterfaces0(instance); // handle factories if (instance instanceof FactoryBean<?>) { try { instance = ((FactoryBean<?>) instance).getObject(); } catch (final Exception ex) { throw new OpenGammaRuntimeException("FactoryBean threw exception", ex); } initialize0(instance); registerInstanceInterfaces0(instance); } // register into data structures final Object current = _instanceMap.putIfAbsent(key, instance); if (current != null) { throw new IllegalArgumentException( "Component already registered for specified information: " + key); } _infoMap.putIfAbsent(info.getType(), new ComponentTypeInfo(info.getType())); final ComponentTypeInfo typeInfo = getTypeInfo(info.getType()); typeInfo.getInfoMap().put(info.getClassifier(), info); registeredComponent(info, instance); // If the component being registered is also an MBean, then register it as such if (JmxUtils.isMBean(instance.getClass())) { registerMBean(instance); } } catch (final RuntimeException ex) { _status.set(Status.FAILED); throw new RuntimeException("Failed during registration: " + key, ex); } }