Tuesday, 27 July 2010

Comparing approaches to Vaadin and OSGi

Some time ago, inspired by an attempt I saw on their forums, I set about enabling Vaadin (a pretty amazing RIA derivative of GWT) so that it would work in an OSGi container. You can read about that here.

As it happens Peter Kriens and Neil Bartlett both set about doing the same thing, all our efforts completely independent of each other. In this post, I'll compare and contrast the three approaches.

Firstly, Peter and I both decided to use Declarative Services (DS), where as Neil decided to create a light-weight service driven API.

In that regard, the approaches fragment and it becomes difficult to compare Neil's approach with the approach taken by Peter and myself. The main advantage of the service driven approach is that you don't need to use DS. You create an instance of the service interface and register it, then the rest of Neil's code makes that implementation available as a Vaadin application. This is a great approach if you might not want to use DS and doesn't stop you from using it if you want. The main disadvantage here is that there is an extra dependency on the API that Neil has created.

With the DS approach there's no additional hard-dependency, though there is a dependency on DS implied. In both Peter's approach and mine, we simply extend com.vaadin.Application and mark the implementation as a component factory. After this, things differ slightly between my approach and Peter's.

My code looks for components with the property "component.factory=vaadin.app" and once I find matching component factories I take the "component.name" of the factory and use that for the HTTP alias against which to register the servlet that does the work. Peter's approach is to look for "component.factory=com.vaadin.Application/*" and take the name from the part represented by the wildcard. This seems like a more sensible approach, as the component name tends to be more unique and use a domain name type structure, if not the component classname, period. A classname is not really an appropriate HTTP alias.

Vaadin uses a fair amount of static resources. My view here is that in most cases a dedicated web-server should be used to handle static resources (e.g. Apache), in a classic n-tier setup where static content web servers sit in front of 'application servers'. As such I've created a second bundle called staticres which will proxy static resources from the Vaadin bundle, but the recommended approach is to use a web-server. Further more, if your app has additional static resources that are not in the Vaadin bundle then these can be added by creating a fragment containing those resources and setting the host to the Vaadin bundle. My "staticres" bundle won't know the difference.

However, this highlights another major difference between my approach and Peter's. In Peter's approach, he expects wraps the Vaadin jar and turns it in to an internal library, exporting it's packages to the container. However, the Vaadin is already a bundle, so this seems unnecessary to me. The additional downside of this is that if the Vaadin jar is updated by the Vaadin folks, then people using Peter's bundle will either need to rebuild it for themselves, or wait for Peter to release a new version. The approach I have taken allows people to update the Vaadin bundle independently of the OSGi code I've written.

The remaining differences between my approach and Peter's are at the code level. Peter's experience shines through showing much better concurrency handling and support for multiple HttpService implementations, where as mine only supports a single HttpService.

So in Conclusion, Vaadin must be an interesting technology (personally I love it) for three individuals to decide to skin that cat in their own way. While the DS approach I've taken is considerably different from Neil's service approach, there are definitely enhancements to what I have produced that I can make based on Peter's code. To summarise the pros and cons of all three:

Neil's approach:
+ no dependency on DS and does not preclude it either
+ not coupled to any specific version of Vaadin
+ lightweight easy to use API
- additional dependency on non-standard API
- no clear way to handle additional static resources
- may end up using DS anyway

Peter's approach:
+ well defined and sensible use of DS
+ high quality implementation
- no clear way to handle additional static resources
- tight coupling to a specific version of Vaadin

Brindy's approach:
+ not coupled to any specific version of Vaadin
+ additional static resources easily handled
- limited to one HttpService
- use of DS needs to be better defined
- needs better concurrency handling

If you're interested in working with Vaadin and OSGi and want a forum in which to discuss your ideas or get help feel free to join our Google Group.

Tuesday, 6 July 2010

functional programming and java - no thanks!

If this is a sign of things to come in Java-land I suspect I'll be moving on:

http://stronglytypedblog.blogspot.com/2010/07/lambdas-in-java-preview-part-2.html

Ugly. Very ugly. So ugly in fact, I want to swear. I haven't looked at the strawman proposal yet, and really don't want to, but I suspect there will all kinds of problem with scope.

Functional programming has it's usefulness, it's great for languages like JavaScript for instance, which I think needs it in order to make up for lack of proper OO syntax or semantics.

What would be really useful in Java is autosynthesis of properties. What the hell do I mean by that?

Well any Java programmer knows that they'll end up writing getters and setters for properties, or ignoring them all together and making the instance variables public (I don't!). A useful feature in Java would be a way to reduce the need for getters and setters while retaining binary compatibility.

It's really not hard:

public class Person {
public property String firstname;
public property String lastname;
}

Which can then be accessed in *either* of the following ways:

System.out.println(person.firstname);
System.out.println(person.getFirstname());

And if you really want a getter or setter ... just add it!

public class Person {

public property String firstname;

public property String lastname;

public String getFirstname() {
// Do something funky, return something completely different, or just return the property itself.
return firstname;
}
}

OR

public class Person {

public property String firstname;

public property String lastname;

public String setFirstname(String firstname) {
if (firstname == null){
throw new NullPointerException("firstname cannot be null");
}
this.firstname = firstname;
}

}

That's the kind of thing I want added to Java.

Wednesday, 9 June 2010

Money Tracker for iPhone



Money Tracker is the simplest financial application on the App Store. It is a no frills day to day money tracker to help you watch your spending easily and quickly.

To start, click the button in the lower left to set a spending amount. Then simply add expense items to subtract from your spending amount and you'll be show how much you've got left, or how much you're over.

You can also mark an item as a credit and this will add instead of subtract from your spending amount.

Great for students or people on a tight budget trying to rein in their disposable income!

Money Tracker is only available in English, but it does support your local currency according to your iPhone's setting - so don't worry if you use Euros, Dollars, Yen, Pounds or anything else - it will still make sense!

If you find problems please comment here!

Screen Shots:



My First iPhone App!

I've just submitted my first iPhone app - Money Tracker... a port of my Android app to iPhone. It's been a very interesting journey and once I got stuck in to it I was actually surprised how easy it is. I'm sure I've still a lot to learn, though.

I'll be posting more details in my next post, which I'll be using as the web page for the application.

Saturday, 27 March 2010

practicing with fibonacci

It's Saturday morning, I'm slightly hungover and my wife has gone out shopping with her friend (and my credit card!). What else am I going to do except practice some coding?

I was reading a few academic sources and a lot of them mention Fibonacci sequence and I thought to myself, you know, I've never coded that (I mean, why would I?).

First up, I created a small test harness:

int sequence[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 };


for (int i = 0; i < style="color: #2600c9">length; i++) {

assertEquals("fail " + i, sequence[i], fib(i));

}


And then I knocked out an iterative function in virtually no time:

public long fib(int n) {


if (n < 0) {

throw new IllegalArgumentException(

"Negative numbers are not supported");

}


if (n < 2) {

return 0;

}


long result = 0;

long first = 0;

long second = 1;

for (int i = 0; i < n - 1; i++) {

result = first + second;

first = second;

second = result;

}


return result;

}

It works, and it's fast, I went back to reading.

After a while I found another example of the Fibonacci algorithm:

static long fib(int n) {
return n <= 1 ? n : fib(n-1) + fib(n-2);
}

Oh! Recursion - damn it, of course, it's obvious, but wait ... throw in a big number there and what's going to happen? Well assuming you don't run out of memory (the stack frame should be quite small anyway), that's going to be slow...

For every number up to n where n is greater than 2, it looks like that function gets called 2 * (2 ^ n) times, i.e. O(2^n) - so assuming i throw in 50 that's 2 ^ 50 operations ... i.e. a lot.

Note: Further reading reveals that function actually has a complexity of O(2^0.7n) though I don't know how they worked that out. If anyone can enlighten me, I'd appreciate it as I haven't done this stuff in anger for several years now.

I wrote two more tests in my test harness to see the difference in time and threw in 50. The iterative one always finishes almost instantly - you can see by looking at it that it will run in O(n) time, the recursive one takes around 90 seconds on this computer.

The next problem I encountered was testing with larger numbers - I soon started seeing negative results as the maximum value of long was exceeded and automatically wrapped around. For instance, throwing in 200 yields -1123705814761610347 which isn't much use.

Thankfully Java has something called "BigInteger", which, as the name suggests, lets you use Big numbers. I modified the method to use the BigInteger class as follows:

public BigInteger fibIterative(int n) {


if (n < 0) {

throw new IllegalArgumentException(

"Negative numbers are not supported");

}


if (n < 2) {

return new BigInteger(String.valueOf(n));

}


BigInteger result = null;

BigInteger first = new BigInteger("0");

BigInteger second = new BigInteger("1");

for (int i = 0; i < n - 1; i++) {

result = first.add(second);

first = second;

second = result;

}


return result;

}


Throwing in 200 to that method yields 280571172992510140037611932413038677189525 which looks better, though I will have to take it on faith that it is correct.

Wednesday, 17 March 2010

enable or disable buttons in a mx:ButtonBar

I can't believe there isn't actual support for this built in to the component, but I have come up with a 'cunning hack' which gets around the limitation of the mx:ButtonBar in which it is not possible to bind the enabled state of it's buttons:


So the object's "toolTip", "label" and "icon" properties get propagated through to the buttons added to the button bar, but the enabled property does not. The code above simply fools the binding in to action by calling a method as part of the bind. When the property changes, that method will get called again and the button's enabled state will be set correctly.

Saturday, 27 February 2010

neo4j on OSGi

I need to have a deeper look at neo4j, which I found out about via InfoQ today, but initially I thought I'd see how OSGi friendly it is.

At first look I was quite excited - the neo4j jars are actually bundles. Yay! :)

So I dropped the contents of the neo4j lib folder in to my Apache FileInstall folder to see what happened.

org.apache.felix.log.LogException: org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Import-Package: org.neo4j.index; version="1.0.0"

And was probably due to:

org.apache.felix.log.LogException: org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Import-Package: org.apache.lucene.analysis; version="0.0.0"

Aha! A quick look at the provided Lucene jar reveals that it is not a bundle. Boo! :(

Easy enough to sort out though, create a quick bnd wrapper! Or so I thought. The following wraps the Lucene jar creating a bundle which exports all the packages from the Jar and imports all detected dependencies:

-classpath: libs/wrapped/lucene-core-2.9.1.jar
Export-Package: *;version=${Bundle-Version}
Bundle-SymbolicName: lucene
Bundle-Version: 2.9.1

To use the above, put it in a file called lucene.bnd and run the bnd tool on it. However, that wasn't the end of the problem...

org.apache.felix.log.LogException: org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Import-Package: sun.misc; version="0.0.0"

sun.misc ... WTF? sub.misc is an optional package used by PersonalJava and a few other things that I doubt many people care about these days. Unfortunately bnd detects this package usage when it creates the bundle and makes an import for it. This can be overcome by creating an import specifically for that package and marking it optional:

Import-Package: sun.misc;resolution:=optional,\
*

The * at the end is quite important, as that tells bnd to make sure it imports all other detected dependencies, as normal.

After that the bundles installed and activated without any problems. Sweet. So I will probably come back and look at neo4j in more detail after I get some sleep.

However, this is the second Apache project that I have looked at this week which has not made it's JAR files bundles by default, the other being Batik (from the XML Graphics project). It isn't a difficult thing to, so why don't they all do it?