I am trying to write a sample JMX application. Here is my MBean class:
package com.pramati.jmx;
@Component
@ManagedResource(objectName="modelMBean:type=simple-calculator",
description="Calculator performing basic arithmetic on integers")
public class SimpleCalculator {
private int operand1;
private int operand2;
public SimpleCalculator() {
System.out.println("SimpleCalculator - MBean created!!");
}
@ManagedOperation(description="Addition operation")
public int add() {
return operand1 + operand2;
}
@ManagedOperation(description="Multiplication operation")
public int multiply() {
return operand1 * operand2;
}
@ManagedOperation(description="Division operation")
@ManagedOperationParameters({
@ManagedOperationParameter(name="operand1", description="Dividend"),
@ManagedOperationParameter(name="operand2", description="Divisor")
})
public int divide(int operand1, int operand2) {
if(operand2 == 0) {
throw new IllegalArgumentException("Can not divide by zero");
}
return operand1 / operand2;
}
@ManagedAttribute
public int getOperand1() {
return operand1;
}
@ManagedAttribute
public void setOperand1(int operand1) {
this.operand1 = operand1;
}
@ManagedAttribute
public int getOperand2() {
return operand2;
}
@ManagedAttribute
public void setOperand2(int operand2) {
this.operand2 = operand2;
}
}
And here is the bean declaration from applicationContext:
<context:component-scan base-package="com.pramati.jmx"/>
<bean id="mbeanExporter" class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
Now when I run jconsole, I am not seeing my Mbean in it. But when I explicitly declare the bean as follows:
<bean id="calculator" class="com.pramati.jmx.SimpleCalculator">
<property name="operand1" value="1000"/>
<property name="operand2" value="50"/>
</bean>
<bean id="mbeanExporter" class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
Now if I run jconsole, I am seeing the Mbean. Why is it that the MBean is not getting registered when I am using component-scan?
Here is my complete applicationContext:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="mbeanExporter" class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
<context:component-scan base-package="com.pramati.model"/>
<context:component-scan base-package="com.pramati.controller"/>
<context:component-scan base-package="com.pramati.service"/>
<context:component-scan base-package="com.pramati.validator"/>
<context:component-scan base-package="com.pramati.type.converters"/>
<context:component-scan base-package="com.pramati.jmx"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean class="com.pramati.spring.mvc.CustomWebBindingInitializer"/>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<mvc:interceptors>
<bean class="com.pramati.spring.mvc.LoggingInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/reservationQuery/**"/>
<bean class="com.pramati.spring.mvc.AuditTimeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<bean name="internalresourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="#{xmlViewResolver.order+1}"/>
</bean>
<bean name="xmlViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="/WEB-INF/court-views.xml"/>
<property name="order" value="#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE}"/>
</bean>
<bean name="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="fr_FR"></property>
</bean>
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${connection.driverClassName}"/>
<property name="url" value="${connection.url}"/>
<property name="username" value="${connection.username}"/>
<property name="password" value="${connection.password}"/>
<property name="initialSize" value="${connection.initialSize}"/>
<property name="maxActive" value="${connection.maxActive}"/>
</bean>
<context:property-placeholder location="classpath:spring/config.properties"/>
<bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>properties/resourceBundle</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.pramati.exception.ResourceNotFoundException">
exceptions/resourceNotFound
</prop>
</props>
</property>
<property name="defaultErrorView" value="exceptions/error"/>
</bean>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<property name="converters">
<set>
<bean class="com.pramati.type.converters.StringToSportTypeConverter"/>
<bean class="com.pramati.type.converters.StringToDateConverter"/>
<bean class="com.pramati.type.converters.StringToPlayerConverter"/>
</set>
</property>
</bean>
<bean id="defaultReservation" class="com.pramati.model.Reservation">
<property name="courtName" value="Soccer Court #1"/>
<property name="date" value="11-11-2011"/>
<property name="hour" value="15"/>
<property name="player" value="Prasanth,9010107771"/>
<property name="sportType" value="2"></property>
</bean>
</beans>
Here is security context:
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="ROLE_"/>
</beans:bean>
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
<beans:bean class="com.pramati.spring.mvc.LocalIpVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<http access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/app/messageList*" access="ROLE_USER,ROLE_ANONYMOUS"/>
<intercept-url pattern="/app/messagePost*" access="ROLE_USER"/>
<intercept-url pattern="/app/messageDelete*" access="ROLE_ADMIN,IP_LOCAL_HOST"/>
<form-login login-page="/login.jsp" default-target-url="/app/messagePost"
authentication-failure-url="/login.jsp?error=true"/>
<logout logout-success-url="/login.jsp"/>
<remember-me services-alias="rememberMeService" key="springRocks" data-source-ref="dataSource"/>
<!-- <remember-me data-source-ref="dataSource" key="pramati"/> -->
<session-management session-authentication-error-url="/login.jsp?error=alreadyLoggedin" >
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"
expired-url="/login.jsp?error=alreadyLoggedin"/>
</session-management>
</http>
<beans:bean id="tokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="createTableOnStartup" value="false"/>
</beans:bean>
<beans:bean id="rememberMeService" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
<beans:property name="key" value="springRocks"/>
<beans:property name="userDetailsService" ref="userDetailsService"/>
<beans:property name="tokenRepository" ref="tokenRepository"/>
<beans:property name="alwaysRemember" value="true"/>
</beans:bean>
<authentication-manager>
<authentication-provider>
<!-- TBD <password-encoder hash="md5"/> -->
<jdbc-user-service id="userDetailsService" data-source-ref="dataSource"
users-by-username-query=
"SELECT username, password, true as enabled
FROM MEMBER
WHERE username=?"
authorities-by-username-query=
"SELECT member.username, role.role as authorities
FROM ROLE role, MEMBER member
WHERE role.member_id=member.id and member.username=?"/>
<!-- <user-service>
<user name="admin" password="password" authorities="ROLE_ADMIN,ROLE_USER"/>
<user name="user" password="password" authorities="ROLE_USER"/>
</user-service> -->
</authentication-provider>
</authentication-manager>
</beans:beans>
As I understand, the @Component annotation indicates that this class is eligible to be a Spring bean when context:component-scan runs. The @ManagedResource annotation indicates that the bean can be exported as a JMX MBean. It's objectName attribute is optional, but can be used to specify a specific name for the MBean. Please change your @ManagedResource as follows
@ManagedResource(objectName="com.pramati.jmx:name=simplecalculator",
description="Calculator performing basic arithmetic on integers")
We are just giving the name for the Mbean.In this case it will be exposed under the 'com.pramati.jmx' directory with the name 'simplecalculator'.
Add this line and check
<context:mbean-export/>
You can add the logging options to debug
@ManagedResource(objectName="com.pramati.jmx:name=simplecalculator", description="Calculator performing basic arithmetic on integers", log=true,
logFile="jmx.log")