Tuesday, October 17, 2006

Remoting semantics of Spring slightly changed

Time passes too quickly, already a month passed since my last blog entry :-(.
We slightly adapted the remoting semantics of Spring. Here's a picture that shows how it works:


In the picture there are 2 JVMs: one has the client and one has the server role. We show the spring application context of each JVM. The rectangles with rounded corners are spring beans (Java objects created by Spring). The normal rectangles are normal Java objects. Arrows are normal Java references. Spring beans with a dashed ring around have an auto proxy (so you could e.g. add interceptors to them).
In the server JVM, to publish POJOs via a remoting protocol, you define an exporter spring bean (this requires no code, only a short Spring configuration). This exporter bean references another spring bean that represents the protocol (this protocol bean fully configures what protocol to use and settings for the protocol). By changing settings on the protocol spring bean, you can fully control how all the linked exporter beans are exported.
In the client JVM, to get access to a remotely published POJO (either via Spring or other remoting), you just define an importer spring bean. This importer spring bean can be accessed like any other spring bean. We tend to share the protocol configuration between the client and the server JVM.

For simpler testing, one could even deploy the spring beans of the client and those of the server in one JVM (omitting the importer and exporter).

Why did we change the semantics of the Spring remoting?
  • It's easier to switch remoting protocols. The protocol definition and the fact that we remote is completely orthogonal.
  • You can also remote 2.0/2.1 EJB beans without writing custom delegator classes (as Spring proposes it)
  • You can optionally enable implicit context passing (this is a topic for another blog entry, you may want to check out my article decribing this if you are impatient).
  • It allows for easy set up of load-balancing
The following picture illustrates our load-balancing feature:



The load balancing protocol is a so-called composite protocol. It applies the Composite Design Pattern and thus allows the user to compose several of the atomic protocols (i.e., a non-composite protocol such as RMI) into this composite protocol. To the outside, it behaves like an atomic protocol. Note that the load balancing protocol is only used on the client side of a (remote) invocation and requires no modifications to existing remoting protocols.

The load balancing protocol attempts to establish an initial connection to a particular server. If this connection attempt fails, it will ask for the next server from the policy bean and attempt to connect to this server. It repeats this behavior until it succeeds to connect, or no more servers are available. In the latter case, it throws a ch.elca.el4j.services.remoting.protocol.loadbalancing.NoProtocolAvailableException.

Different policies can be plugged to govern the sequence in which protocol instances are invoked.

Tuesday, September 19, 2006

Pragmatic merging of XML

Sometimes it is useful to be able to merge different XML document into one. For example when a tool accepts only one XML configuration file, but different subprojects that use the tool together would each be able to add some information to the XML configuration file. A concrete example would be the web.xml file of a J2EE servlet container: there can only be one such file per WAR-file. What if you have 2 subprojects that you would like to deploy into one WAR-file?
You could merge the files by hand or you could set up an merging functionality to do it automatically for you. With the little framework I present here, you can easily set up your own XML file merging. The framework is available under the EL4J project (http://EL4J.sf.net) as part of the xml merger module. It was contributed by Laurent Bovet (from outside of the EL4J core team), thanks.

Let's look at a simple example:



The following simple code implements this:

public String merge(String original, String patch) {
Configurer c = new PropertyXPathConfigurer("xpath.1=/root/d \n matcher.1=ID");

return new ConfigurableXmlMerge(c).merge(new String[]{original, patch} );

}


You may ask: what does it mean to merge XML documents? I think it is difficult to find a general answer to this question:
  • Sometimes the second XML file should be able override tags of the first XML file
  • What are the branches that should be merged? Just the same XML tags? Or does some attribute need to be equal?
  • Sometimes some branches of the XML document may need to be left out
Because of this, the XML merger is set up as a framework. You plug in your own definitions of how matching and mappings are done. There are basic merging semantics implemented in the framework. If you need other rules, you can extend the parts that you are interested in.

Please consult the detailed documentation or the samples of the xml merger in case you would like to know more.

Wednesday, September 13, 2006

Getting insights in a running Spring application via JMX

During development it is often practical to be able to get more information about what is going on in a running JVM, e.g.
  • what Spring configuration was loaded (taking into account all the overridden configuration),
  • what threads are running and with what properties,
  • what interceptors are present on what spring beans
The EL4J JMX module allows exactly this. You just add a dependency from your application module to the JMX module and automatically have this and more information available via any web browser.

Here are some screenshots to illustrate this:

First we show the JMX overview page:



Clicking on the fooBean leads to the following view:



Clicking on the Configuration property shows the config values of the bean:




Which corresponds to following spring configuration:


You can also see all the threads that run in the JVM with their attributes:



Additional features:
  • Change the log4j logging level for a certain package during runtime
  • Get the current configuration location of log4j
  • See the measurements from the JaMON performance measuring interceptor
  • Activate log4j appenders during runtime (e.g. to get more info in case of problems)
  • See all system properties defined in the JVM (e.g. to get the current CLASSPATH)
  • Get the order of the configuration files as Spring reads them
All this is available with just the addition of a reference to the JMX module. Remark: to make the spring configuration available to JMX, it is required to use a subclass of the normal XMLApplicationContext.

Wednesday, August 16, 2006

Modules in the open-source EL4J framework

EL4J is to a large extent a collection of existing J2EE frameworks. Spring is the most important of the contained frameworks.

One interesting feature of EL4J are modules. They allow to split an application in smaller pieces. EL4J itself also uses modules to split its features in more handy chunks. A module is similar to an eclipse plugin or to a maven project (in fact, an EL4J module is both mapped to an eclipse plugin and a maven module).

A module in EL4J contains (1) code, (2) predefined configuration and (3) dependencies. You can make dependencies on other modules or on jar files. When a module m1 uses another module m2, the module m1 has acces to all the content (code, config and dependencies) of module m2. This works transitively, i.e. if m2 depends on a module m3, m1 has also access to m2.

Sample use: Adding simple performance tracking
Why are modules useful? Let's assume you have an application with the module app. If you want to setup the performance interceptor to automatically time the duration of all calls to certain spring beans, you just make a dependency from your application to the module "light-statistics". From then on, you can access performance information via JMX.
Under the hood, the module light-statistics sets up the JAMON performance interceptor, adds it by default to all spring beans (you can override this) and makes the information available in JMX. No need to configure anything or know more about the working of the module light statistics. By default, all is setup for you.
In case you are not happy with the default, you can change anything. But simple things are simple to set up.

Here's a sample setup of modules:
















In your applications, you make a dependency on all EL4J modules you need (above the module YourApplication needs the modules Security and WebTools. In this way, you automatically setup the things that are tedious to set up: jar-dependencies and the default configuration.

Are you afraid that EL4J loads configuration "magically"? You don't have to use this feature, we just recommend it for simplicity. For your application context, you specify the place from where configuration should be loaded from (as always in spring). By convention, we put configuration we recommend to always use for a given module in a directory called mandatory. The location we recommend to add to the list of locations to load configurations from is "classpath*:mandatory/*.xml". Spring then includes all the default configuration automatically. You also have the possibility to exclude a location in case you do not need it.

Monday, August 14, 2006

We need a well-integrated set of best-of-breed tools for J2EE development

For simple, non-heterogeneous environments, IT-analysts often recommend using the .NET framework as development platform, rather than the J2EE. They say that .NET is simpler and more productive.
This bugs me, because I prefer the Java platform and because I favor the more open community around the J2EE. Great innovation occurs in the J2EE open source world. We also have the better IDEs.

However, when I recommend how to use the J2EE myself, I enumerate many different tools (just to name a few: Spring, Hibernate or Ibatis, Axis, Maven, Ant, JUnit, Log4j, Acegi), from different sources. It is often far from obvious what frameworks one should choose, there are just too many out there (consider e.g. the web framework domain). The integration of these frameworks is also done anew too many times.

EL4J, the open-source project I work on, has the goal to improve this situation. It combines leading J2EE tools, provides sample applications and adds some features of its own. It was already used in 16 projects so far. http://EL4J.sf.net

How do you estimate the situation in the J2EE development world?