Results 1 to 7 of 7

Thread: how to use persistent MBeans

  1. #1
    Join Date
    Dec 2005
    Location
    California
    Posts
    63

    Default how to use persistent MBeans

    Hi
    I added the sample JMX-enabled class from the Spring pdf and when I run it on Tomcat 5, the MBean shows up in JConsole all right. However, the persistent behavior of the MBean does not work. How do I test MBean persistence?
    Here is my annotated class:

    @ManagedResource(objectName = "bean:name=testBean4", description = "My Managed Bean",
    log = true, logFile = "c:/temp/jmx.log", currencyTimeLimit = 15, persistPolicy = "OnUpdate",
    persistPeriod = 200, persistLocation = "c:/temp/foo", persistName = "bar")
    public class AnnotationTestBean

    Thanks.
    Janos

  2. #2
    Join Date
    May 2005
    Location
    London, UK
    Posts
    11

    Default JMX Persistence

    This is similar to another post "java 5 persist attribute" on this forum. The answer given on that post was that the JMX agent in the Java 5 runtime doesn't support this advanced feature.

    I've been doing a bit of research myself into this topic, because it would be so much more useful for JMX attribute modifications to survive application restarts. It would also be useful to be able to change an attribute for all the servers in a load-balanced cluster.

    Rather than use the standard JMX persistence and cluster transparency features (which don't seem to work, as you noticed, and also they use a flat file and I quite wanted to use a database), I've written a class which extends MBeanExporter, adding persistence (and optionally cluster-transparency). It does this by creating a Sping AOP proxy for each MBean, which writes attributes to a database (provided in a "dataSource" property of the exporter). It registers the proxy instead of the MBean, and also reads in the saved values after a restart. Just use this class instead of MBeanExporter, and all your JMX properties will be persistent.

    The cluster-transparency uses a "broadcaster" class which is supposed to spread method calls around using a UDP broadcast, but I haven't actually tested it yet so it probably doesn't work.
    Attached Files Attached Files

  3. #3
    Join Date
    Dec 2005
    Location
    California
    Posts
    63

    Default Persistent MBeans

    I looked at your code, it is a quite reasonable solution.
    I looked at the unit tests in the
    Code:
    org.springframework.jmx.export.assembler
    package and of course only the correctness of the model mbean descriptors is tested....
    Janos

  4. #4

    Default

    Did u find any better solution to this?

    is there anyway to Persist the Values using SPRING itself in the BEAN DEFINITION xmls?

  5. #5
    Join Date
    Apr 2008
    Posts
    3

    Default

    I also have this problem.
    Is there SPRING solution for this?

  6. #6

  7. #7
    Join Date
    Aug 2006
    Posts
    129

    Default spring solution :

    i used Preferences to store those properties

    Code:
    <aop:config proxy-target-class="true">
    		<aop:pointcut id="jmx.export.attribute" expression="execution(* set*(java.lang.String)) and @annotation(org.springframework.jmx.export.annotation.ManagedAttribute)"/>
    		<aop:advisor advice-ref="jmx.prefs.advice" pointcut-ref="jmx.export.attribute"/>
    	</aop:config>
    
    	<bean id="jmx.prefs.advice" class="wims.cycle.prefs.PreferencesPersisterAdvice"
    		p:userTreePath="wims.cycle"
    	/>
    with an AfterReturningAdvice


    Code:
    public class PreferencesPersisterAdvice implements AfterReturningAdvice{
    
    	private String userTreePath;
    	private Preferences userPrefs;
    
    	Log logger = LogFactory.getLog(getClass());
    	
    	public void afterReturning(Object returnValue, Method method,
    			Object[] args, Object target) throws Throwable {
    		logger.info(method);
    		try{
    			userPrefs.node(pathName(target)).put(key(method), value(args));
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
    	
    	public void setUserTreePath(String userTreePath) {
    		this.userTreePath = userTreePath;
    	}
    	
    	String pathName(Object target){
    		return target.getClass().getName();
    	}
    	
    	String key(Method method){
    		return StringUtils.uncapitalize(StringUtils.delete(method.getName(), "set"));
    	}
    	
    	String value(Object[] args){
    		if(args !=null && args.length==1 && args[0]!= null)
    			return args[0].toString();
    		throw new IllegalArgumentException();
    	}
    	
    	@PostConstruct
    	void postConstruct(){
    		this.userPrefs = (this.userTreePath != null) ?
    			    Preferences.userRoot().node(this.userTreePath) : Preferences.userRoot();   
    	}
    now how to read them back is already provided in Spring :


    Code:
    <bean id="prefs.config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"
         	p:userTreePath="wims.cycle" p:properties-ref="prefs.props"
         />
         
         <util:properties id="prefs.props">
         	<prop key="wims.cycle.rss.RssReader/sourceAddress">http://newsrss.bbc.co.uk/rss/sportonline_world_edition/other_sports/cycling/rss.xml</prop>
         </util:properties>
    convention between configurer and advice is to use the full class name as node
    Last edited by wims.tijd; Jun 2nd, 2009 at 08:54 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •