Of course, when it’s so funny (burst the web 2/3.0 bubble):
I have been happily surprised by htmlunit. Actually, for a personal project, rewriting a rails app to Seam I tried to find a replacement of excellent Ruby library hpricot. I needed to perform Xpath expression on a HTML DOM tree to retrieve nodes.Well, htmlunit combined with Neko html parser and jaxen Xpath excels at just doing that. Htmlunit is also used by Canoo web testing .Here’s a code snippet to retrieve all USA states on Yahoo Weather :
Ok maybe htmlunit could reduce its dependencies and use Xpath support added to Java 5 (via Jaxp 1.3). But that’s what i like about Java plateform: there’s virtually a library for every need. And with (more or less) recent additions to the language: Generics, autoboxing, enums, DSL like code constructions (Fluent Interfaces) and future additions like closures, there are less and less reasons to use dynamically typed languages (even if i like Groovy).
Here are my top 10 blogs over the last 30 days but my 2007 blogs ranking shouldn’t be far from it. Stats are generated by Google Reader’s trend page:
|Subscription||# Read||% Read|
|InfoQ Personalized Fe||61||50%|
|Vinny Carpenter’s blo||18||46%|
|“a19s” via dgirard||13||100%|
|Nati Shalom’s Blog||8||80%|
|Peter Pilgrim’s Weblo||7||100%|
Here’s a quick review of jBPM and some issues I experimented on a recent project.jBPM features:
- A bare workflow engine focused on persistence of a business process.
- Graph oriented programming with different kinds of nodes (wait,action,decision, tasks,etc.) . The graph is represented in XML format following the Jboss Process Definition Language format.
- Persistence handled by Hibernate.
- An eclipse plugin to visually design the Business Process and generate the jPDLsource file. It can also generate a web form to enable user interactions with the Business Process (task nodes).
- BPEL support and integration with Jboss ESB.
- A web console with JSF components that allows to find process instances, timers, execute tasks and deploy jBPDL processes.
The main drawbacks with jBPM are:
- jBPM does not provide any connectors for wait nodes (incoming events) or action nodes (interaction with external systems). You have to code them and use jBPM API for signalling a process instance that it should proceed execution. Also by default, a signal operation on a process instance is synchronous and blocks until it finds a wait node or any node with async attribute set to true .
- the Business Process can not be published as a web service. You can pass data to the buisness process storing variable in its execution context with the jBPM API.
- No “business transaction” support.
- Documentation is not really up-to-date and be prepared to spend time on the wiki and the forums For instance we experienced the following issues:
- We didn’t use the jBPM console and we spent some time trying to figure out how to start jBPM timers. Well, a JobScheduler had to be started behind the scene .
- We had troubles with transaction management and integration with JTA transactions. This one was not jBPM’s fault but we spent some time on it. jBPM JobScheduleService delete persisted timers when the business process ends. It does this before the commit of the transaction by registering a JTA’s Synchronization instance on the current JTA Transaction. Our jBPM Hibernate session was also handled by Spring and also registered a Synchronization instance that closed the Hibernate session before commit. Of course, it closed session before the JobScheduler and made the JobScheduler fail to delete timers. As a workaround, we had to use raw Hibernate SessionFactory to prevent this (it avoided Spring ‘s beforeCommit session closing):
and setting the following property of the LocalSessionFactoryBean:
Also, we used the Spring jBPM module since our jBPM actions, decision handlers were implemented as Spring beans. Spring module offers workflow deployments features but we found little value in Spring modules since it’s quite easy to extend jBPM to look for Spring beans in a Spring context. The jBPM Spring module does not seem to be maintained anymore.So, jBPM is really a bare workflow engine and we hope it will offer tigher integration with Jboss ESB for connection with external systems and also more advanced features.Seam offers integration with jBPM : you can register a jBPM process definition as a Seam component, and let Seam deploy it. Seam also provides some anotations to interact with a business process to share data (bijection) with it or start it in a Seam conversation. Seam’s adoption will probably boost jBPM’s usage, well at least i am looking forward to it.
That’s it Seam 2.o has just been released.I am still not sure about Redhat commitment in Jboss products but i hope Seam 2.0 will be a big success since it leverages JavaEE 5 standards (ejb3, Jsf) and Jboss projects (jBPM, drools).
Some frameworks like Seam use the @Logger annotation to instantiate a logger. Seam discovers at deployment annotated classes (see the Scanner class for instance).You could mimic this behaviour with Spring and its AOP capabilities on Spring beans with the <aop:aspectj-autoproxy/> feature.But if you don’t want to bootstrap your application with an IOC container or a framework, there’s still AspectJ AOP to the rescue.For the example, let’s create the Logger marker annotation (AspectJ requires the target retention to be set to RUNTIME).
Now in any class of your application, create a Logger (to make it short we’ll use the commons-logging API and its org.apache.commons.logging.Log interface).Example:
Then the aspect with Aspectj annotated feature and a bunch of reflection to instantiate the logger appropriately (it only invokes the LogFactory and sets the proper class name).
The key here is the pointcut definition with a @Before advice and the get pointcut which intercepts accesses to every field annotated with @Logger annotations from a base package and its descendents.To build with maven, bind the maven’s aspectj plugin compile goal to your compile phase:
Note that the aspect could be packaged in a dedicated library and woven to your classes (see aspects libraries) for usage example.
=> Ok this example is only for demonstrative purpose and adds the overhead of reflection on every access to common’s logging Log implementation getters !So it might not be a good idea after all due to performance penalty. But it’s just a starting point for other annotations with aspects ideas to build your own framework.
I gave RedHat Developer Studio (a.k.a Jboss tools) a quick try and it seems quite promising. I set it up on a brand new Eclipse Europa using the nightly buildsIt integrates Exadel Studio for Jsf development, and plugins to develop with your favorite Jboss Enterprise Middleware System tools and frameworks (hibernate, jbpm , jboss rules, jboss tree and aop cache,Jboss WS (jsr-181)) and off course the brand new Seam. It will offer a complete enterprise grade and open source middleware stack with a nice ide.I am really looking forward to the final release.
Here are some screenshots:
- Hibernate’s perspective (using a Jpa persistance unit):
Since it can be tricky, here’s how Ant’s regexp task can be used in a maven pom file:
I recently discovered Spring’s ability to declare beans that are script-based. This feature can be used to mock business interfaces with Groovy implementations. In a JavaEE container where startup and redeployment can take a while, it can be very useful, in pre-integration tests, to change the behaviour of your business services especially without redeploying the whole EAR or restarting the server.Here’s an example declaration:
The “defaultRefreshCheckDelay” parameter sets the delay in seconds between checks for modifications of the script. and the groovy script:
I see many benefits in this solution:
- hot-swapping implementations without redeployment.
- returned objects can be dynamically generated. For instance if you want to return objects depending only one a given parameter it can be done easily.
- more concise than XML (see xmlstubs a XML based mocking solution).
On a side note, groovy requires ASM 2.2.2 library so if you use hibernate use the cglib with no dependency library which includes asm classes in renamed packages. Also use Spring 2.0.3+ if you use AspectJ pointcut declarations or you can expect errors.With maven profiles it ‘s easy to build a mock and non-mocked service layer of an EAR.Note that you can still inject the real implementations if you want to delegate work to it.
On an other side note, I like both Groovy and JRuby but now tend to prefer Groovy because it leverages my knowledge of Java API. With Ruby i spend too much time finding the reference web site how to achieve things that i do almost naturally in Java. OTH, Ruby has its core API use closures. Closures are tightly integrated and tend to favor loose coupling.
I uploaded on Google code hosting an example of Webservices with Xfire (1.2.1) and Jibx (1.1) built with Maven2. Services are defined and accessed through a Spring application context.Have a look if you are interested in such a solution. The built server war file is for Weblogic server 8.1 but you should be able to run it in any servlet engine (>2.3).
Where does Xfire and Jibx combination shine ?
- When you need to adapt XML schemas to your Java model. Let’s say your client provides you the XML schemas that define the contract of your Webservice and you need to adapt them to your buisness interfaces. Generally, business facades are not exposed directly as Webservices and an adapter layer is coded on top of it. The goal of the adapter layer is to transform simple types (arrays, primitive types, simplified objects) to more complex ones (the ones of your business interface). Here with Jibx you can code transformation directly in the mapping file. The WSDL is still dynamically generated. This “design by contract” approach could also be used.
- Performance. Jibx is supposed to be efficient since it uses a stax XML parser to perform unmarshalling and instantiate your Java objects. But unfortunately I didn’t run any benchmark to confirm this and compare Jibx XML binding with other binding libraries (JAXB 2, XMLBeans, Castor, etc.)