Archive for the ‘Software Architecture and Design’ Category

Notes on the Spring-WS tutorial

September 26, 2009

Today I have reviewed a proof of concept I have done in order to decide which Web Services framework matches the requirements of a bioinformatics project. Because of forgetting to store a file in the versioning system, I had to review the whole tutorial and to look for the file within the Spring tutorial. What is interesting, until now nobody published the full content of the Spring-WS tutorial.

So, here is my pom.xml. I am using Apache Maven2 in order to strictly enforce the versions of the JAR files. Nobody is constrained to use Maven, but without it, it would be very difficult to sort out the transient dependencies.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi=""
 <name>holidayService Spring-WS Application</name>
 <dependency> <!-- required by AbstractJDomPayloadEndpoint -->

I am using the jetty plugin in order to be able to run the application right from the command line; xalan dependency is required in order to avoid the exception “java.lang.IllegalStateException: Could not find SAAJ on the classpath” thrown by Spring-WS, corrected in a newer version of xalan.

Also according to the tutorial, the file spring-ws-servlet.xml, a regular Spring context file, describes the external interface of the Web Service and the associated Java classes. This file has to be placed in the src/main/webapp/WEB-INF directory.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""

 <bean id="holidayEndpoint" class="">

 <bean class="">
 <property name="mappings">
 <prop key="{}HolidayRequest">holidayEndpoint</prop>
 <property name="interceptors">
 <bean class="" />

 <bean id="holiday" class="">
 <property name="builder">
 <bean class="">
 <property name="schema" value="/WEB-INF/hr.xsd" />
 <property name="portTypeName" value="HumanResource" />
 <property name="locationUri" value="http://localhost:8080/holidayService/" />


And here is the implementation of According to Maven customaries, this have to be placed in the src/main/java subdirectory of the project. I have tried to keep the implementation minimal by avoiding further service instantiations, unrelated to Spring-WS:


import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.xpath.XPath;

public class HolidayEndpoint extends AbstractJDomPayloadEndpoint {

 private XPath startDateExpression;

 private XPath endDateExpression;

 private XPath nameExpression;

 public HolidayEndpoint() throws JDOMException {
 Namespace namespace = Namespace.getNamespace("hr", "");
 startDateExpression = XPath.newInstance("//hr:StartDate");
 endDateExpression = XPath.newInstance("//hr:EndDate");
 nameExpression = XPath.newInstance("concat(//hr:FirstName,' ',//hr:LastName)");

 protected Element invokeInternal(Element holidayRequest) throws Exception {
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 Date startDate = dateFormat.parse(startDateExpression.valueOf(holidayRequest));
 Date endDate = dateFormat.parse(endDateExpression.valueOf(holidayRequest));
 String name = nameExpression.valueOf(holidayRequest);

 // do something meaningful with the extracted data.
 System.out.println("Start date: "+startDate+" end Date: "+ endDate+" Employee: "+name);
 return null;

My final file structure is:

|-- pom.xml
`-- src
 `-- main
   |-- java
   |   `-- com
   |       `-- razvan
   |           `-- hr
   |               `-- ws
   |                   `--
   `-- webapp
     `-- WEB-INF
        |-- hr.xsd
        |-- spring-ws-servlet.xml
        `-- web.xml

The web.xml is pretty standard for Spring applications:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="" xmlns:xsi=""

 <display-name>Spring test application</display-name>




This is the whole Web Service application. In order to run the application try from the command line:

mvn clean install jetty:run

This will compile the war file and start an instance of the jetty web server.

By accessing the address: http://localhost:8080/holidayService/holiday.wsdl you can see the generated WSDL associated to your described web service. While leaving the jetty running, you may attempt to create a client, in order to see the message printed within the invokeInternal method. Following it will be described a Java client, but it is possible to build your client using any other language or platform.

Using the Eclipse wizard create a new empty Java project, than create using the wizard a new “Web Service Client”. Provide the address of the wsdl and you will have a bunch of Java classes describing your web service and the required XML parsers dependencies in your newly created project. Create a new main class in the default package named, with the following content:

import java.math.BigInteger;
import java.util.Date;


public class TestWs {
 public static void main(String[] args) {
 try {
 HumanResourceServiceLocator loc = new HumanResourceServiceLocator();
 HumanResource myserv = loc.getHumanResourcePort();

 HolidayType ht = new HolidayType(new Date(), new Date());
 EmployeeType et = new EmployeeType(new BigInteger("100"), "Razvan",
 HolidayRequest req = new HolidayRequest(ht, et);;
 } catch (Exception e) {


Run the class, and you will be able to observe the message in the maven window.

A few conclusions of the test are:

– Spring-WS is a great approach if the schema definitions of the data model already exists.

– The required xalan dependency is a bug in Spring-WS dependency requirements, fortunately Maven made possible the correction.

– The element wsdl:definitions is optional, the tutorial worked without it as well.

Apache Maven

May 24, 2009

I am using Apache Maven 2 to build the most projects i am involved in. It keeps the project minimal, by the concise description of the dependencies through the transient dependency mechanism and it stores the dependent JAR files separately of the project. It integrates nicely with Eclipse (by creating Eclipse projects) and promises an easy way to get night builds and to separate the sources in a team; for security reasons I don’t want all the members of the team to have all the source code of the application.

I foresee an application of Maven dependency resolution in BeanShell. It will be greatly to have a function like Maven.resolveDependency(String groupid, String artifactid,[String version]). This will make use of the local Maven cache or it will connect to the configured maven repositories and it will download the JAR file together with its dependencies. What a great way to use “dependency rich” modules like Apache Fop in short and self containing BeanShell scripts.

On the other hand, daily use of Maven is far away from idyllic. What annoys a lot are the permanent changes that invalidate the previous configurations. Yesterday I have to build a Web Start application for my employer’s Java Swing software application. Of course, I perceived it as a rather routine task, even with special requirement to obfuscate as much as possible of the source code, except of course of the parts being introspected by the various XML parsers or serializers.

First, I have realized that obfuscation is not possible for multiple projects, except if they are united together. The assembly:assembly plug-in was stubborn enough to include the current directory even if I explicitly forbade it. It also created the nice “c:” entry in the JAR file. Fortunately the entry was not recursive, else I would have ended with my whole C drive in the output file. Help came from the FreeHEP plug-in, their implementation shown efficiency and coherence.

Second, finding an obfuscator is not a trivial job. After some tests, yguard shown the best results.

Third, building the Web Start application itself. Some nice guy renamed the group ID of the package from org.codehaus.mojo” to org.codehaus.mojo.webstart”, so basically I have wondered for a few hours why is my configuration not working, why some settings are simply ignored. I figured it out after I have downloaded the sources of the plug-in and tied to debug it. The task of the plug-in is not trivial, it needs to sign all the dependent JAR file involved in the project and to build the JNLP file. Until now I had my own JNLP template, containing a $dependencies macro to avoid listing the dependencies manually. The file was now simply ignored as I moved to the new plugin and I had to spend a lot of time to fix the configuration. The reason I moved to the new plugin was simple: I needed a way to resign already signed JARs and the new plugin seamed to be the only solution.

Other thoughts about Maven: it is full of unexpected issues, such as, lastly:

[INFO] Internal error in the plugin manager executing goal ‘org.apache.maven.plu gins:maven-antrun-plugin:1.1:run’: Unable to find the mojo ‘org.apache.maven.plugins:maven-antrun-plugin:1.1:run’ in the plugin ‘org.apache.maven.plugins:maven- antrun-plugin’
Component descriptor cannot be found in the component repository: org.apache.maven.plugin.Mojoorg.apache.maven.plugins:maven-antrun-plugin:1.1:run.

Well, the plugin was there, it has even worked previously when running the sibling project. The error occured when compiling the parent project. After some efforts to understand the issue I found a forum, here somebody indicate that placing the plug-in in the  pluginManagement” section of the parent project will overcome the issue. This has worked, but I am still frustrated by not having an answer on the question “why?”.

Another point is the AndroMDA code generator. The generator is implemented through a Maven plugin. In winter I have spend some effort to write an educational software consisting in multiple choiche questions. The software was EJB3 based, all entity beans were described in an UML model. The code generator produced all needed beans, with annotations, cascading rules and database configuration file. The problem now is that the generator was as a Snapshot, and now the same version is not working anymore. [error here].

So, what is the future of Apache Maven? Here is my vision:

  • GUI: it should be possible to configure the project and each single plugin through an user interface. It does not need to be fancy but it should be just effective, see ArgoUML. Editing text XML in 21st century is outrageos.
  • Custom project phases. The predefined build / clean / site lists of phases are insufficient for complex projects.
  • Multiple target types. What if the user needs to have multiple JAR versions of the same project, such as “Java 1.5” or “Java 1.6” Runtime? Again hardcoding the possible targets as: sources/javadoc/jar is a private club solution.
  • Multiple languages. C/C++/.NET, even if the project flow is orchestrated by the Java engine.
  • Pipelines. It is nice to have a declarative syntax, but some steps have to be procedural. Currently I think I abuse the Ant plugin and/or the “executions” feature of the plugins, to achieve some kind of procedural steps. Forking should be also allowed, as it can greatly increase the build performance, especially on multiprocessor/multicore machines.
  • Atomicity. Each goal of the plugins has to be atomic. Goals like “discover the Philosopher’s Stone, compile the project and interpret Beethoven’s 9th symphony” should be clearly split in their atomic constituents.
  • Easiness of plug-in development. Writing a plug-in should be easy, ant-like. Also the license should allow, if not yet doing it, proprietary code. Also, the parameters of a plug-in should be self-describing, so that the user interface will be able to present the choiches properly. There should be a plugin test framework, to facilitate quality assurance.

The future of MDA

April 15, 2009

I have discovered MDA, through the AndroMDA project, about 4 years ago. The idea of automatically generating some repeated patterns, the amaizing power of generating a database structure, Entity Beans or Hibernate linkage files by only providing an UML diagram model, the capability of keeping a minimal description (the UML document) have all convinced me not only to learn how AndroMDA works, but also to start using it in production.

As for today, I have used AndroMDA in at least 6 distinct projects. I didn’t use the clasical path shown by AndroMDA. I have chosen atomic Maven projects either 100% UML generated or 100% manual. No file was manually changed after generation, this pattern proved to be desastruous in practice.

I am wondering what is the today future of the MDA. As I was warning 5 month ago a developer of ArgoUML about a minor issue, they exclamated “wow, you are still using AndroMDA!”. So what is the next MDA product? Any answers from the community?

The ZK AJAX Library ignores some of the user’s input

February 1, 2009

I have used ZK for a while, building mostly web administrative interfaces. My applications get usually used in the intranet, they rarely get exposure with the open Internet. The distance between the server and the browser is usually a few routers, so they benefit of an especially low latency and wide bandwidth.

Many users reported that sometimes the application fails to perform the instructed task. From time to time, nothing happens when the user pushes a button or chooses an item from a context menu. Although I have first suspected a programming error, the random distribution of this behavior, in various applications, determined me to suspect the ZK engine of this loss of events.

I have designed a simple test application to check this issue:

<window xmlns="" xmlns:xsi=""
    xmlns:a="" use="Test1"
    id="w1" width="600px" title="Test window">
<button id="b1" label="Increment" onClick="w1.increment()"/>
<separator width="20px"/>
<label id="lbl" value="Not initialized."/>

The corresponding  Java resource is:

import org.zkoss.zul.Label;
import org.zkoss.zul.Window;

public class Test1 extends Window {

	public void onCreate() {

	public void increment() {

	private void setValue(int v) {
		Label l = (Label)getFellow("lbl");

	private int start = 1;

This page simply increments a counter as the button is pressed.

Now, I am going to press the button a lot, to find out how many times the system actually records the button was pressed. The best way to test it is to write a unit test module, based on Selenium test framework. The button is clicked, then the test waits for 350 milliseconds to process the request. After this, the label is pooled for the next 3 seconds to update. If it is not updating to the expected value at the end of the 3 seconds, the iteration is considered an error.

import java.util.Date;
import com.thoughtworks.selenium.SeleneseTestCase;

public class IncrementTestCase extends SeleneseTestCase {
	public void setUp() throws Exception {
		setUp("http://localhost:8080", "*custom /usr/bin/firefox");

	public void tearDown() throws Exception {

	public synchronized void testIncrement() throws Exception {
		int errors = 0;"/testapp/test1.zul");

		int value = 1;
		for (int i = 0; i != 100; i++) {"//td[text()='Increment']");
			Date start = new Date();
			boolean found = false;
			// 3 seconds waiting time
			while (new Date().getTime() - start.getTime() < 3000) {
				String s = selenium.getText("//span[@class='z-label']");
				if (Integer.parseInt(s) == value) {
					found = true;
			if (!found) {
				String s = selenium.getText("//span[@class='z-label']");
				System.out.println("Expected: "+ value + " found " + s);
				value = Integer.parseInt(s);
			System.out.println(new Date().toString() + " Errors: "+ errors + " Loops: " + (i+1));
		System.out.println("Errors: "+ errors);

The following output results after the execution of the test:

Sun Feb 01 14:03:08 EST 2009 Errors: 0 Loops: 1
Sun Feb 01 14:03:09 EST 2009 Errors: 0 Loops: 2
Expected: 4 found 3
Sun Feb 01 14:03:12 EST 2009 Errors: 1 Loops: 3
Sun Feb 01 14:03:12 EST 2009 Errors: 1 Loops: 4
Sun Feb 01 14:03:13 EST 2009 Errors: 1 Loops: 5
Expected: 6 found 5
Sun Feb 01 14:03:16 EST 2009 Errors: 2 Loops: 6
Sun Feb 01 14:03:16 EST 2009 Errors: 2 Loops: 7
Expected: 7 found 6
Sun Feb 01 14:03:19 EST 2009 Errors: 3 Loops: 8
Sun Feb 01 14:03:20 EST 2009 Errors: 3 Loops: 9
Sun Feb 01 14:03:20 EST 2009 Errors: 3 Loops: 10
Expected: 9 found 8
Sun Feb 01 14:03:23 EST 2009 Errors: 4 Loops: 11
Sun Feb 01 14:03:24 EST 2009 Errors: 4 Loops: 12
Sun Feb 01 14:03:24 EST 2009 Errors: 4 Loops: 13
Sun Feb 01 14:03:24 EST 2009 Errors: 4 Loops: 14
Sun Feb 01 14:03:25 EST 2009 Errors: 4 Loops: 15
Expected: 13 found 12
Sun Feb 01 14:03:28 EST 2009 Errors: 5 Loops: 16
Sun Feb 01 14:03:28 EST 2009 Errors: 5 Loops: 17
Expected: 14 found 13
Sun Feb 01 14:03:31 EST 2009 Errors: 6 Loops: 18
Sun Feb 01 14:03:32 EST 2009 Errors: 6 Loops: 19
Expected: 15 found 14
Sun Feb 01 14:03:35 EST 2009 Errors: 7 Loops: 20
Sun Feb 01 14:03:35 EST 2009 Errors: 7 Loops: 21
Sun Feb 01 14:03:35 EST 2009 Errors: 7 Loops: 22
Expected: 17 found 16
Sun Feb 01 14:03:39 EST 2009 Errors: 8 Loops: 23
Sun Feb 01 14:03:39 EST 2009 Errors: 8 Loops: 24
Sun Feb 01 14:03:39 EST 2009 Errors: 8 Loops: 25
Sun Feb 01 14:03:40 EST 2009 Errors: 8 Loops: 26
Sun Feb 01 14:03:40 EST 2009 Errors: 8 Loops: 27
Sun Feb 01 14:03:40 EST 2009 Errors: 8 Loops: 28
Expected: 22 found 21
Sun Feb 01 14:03:44 EST 2009 Errors: 9 Loops: 29
Sun Feb 01 14:03:44 EST 2009 Errors: 9 Loops: 30
Expected: 23 found 22
Sun Feb 01 14:03:47 EST 2009 Errors: 10 Loops: 31
Sun Feb 01 14:03:48 EST 2009 Errors: 10 Loops: 32
Sun Feb 01 14:03:48 EST 2009 Errors: 10 Loops: 33
Expected: 25 found 24
Sun Feb 01 14:03:51 EST 2009 Errors: 11 Loops: 34
Sun Feb 01 14:03:51 EST 2009 Errors: 11 Loops: 35
Sun Feb 01 14:03:52 EST 2009 Errors: 11 Loops: 36
Sun Feb 01 14:03:52 EST 2009 Errors: 11 Loops: 37
Expected: 28 found 27
Sun Feb 01 14:03:55 EST 2009 Errors: 12 Loops: 38
Sun Feb 01 14:03:56 EST 2009 Errors: 12 Loops: 39
Sun Feb 01 14:03:56 EST 2009 Errors: 12 Loops: 40
Expected: 30 found 29
Sun Feb 01 14:03:59 EST 2009 Errors: 13 Loops: 41
Sun Feb 01 14:04:00 EST 2009 Errors: 13 Loops: 42
Sun Feb 01 14:04:00 EST 2009 Errors: 13 Loops: 43
Sun Feb 01 14:04:00 EST 2009 Errors: 13 Loops: 44
Sun Feb 01 14:04:01 EST 2009 Errors: 13 Loops: 45
Sun Feb 01 14:04:01 EST 2009 Errors: 13 Loops: 46
Sun Feb 01 14:04:02 EST 2009 Errors: 13 Loops: 47
Sun Feb 01 14:04:02 EST 2009 Errors: 13 Loops: 48
Expected: 37 found 36
Sun Feb 01 14:04:05 EST 2009 Errors: 14 Loops: 49
Sun Feb 01 14:04:06 EST 2009 Errors: 14 Loops: 50
Expected: 38 found 37
Sun Feb 01 14:04:09 EST 2009 Errors: 15 Loops: 51
Sun Feb 01 14:04:09 EST 2009 Errors: 15 Loops: 52
Sun Feb 01 14:04:09 EST 2009 Errors: 15 Loops: 53
Expected: 40 found 39
Sun Feb 01 14:04:13 EST 2009 Errors: 16 Loops: 54
Sun Feb 01 14:04:13 EST 2009 Errors: 16 Loops: 55
Sun Feb 01 14:04:13 EST 2009 Errors: 16 Loops: 56
Sun Feb 01 14:04:14 EST 2009 Errors: 16 Loops: 57
Sun Feb 01 14:04:14 EST 2009 Errors: 16 Loops: 58
Expected: 44 found 43
Sun Feb 01 14:04:17 EST 2009 Errors: 17 Loops: 59
Sun Feb 01 14:04:18 EST 2009 Errors: 17 Loops: 60
Expected: 45 found 44
Sun Feb 01 14:04:21 EST 2009 Errors: 18 Loops: 61
Sun Feb 01 14:04:21 EST 2009 Errors: 18 Loops: 62
Sun Feb 01 14:04:22 EST 2009 Errors: 18 Loops: 63
Sun Feb 01 14:04:22 EST 2009 Errors: 18 Loops: 64
Expected: 48 found 47
Sun Feb 01 14:04:25 EST 2009 Errors: 19 Loops: 65
Sun Feb 01 14:04:25 EST 2009 Errors: 19 Loops: 66
Sun Feb 01 14:04:26 EST 2009 Errors: 19 Loops: 67
Sun Feb 01 14:04:26 EST 2009 Errors: 19 Loops: 68
Expected: 51 found 50
Sun Feb 01 14:04:29 EST 2009 Errors: 20 Loops: 69
Sun Feb 01 14:04:30 EST 2009 Errors: 20 Loops: 70
Sun Feb 01 14:04:30 EST 2009 Errors: 20 Loops: 71
Sun Feb 01 14:04:31 EST 2009 Errors: 20 Loops: 72
Sun Feb 01 14:04:31 EST 2009 Errors: 20 Loops: 73
Sun Feb 01 14:04:31 EST 2009 Errors: 20 Loops: 74
Sun Feb 01 14:04:32 EST 2009 Errors: 20 Loops: 75
Sun Feb 01 14:04:32 EST 2009 Errors: 20 Loops: 76
Sun Feb 01 14:04:32 EST 2009 Errors: 20 Loops: 77
Sun Feb 01 14:04:33 EST 2009 Errors: 20 Loops: 78
Expected: 60 found 59
Sun Feb 01 14:04:36 EST 2009 Errors: 21 Loops: 79
Sun Feb 01 14:04:36 EST 2009 Errors: 21 Loops: 80
Sun Feb 01 14:04:37 EST 2009 Errors: 21 Loops: 81
Sun Feb 01 14:04:37 EST 2009 Errors: 21 Loops: 82
Sun Feb 01 14:04:38 EST 2009 Errors: 21 Loops: 83
Sun Feb 01 14:04:38 EST 2009 Errors: 21 Loops: 84
Expected: 65 found 64
Sun Feb 01 14:04:41 EST 2009 Errors: 22 Loops: 85
Sun Feb 01 14:04:42 EST 2009 Errors: 22 Loops: 86
Sun Feb 01 14:04:42 EST 2009 Errors: 22 Loops: 87
Expected: 67 found 66
Sun Feb 01 14:04:45 EST 2009 Errors: 23 Loops: 88
Sun Feb 01 14:04:45 EST 2009 Errors: 23 Loops: 89
Expected: 68 found 67
Sun Feb 01 14:04:49 EST 2009 Errors: 24 Loops: 90
Sun Feb 01 14:04:49 EST 2009 Errors: 24 Loops: 91
Sun Feb 01 14:04:49 EST 2009 Errors: 24 Loops: 92
Expected: 70 found 69
Sun Feb 01 14:04:52 EST 2009 Errors: 25 Loops: 93
Sun Feb 01 14:04:53 EST 2009 Errors: 25 Loops: 94
Expected: 71 found 70
Sun Feb 01 14:04:56 EST 2009 Errors: 26 Loops: 95
Sun Feb 01 14:04:57 EST 2009 Errors: 26 Loops: 96
Sun Feb 01 14:04:57 EST 2009 Errors: 26 Loops: 97
Expected: 73 found 72
Sun Feb 01 14:05:00 EST 2009 Errors: 27 Loops: 98
Sun Feb 01 14:05:00 EST 2009 Errors: 27 Loops: 99
Sun Feb 01 14:05:01 EST 2009 Errors: 27 Loops: 100
Errors: 27

Even after multiple executions, the errors are not occurring consecutively. If this would happen randomly, the chances of occurrence of at least two consecutive errors in 100, with 27% occurrence rate is quite high. It never happened, even after running multiple tests. The reason seams to be the 3 seconds delay of pooling  when reading a bad label value in case of an error. It seams ZK increases the probability of ignoring an event if this event comes right after another one. If the delay between clicks is increased (the red source code line), meaning the delay between requests is bigger, the error rate decreases, even reaches 0.

200 ms      50%

300 ms   27%

500 ms    0%

1000 ms  0%

I have always attempted to prevent usual web application users to submit a form twice (by disabling the submit button after the first submit) but my administrative interfaces model a complex data interaction, requiring a constant client-server interaction. The user is allowed to press a button more than once at very short intervals, for example by pressing the buttons “Up” or “Down” to specify the order of the elements in a list.

Another even simpler test is to send a given amount of clicks and then to evaluate how many clicks were accounted on the server side:

	public void testIncrement2() throws Exception {"/testapp/test1.zul");

		for (int i = 0; i != 100; i++) {"//td[text()='Increment']");
		String s = selenium.getText("//span[@class='z-label']");
		int val = Integer.parseInt(s);
		System.out.println("Value: "+val+ " expected: 101");

For a delay of 350 between requests, we receive an error rate of 49 clicks. For a delay of 100 milliseconds not less than 77 clicks fails to be recorded. The failure rate decreases as the request frequency decreases: for a delay of one second, the error rate is 0 and for 50 microseconds it is 81 percent!

In conclusion, I won’t recommend the usage of ZK in any application requiring a lot of client-server roundtrips. I have never tested their commercial version, they claim a substantial performance gain. I assume if the bug is still there, it only occurs less often.

“So what?” test for software

July 10, 2008

It is widely known that any published text must pass the “so what?” quality gate. The following post tries to extend this to software.

Imagine that you have a scripted language code (in my sample, apache maven) which allows the caller to provide values to one or more variables.

Within the pom.xml file, there is a line like:


And the caller is able to provide a value to the variable, with the call

mvn install

So far so good, but what about if the structure is much complicated, and the user misspells the variable name in the command line call? In this case, no error or warning is issued, the variable uses the default value. This only because the interpretor is unable to question “so what?” the command line.

The implementation of such a feature is difficult: the software should be able to keep track of the variables, their definition source and the amount of accesses. If an user defined variable had no accesses then is as good candidate for the “so what?”

[K]ubuntu 8.04

April 28, 2008

Last week I have installed Kubuntu 8.04 on my machine. And I have got a pleasant surprise. First time in my life, all hardware are functional after a Linux installation. My wireless card, Marvell Libertas based, required ndiswrapper, which was not on the installation CD (it’s supposed to download the driver of the network card), and I installed it manually with a memory stick.

Next, the nVidia Geforce 7 card (on the motherboard) required nVidia “proprietary” drivers. Since it works, I don’t see an issue with the lack of open source drivers.

The big surprise was the sound card, not recognized by other older distributions; no configuration was required and it “simply worked” after disabling the KDE sound manager.

Enabling Compiz under newly installed video driver was also easy and near the window effects I could find some useful shortcuts, such as full screen for any window. Also fonts are looking better rendered than with the standard VGA driver and the controls show more responsive.  Some other “Vista-like” candies like 3D window / desktop switching are also there.

No operating system is useful without applications. Kubuntu has two package managers, which seem very developer friendly. I could install Apache Maven, Sun Java SDK and Subversion and Eclipse with no effort, I have just queried the package database. This was _much_ easier than doing it under Windows, under normal circumstances.

So for a Java developer I think Linux is a better choice because of:

– zero cost of the operating system

– easy to install all the needed tools

– availability of major IDEs (Eclipse or Netbeans)

– availability of server applications (most if not all of the J2EE servers run on Linux as well)

– database servers available – Oracle, MySQL, Postgresql

Of course, there are also reasons to use Windows:

– Microsoft SQL Server, runs on Windows only

– .Net platform (this belongs actually to .net developers)

– you have hardware which does not works under Linux

So my conclusion are:

– installing Linux is faster then installing Windows

– installing Linux is more difficult than installing Windows, if you are unlucky with the hardware. If you are really unlucky with the hardware or simply not skilled enough, you may have no chance to make it run.

– installing developer tools is much easier and faster under Linux

GWT and J2EE

April 21, 2008

My quest after a consistent AJAX interface continues with the next stop, GWT. It sounds impressive that I only have to code Java, and the client will be compiled in static HTML and JavaScript by the GWT compiler. It provides the complete platform independence. Once compiled, the web pages can be used within any web server.

What about the client server communication? Is this a step back to the static content? Standard GWT provides mechanisms of calling a servlet, with  given classes, which have to implement a proprietary GWT serialization interface. Further researches revealed GWT-EXT, here are even MVC GUI controls available.

So once the client-server communication layer is implemented, development of enterprise J2EE applications can be accomplished quite fast. A closed source application, gwt-plus, with a cost of about $200/year provides a transparent way of working with the beans and collection of beans on the server side over the GWT RPC from the GWT client.

EJB3 Remote client: Hello world vs production usage

April 17, 2008

Yesterday I have made the first remote client for an Session bean. Hello world bean worked great, with a little research about how to configure the JNDI client to connect to the Glassfish server and what to provide in the CLASSPATH. I had to duplicate the remote interface and to delete the EJB annotation, since these JARs shouldn’t be imported on the client. I won’t do it in a production application, so I am ready for J2EE dependencies on the client as well.

The evil is as usual in detail. I don’t use EJB to write Hello word software. My session beans work with complex objects, persisted as entities. The beans do refer another beans, in one-to-many relations. In order to load such a list, the client needs to depend on the persistence library of the server, since that list is not a “vanilla” java.util.HashSet class, but one from TopLink or Hibernate, depending on the chosen EJB persistence.

So, near the entity beans, I had to import also the TopLink libraries in the client.

A solution to move from this dependency forest would be to employ web services. Regarding them, my experiences were not encouraging: they crash when receiving a reflexive reference (object A references object B and B references A) and they suffer performance issues both on server and client side when serving large collections.

Another ideas, is to use the value object pattern. This would mean at least duplication of my data model; but remember, I use MDA, so my model is generated from an UML model. Maybe the build of some plain objects could provide a special client JAR file (beans and service interfaces) and a copy mechanism from the beans, to be used on server side.

Ajax and J2EE or how simple things became complicated

April 15, 2008

Last days I have started a new project. It’s about finance, budgeting and management. The UML class diagrams have already dozen of entities, which translate in dozen of tables.

As a big fan of MDA, after designing the model I have immediately generated the database structure, Hibernate POJOs and EJB (at that moment, still undecided which direction should be followed). The whole work took about 30 minutes, with Apache Maven and AndroMDA.

But what about the user interface? AndroMDA offers something similar to “scaffolding” of Ruby on Rails. My problem with this scaffolding is that a number of files are only generated once, subsequent changes will not reflect them self on the existing generated sources. With other words, it sucks, since I am sure my model is not final, customers will perform lots of changes until it goes into production.

Following the speculation path (yes, I do use Agile PM), I have taken the simplest entity, which only has three columns (2 strings and a boolean) and attempted to see how easy is to have an AJAX based table to perform CRUD (create read update delete) on this table.

The first choice would be ZK, an open source AJAX library. Because of their GPL license, which forces me either to publish my sources or to acquire their commercial license, I have considered another AJAX engine, RichFaces.

RichFaces has a nice comprehensive demo and a bad written manual; as a beginner in RichFace, I find it unreadable because of cyclical definitions (such as: “bypassUpdates attribute allows to bypass the Update Model phase” and no definition of Update Model is given) and employment of too many undefined concepts. Maybe my further contacts with RichFaces will allow me to read their manual with other eyes. I have found a nice sample explaining tables with editable cells. It looks nice, but, it doesn’t store the changed data! The inquiry on the RichFaces forum had was immediately answered by some more advanced user, which acknowledged the issue and provided a solution. I was just one step away of abandoning the RichFaces track and moving to other AJAX engine, but their vibrant community convinced me indirectly not to switch.

After successfully building and running the web application within Maven, my approach is to connect the table to a list of EJB3 entities. The plan is to build a transaction on each change since it is not usual that users will perform a lot of changes here, and this avoids the usage of a “Commit” button people can forget to press while jumping to another page.
I also plan to have a “New Item” and “Delete Item” button. Delete seems to be easy to implement, while adding a new item can be a pain – since the table has a paged scroller and after adding the new item, the scroller should jump at its page. Also, the newly inserted item has an “uncommitted” state until all of its items are filled with data.

Well, after reviewing the findings in this loop, I remember 18 years old technology named “FoxPro”. This technology powered my first business. It didn’t have funny programming features such objects, no enterprise capabilities (they were added afterwards). It doesn’t run through a web interface or even within a windowing system (but on a 80×25 character screen). This tool could easily handle an editor with millions of entries on an Intel 80286 processor based machine, and this with a simple BROWSE command. Now, I read blogs of ajaxians complaining about performance of Ajax tables containing 500 entries! If FoxPro would be hypothetically transformed in a client server engine, considering an average refresh rate of the screen to one second, it would use only a 32kbit bandwidth to run through a terminal. An ajax application uses much more bandwidth, even in the context Ajax reduces the amount of data transacted (and if properly coded, the number of transactions) between server and client.

So, what is the direction our technology evolution follows? Do we sacrifice the simplicity of design and implied simplicity of deployment and usability to acquire some obscure targets such as “transactionability” or “service oriented architecture”? I see now more than ever web sites crashing with errors like “Invalid Transactional State” or “Session Expired” (although I didn’t time it out). I try to imagine what platform did the developers of these sites use and what mistake they done and the answer is from day to day harder to find.