ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Archive for August, 2009

Groovy, JMX and MBeans

Posted by ice09 on August 31, 2009

It’s really easy to create a MBean, export it with the platform MBean server and access the bean with Groovy.
Here’s how (it’s more or less an extended rewrite of this post).

The main trick is to implement ApplicationContextAware, which let Spring call the setApplicationContext method with the prepared application context (not tried, could be even shorter: is autowiring with the type “ApplicationContext” possible as well?)

Java part

The ManagementFactory lets you register your MBean in the platform MBean server (used to serve the application context).
Important: The easiest way to access the MBean remotely is by providing -Dcom.sun.management.jmxremote.port=6666 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false as System parameters (VM arguments in Eclipse) – obviously, this is not very secure.

package com.commons.blog;

import java.lang.management.ManagementFactory;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AppCtxGlobalExporter implements AppCtxGlobalExporterMBean, ApplicationContextAware {

	private ApplicationContext appCtx;
	
    public AppCtxGlobalExporter() {}

	public void setApplicationContext(ApplicationContext appCtx) throws BeansException {
		this.appCtx = appCtx;
    	initMBeanServer();
	}

	private void initMBeanServer() {
		try {
			ManagementFactory.getPlatformMBeanServer().
				registerMBean(this, new ObjectName("jmxsample:type=AppCtxGlobalMBeanExporter"));
		} catch (InstanceAlreadyExistsException e) {
            Logger.getLogger(AppCtxGlobalExporter.class.getName()).log(Level.SEVERE, null, e);
		} catch (MBeanRegistrationException e) {
            Logger.getLogger(AppCtxGlobalExporter.class.getName()).log(Level.SEVERE, null, e);
		} catch (NotCompliantMBeanException e) {
            Logger.getLogger(AppCtxGlobalExporter.class.getName()).log(Level.SEVERE, null, e);
		} catch (MalformedObjectNameException e) {
            Logger.getLogger(AppCtxGlobalExporter.class.getName()).log(Level.SEVERE, null, e);
		} catch (NullPointerException e) {
            Logger.getLogger(AppCtxGlobalExporter.class.getName()).log(Level.SEVERE, null, e);
		}
	}

    public String[] getBeanNames() {
    	return appCtx.getBeanDefinitionNames();
    }

}

with the interface:

package com.commons.blog;

public interface AppCtxGlobalExporterMBean {
	
    String[] getBeanNames();

}

Here the main class:

package com.commons.blog;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppCtxRegistry {
	
	public static void main(String[] args) {
		ApplicationContext app = new ClassPathXmlApplicationContext("beans.xml");
		SampleBean sample = (SampleBean) app.getBean("sample");
		System.out.println(sample);
		while(true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

the sample bean is left out, it’s not important and could even be empty.
The important part is the applicationContext.xml, the bean which implements ApplicationContextAware must just be instantiated, the Method setApplicationContext is called with the appropriate appcontext on startup.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
   "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
  <bean class="com.commons.blog.AppCtxGlobalExporter"/>

  <bean id="sample" class="com.commons.blog.SampleBean"/>
</beans>

Now comes the fun (Groovy!) part:

import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXServiceURL as JmxUrl

class JmxClient {

    def jmx() {
        def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:6666/jmxrmi'
        def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection
        def mbean = new GroovyMBean(server, "jmxsample:type=AppCtxGlobalMBeanExporter")
       	mbean.BeanNames.each {
        	println it
        }
    }

    public static void main(String[] args) {
        new JmxClient().jmx()
    }

}

Posted in Groovy | Leave a Comment »

Scala on stage with receiving and reacting Actors

Posted by ice09 on August 16, 2009

Being quite a fan of Groovy (which also is related to Spring in some way), I nevertheless experimented with Scala a bit.
Trying not to follow the current hype about this language, I mainly wanted to check a higher-level (meaning higher than Java), typed language and like Scala, even though to me there seems to be too much magic in it to overcome the non-dynamic aspect (this might not be formally correct, but hopefully understandable).

Due to this non-dynamic aspect, many things which are highly praised in Scala seem clumsy compared to Groovy. Just compare the granted-better-than-Java XML-handling in Scala with the even-much-better XML-handling in Groovy.
Of course, my IDE will never be able to code complete the Groovy variant – however, currently, the Scala Eclipse Plugin does it neither.

So, I bought the book “Programming in Scala”, which is good, but there are certain parts which are not too well described, one being the difference between “receive” and “react”.
I did it understand only after trying out myself (see below) and reading this post.
Once again, stackoverflow.com has been very useful to me (I just know the site for about 2-3 months and found useful information there several times).

So, I wanted to try if I can validate the different behaviour (which is in short that receive blocks a Thread and react returns immediately and is not bound to a particular Thread – but there are better explanations out there).

Preparation

I wanted to check the behaviour by forcing Scala to instantiate just one thread in the thread pool. This can be done by setting two system properties:

-Dactors.maxPoolSize=1
-Dactors.corePoolSize=1

this can be concluded by the Actors sources.

Running

I used two different objects:

import scala.actors._
import scala.actors.Actor._

object Reactor extends Actor {
	
	def act() {
		while(true) {
			receive {
				case (x: String, actor: Actor) => println("received:" + x)
				actor ! (x, self)
			}
		}
	}
}

and the Runner:

import scala.actors._
import scala.actors.Actor._

object Runner extends Actor {

	def act() {
		while(true) {
			receive {
				case (string: String, actor: Actor) => 
					println("got: " + string)
					actor ! ("hello", self)
			}
		}
	}
	
	
	def main(args : Array[String]) : Unit = {
			Runner.start()
			Reactor.start()
			Reactor ! ("hello", Runner)
	}	
  
}

Starting the application with this parameters just freezes it immediately. We need at least a threadpool of two threads. With these two threads, the application starts and the result with visualvm is like this:

Switching while(true) to loop and receive to react results in one sharing thread, which means the size can be max=1, core=1 and the application runs like this:

Which look like it should – the react does not block the thread, therefore one “shared” thread is enough – the react of each actor is then “attached” to the main thread.

Posted in Scala | Leave a Comment »

Spring and Groovy, again…

Posted by ice09 on August 9, 2009

No real news here, just another example for Spring and Groovy in a simple web project.

Github for server version is here.
Github for client version is here.

What does it do?

We needed a simple Request/Response Mock for SOAP Web Services. Since the real sending component uses EJB and Weblogic t3-protocol specific stuff, I wanted to decorate this component.
The simplest way seemed to create an own endpoint, which accepts the SOAP web service requests, searches for templates based on the payload-root-element and evaluates the determined template (which itself is a Groovy template).

How does it work?

Quite straightforward. If a directory with the file template.groovy and the name of the root element of the payload exists, the template is loaded and evaluated with the input data and finally returned by the DispatcherServlet.
Spring MVC is used, however it was not necessary for this little sample.
The most interesting part is the injection (with @Autowired) of the Groovy script (which resides in src/main/resources/, which is not really correct).

<!-- this is really important to start the annotation processing in Spring -->
<context:annotation-config/>

<!-- the controller is instantiated, via @Autowired the Groovy Script is set -->
<bean id="RequestMockController" class="com.mock.sample.RequestMockController"/>

<!-- local repository (must be changed most likely) -->
<bean id="localRepo" class="java.lang.String">
   <constructor-arg value="c:/temp/repo/"/>
</bean>

<!-- instantiate Groovy as a Spring bean -->
<lang:groovy id="xml" script-source="classpath:XmlToolImpl.groovy"/>

IMPORTANT: to be able to use Groovy-Spring beans, the Groovy object should implement a Java interface (which is then used in the Java code).

How do I test it?

Use the client code with the parameters supplied in the README.
The request could look like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wss="http://wsssample.com.mock.sample">
  <soapenv:Header/>
    <soapenv:Body>
      <wss:getString>
        <wss:name>?</wss:name>
      </wss:gettring>
   </soapenv:Body>
</soapenv:Envelope>

For this request to succeed, the file REPO/getString/template.groovy must exist (see resources).

Specials

In the sample, there is one special behaviour, which requires two passes – if the template returns something like “>redirect”, the request is redirected to the new file (this works one time only and is just included to easy the “dispatching or controller pattern”)

Posted in Groovy, Maven | 1 Comment »