Archive for the ‘java’ Category

Spring Configurator

July 13, 2007

In Apache Cocoon we have several subprojects that can be used completely outside Cocoon scope. Roots of these subprojects are of course in Cocoon, we needed solutions for our own problems. Then it turned out that some pieces can be generalized and isolated from Cocoon’s code and concepts. One of such projects is Cocoon Spring Configurator. See it’s introduction page to get overall idea of what functionality it brings.

My own opinion is that Spring Configurator may be handy to everyone who develops nontrivial applications utilizing Spring framework. As the names suggests its main function is to deal with configuration of your apps and it does its job very well! I’ll show you an example of bean-map functionality that I like most.

It’s very common case that you have several implementations of some interface; each one identified by some name. I had such a case in Cocoon, recently. I wanted to let people define database connections as Spring beans so they could be used in every Cocoon component. I’ve created Spring bean with following property:

private Map springDataSources;

and configured it that way:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:configurator="http://cocoon.apache.org/schema/configurator"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://cocoon.apache.org/schema/configurator
  http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd">
  
  <bean id="..." class="...">
    <property name="springDataSources">
      <configurator:bean-map type="javax.sql.DataSource"/>
    </property>
  </bean>
  
</beans>

I’ve cut down details that does not matter here. As you can see, Configurator takes a burden of creating Map of beans implementing javax.sql.DataSource interface that is passed to our bean. The key for every entry in the Map is bean id (but it can be something else, e.g. property of a bean).

Example above is not rocket science but I find bean-map functionality very handy. In a fact, Spring Configurator can do a lot of more but it’s not a point to replicate what’s already in the documentation. At the end, I advise you to take a look at this hidden treasure; it’s very light-weight and has small number of dependencies.

Advertisements

First results of GSoC work

July 7, 2007

Finally, besides discussing, I have done some real work as GSoC participant. I have successfully moved expression handling code to separate modules (api and impl) so they are not tied to template handling code. Next important thing was getting rid of Avalon dependencies. Believe me or not, but such a conversion is not that scary and if you grasp basic principles it’s really a matter of labour work.

If you want to check in detail what has been changed, check this issues:

  • COCOON-2082 – Get rid of Avalon dependencies in cocoon-expression-language code
  • COCOON-2081 – Move api and implementation of expression languages to separate module

I had to move tests too and it turned out to be much more difficult task mainly because Cocoon was lacking any up-to-date documentation on that subject. After figuring all out of details and getting tests back to the work I decided to share my experiences. Check this document to see how to write tests for Cocoon 2.2.
When it comes to documentation, it’s worth to mention other small addition: document describing how to configure logging in Cocoon 2.2. Thanks to Alex for bringing original information.

Hacking Cocoon during summer

June 15, 2007

I guess that most of you reading my blog do not know that I was accepted for Google Summer of Code. I proposed to work on Cocoon’s expression handling during upcoming summer, you can find detailed proposal here.

What are benefits you may ask. Current situation is quite depressing when it comes to expression handling. First of all, we have dozen of them in use across the Cocoon. Some of them operate on similar but still different model so it’s very usual that you may access the same values differently depending on you ask for them from flowscript or jx template. What is worse, models and expressions itself are poorly documented. My task is to change that reality and I hope to not fail.

It is interesting that on Cocoon’s dev mailing list almost nothing happens. My guess is that everyone just waits for RC1 in silence and keeps fingers crossed. Yes, we need a lot of good faith because Maven seems to hurt us really badly. Torsten has told me about his never-ending struggle with Maven bugs, limitations or bad implementation of nice idea. Basing on my own experience I must say that from time to time Maven disappoints me also. The worst thing is that when you get stuck you also get the feeling that there is no way out. It’s also a time when you feel that you really wasting your time.
I hope we’ll not waste to much time because of Maven and Apache Cocoon 2.2 RC1 will get released soon.

Last thing I would like to mention is ongoing discussion about Cocoon’s minimal requirement for JVM version. As you may already seen reading the discussion I opt for Java 1.5 as minimal. The main argument for abandoning Java 1.4 compatibility is a cost for community of maintaining that compatibility. Really, only few persons develop (or at least test) Cocoon with Java 1.4, Continuum is running on Java 1.5, etc.
If you have something to add drop a comment here or post your thoughts to Cocoon’s mailing list.

Solution for singly-circularly-linked problem

June 10, 2007

I promised to post a solution for the problem I set earlier. Now it’s time to keep the promise.

The solution is really simple because the problem itself is trivial I would say. Imagine two racers at the running track that has circular shape both starting from the same position. Let’s assume that one trained harder and can run at double speed of the another racer. Let’s imagine that they start to race but do not finish after running a one lap. They continue to race, what will happen eventually? The answer is that faster one will lap the slower runner. That’s main idea behind the solution… ๐Ÿ™‚

Let’s translate it to a terms used in programming. You have two variables (runners) pointing at the first element of the list. Now, each time one pointer moves two elements further but other one moves only by one element from the list further. You can observe the process at this picture:

Picture showing two pointer moving along the list

Now we have two cases:

  1. If list is not circularly-linked faster runner (pointer) will reach its end and that will be a sign for us that we have detected list that is not circularly-linked
  2. If list has a cycle faster runner (pointer) will lap the slower one at some point and that will be an information for the algorithm that circularly-linked list has been detected

Obviously, the algorithm uses constant memory (two pointers). I’ll leave as an exercise to show that number of pointer shifts is not great than 2n where n is number of elements in the list.

Here you have simple implementation of this algorithm:

public class DetectCycle {

	static int steps = 0;
	
	public static void main(String[] args) {
		System.out.println(detectCycle(createLinkedList(50, -1)));
		System.out.println(steps);
	}
	
	static private boolean detectCycle(ListItem head) {
		ListItem slowerRunner = head;
		ListItem fasterRunner = head;
		steps = 0;
		while (true) {
			if (fasterRunner.getNext() == null) return false;
			fasterRunner = fasterRunner.getNext();
			if (fasterRunner.equals(slowerRunner)) return true;
			
			if (fasterRunner.getNext() == null) return false;
			fasterRunner = fasterRunner.getNext();
			if (fasterRunner.equals(slowerRunner)) return true;
			
			slowerRunner = slowerRunner.getNext();
			steps = steps + 2;
		}
	}
	
	static private ListItem createLinkedList(int numberOfItems, 
                                                 int closeCycleAtPosition) {
		ListItem head = new ListItem();
		ListItem tail = head;
		
		for (int i = 1; i <= numberOfItems; i++) {
			tail.setNext(new ListItem());
			tail = tail.getNext();
		}
		
		if (closeCycleAtPosition >= 0) {
			ListItem item = head;
			for (int i = 1; i < closeCycleAtPosition; i++)
				item = item.getNext();
			tail.setNext(item); //closing cycle at specified position
		}
		
		return head;
	}

}

and ListItem class:

public class ListItem {
	private ListItem next;
	
	public ListItem() {
		next = null;
	}
	
	public ListItem getNext() {
		return next;
	}
	
	void setNext(ListItem next) {
		this.next = next;
	}
}

EDIT: I thought that it would be nice to tell you similar riddle. Here it goes:
How to count number of elements (legnth) of the list despite it has cycle or not. Rules are the same: algorithm must be linear and use constant amount of memory. Again solution is simple!

Cocoon 2.2 RC1 release delayed

June 6, 2007

I have finally some free time. In Poland, 7th of June is a catholic feast so everyone has a free day.

I have a bad news about Cocoon’s upcoming release. Even though it was nearly there we had to delay the release because of small but important issue. We had a dependency on a artifact that is not officially released (and is not available on Maven’s central repository).

I think that the fault comes from the bad practice of Cocoon 2.1.x days that we were depending on snapshot versions and shipping them with our big, fat distribution. Use of Maven enforces us to be more careful on how we handle our dependencies, we need to work out new rules and practices.

I must admit that I do not blame Maven and I’m quite happy with the situation. The blocking issue should be fixed really soon and we’ll make that eagerly awaited announcement. What’s also important, we’ll not have a dependency on cryptic version of commons-jci that no one will have an idea what it was a year later.

Stay patient a little bit longer, Cocoon will come. ๐Ÿ™‚

cocoon-rcl – my precious

March 24, 2007

I finally made cocoon-rcl to work, few days ago. Cocoon-rcl is Maven plug-in that makes life of every Cocoon developer much easier and pleasant. It enables you to develop Cocoon applications/blocks rapidly. You may wonder what that means exactly. In a fact, it takes care of resource and classreloading so you can develop without any restarts of your application.

Essentialy, all you have to do is to start your block this way:
mvn cocoon-rcl:webapp jetty:run
And start hacking sources of your block in any IDE you like. All changes will be instantly visible in a browser. You can change sitemaps, flowscript files and even ordinary Java classes.

I would like to thank Reinhard Pรถtz who has done this handy plug-in. Developers willing to migrate from 2.1.x should consider it as one of killer-features along with servlet services and Spring integration.