Archive for the ‘Java’ Category

Generic variable to the current type

Friday, March 6th, 2009

I just noticed that I’ve been using the Builder pattern with method chaining a lot. Looks like this:

FooBuilder builder = new FooBuilder();
Foo foo = builder.add(...).divide(...).multiple(...).builder();

The issue that arises is that I want to store a bunch of methods in a base class that various builders can use. In order to do this correctly, I have to really hack up my classes with some strange generics and unchecked casts like this:

public class BaseBuilder<T extends BaseBuilder> {
  public T add(...) {
    ...
    return (T) this;
  }
  public T divide(...) {
    ...
    return (T) this;
  }
  public T multiply(...) {
    ...
    return (T) this;
  }
}

public class FooBuilder extends BaseBuilder<FooBuilder> {
  public Foo build() {
    ...
  }
}

This is really annoying. I think every class should have a generic type variable that references the current type and let the compiler figure it out. Just name the variable ME or something. It would make the code look like this instead:

public class BaseBuilder{
  public ME add(...) {
    ...
    return this;
  }
  public ME divide(...) {
    ...
    return this;
  }
  public ME multiply(...) {
    ...
    return this;
  }
}

public class FooBuilder extends BaseBuilder{
  public Foo build() {
    ...
  }
}

Now that’s much nicer looking.

Inferred typing

Friday, March 6th, 2009

I know that .Net 4 is going to have some pretty cool features around dynamic typing and C++0x is also adding some auto typing features. I was thinking about all of this today and realized that what I really use most of the time is an inferred type. Essentially it would infer a new type based on the method’s contents.

Let’s say we have this:

public void callSomeMethod(Object obj) {
  obj.methodCall();
}

In static languages this fails because Object doesn’t contain the method methodCall. However, what if we told the compiler to create a new interface based on the content of the method? This code would then look like this:

public void callSomeMethod(autotype obj) {
  obj.methodCall();
}

The autotype keyword would cause the compiler to actually create this code:

public interface MethodCallInterface {
  void methodCall();
}

public void callSomeMethod(MethodCallInterface obj) {
  obj.methodCall();
}

This would now compile. Next, a caller to this method could pass in any object whose type the compiler could add this interface to. If you called it like this:

public class MyClass {
  public void methodCall() {
    System.out.println("Here I am");
  }
}

// Some other code somewhere
MyClass mc = new MyClass();
callSomeMethod(mc);

The compiler could take the interface it created for this method call and then see if the type passed in could implement that interface. If MyClass has already been compiled, it could do one of two things:

  • If MyClass is accesible as part of the current compilation unit, it could update the compiled Class to implement the interface
  • If it isn’t part of the current compilation unit and isn’t final, it could create a proxy for the call that implements the interface and delegates the call

Not sure yet how #2 really works or if it even makes sense to do it that way, but it seems to be the only way to make it work if the Class is in a JAR or DLL or something like that.

The only issue would be reflection. How could you reflection on the method and then pass an Object to it so that it would not completely blow chunks at runtime? Perhaps the reflective method invocation could determine if the object being passed could be proxied to the dynamic interface and then create a proxy on the fly.

Anyways, just pondering type systems in general today….

Android review and iPhone comparison

Friday, January 23rd, 2009

Here’s a quick run-down and comparison between the G1 vs. iPhone and Andriod vs. OS X mobile. This is based on side-by-side evaluation with both phones.

The phones

Keyboard

The winner: G1

The G1’s keyboard is awesome. I like it so much better than the iPhones mainly because I can see the whole screen while typing, but also because it has numbers and I don’t have to hit something to switch between numbers and letters. I’m a keyboard freak, so hands down the G1 wins.

Screen

The winner: iPhone

I think this is close to a tie, but the iPhone screen is bigger. The resolution is the same for both phones, which means that the G1 can display as much information as the iPhone, but it is smaller.

Battery

The winner: iPhone

The iPhone’s battery is 2-3 times better than the G1’s. I’ve heard word of T-Mobile shipping out batteries that add 30% more life, but even still, I play around with my G1 very little and it still needs to be charged daily. My iPhone needs charging every 2-3 days with the same use.

Form factor/Design

The winner: iPhone

This isn’t much of a battle. The iPhone is sleek, light and really nice to look at. The G1 is thicker, heavier and an eye-sore comparatively. However, I can understand the extra size given the full keyboard. One thing the G1 does nicely is it figured out the exact size required for anyone to hold it in one hand and use any feature of the phone. This is the only thing nice about the G1’s size and shape.

Buttons

The winner: G1

I like the buttons and track ball with the G1. The iPhone is sometimes a bit cumbersome to use given that everything is on the screen. Sometimes it is nice to just hit a button.

Accelerometer

The winner: iPhone

The iPhone has a really good accelerometer that seems to be level and responsive. The G1’s is a little rough around the edges and you can’t calibrate it or tweak it at all.

The operating systems and software

Structure

The winner: Android

Android has a lot of advanced features that are pretty nice overall. Each application has a menu, which is great for adding loads of functionality. There are keyboard shortcuts in applications which makes using features fast. Android has intents which are nice. It also allows applications to leverage other applications and common libraries. By far, Android wins when it comes to a modern platform.

At the same time though, Android has many bugs and issues that also make it difficult to actually use.

Homepage/Application Chooser

The winner: Tie

The iPhone home page doesn’t have the cool backgrounds or the lame analog clock or the drag and drop application display, but it is simple, orderable (you can move apps around), and looks really nice. Androids has a cool homepage that allows ordering and an alphabetized app chooser. So, they are different, but equally as usable and cool.

Androids icons definitely have that Linux look, which I grew tired of a decade ago while iPhone’s icons are sleek and nice and I haven’t gotten tired of yet (only 1 year as a Mac user). It seems like Apple is more in tune with style and each OS release keeps things fresh. We’ll see how 10.6 goes. Linux on the other hand just plain sucks the life out of you.

Voicemail

The winner: OS X

T-Mobile and Android’s voicemail integration is horrible. It is exactly the same as every other phone for T-Mobile because you have to dial into voicemail and manage it via T-Mobile’s phone system. There is an 3rd party application that adds visual voicemail to Android phones, but it is in beta and it is a hack that appears to actually dial up your voicemail and record the voicemails to an MP3. I’m not positive on that, but this is what it seems like. Regardless of how this application works, it is a 3rd party application and T-Mobile and Android should really be offering a tightly integrated feature of the phone.

The iPhone completely integrates with AT&T’s voicemail such that you can view all your voicemails on the phone, listen to them on the phone, and even setup and switch your voicemail greeting on the phone.

Calendar

The winner: Android

The Android Google calendar integration is great. However, it doesn’t support multiple calendars very well (you can only view calendars in the associated GMail account and not other GMail accounts or an Exchange calendar) and that’s a real pain point for most. Since I use a single calendar for everything, I don’t mind too much. On the other hand, if you have a Mac and only use Calendar.app, integration with the iPhone is great. This combined with Mobile Me would be ideal for real-time updates and syncing. For now though, Android wins in this department.

I’d imagine that Google will soon offer syncing with the iPhone as it does with the BlackBerry. If not, NuevaSync will work once it is finished and out of Beta.

Likewise, I would put money that Android will start supporting multiple calendars shortly.

Maps

The winner: OS X

Multi-touch, double-click and good integration/features wins this battle. Since you are already touching the screen to move around, multi-touch is nice. The G1’s map interface is nice and it does allow single handed use, but iPhone’s bigger screen and multi-touch prevail in this category.

Email

The winner: OS X

First, the GMail application really should be combined with the Email application. The fact that they are separate is really painful and annoying. Email should just be email like the iPhone does. Second, Android’s email application is one of the worst applications ever written. Here are a few of the pain points:

  • Can’t view first few lines of emails in the inbox view
  • The folder and email view are combined making for a very cluttered interface
  • Email fails regularly even when connected to a WiFi
  • Deleting emails does nothing for GMail accounts via IMAP.
  • Can’t setup what happens on delete for IMAP accounts. For example, with GMail IMAP it should move the message to [Gmail]/Trash

The worst thing is probably that the Email application doesn’t instantly work with GMail IMAP accounts. This should just work considering that the entire platform and stock applications are written by Google. I mean come on guys, take a cue from Apple and just make stuff work, especially with your own systems. Plus, Email constantly crashes and has so many issues that it is rendered useless in most situations.

The iPhone email isn’t perfect, but it handles all of these things much better and also makes setting up GMail accounts a snap.

Document Viewer

The winner: OS X

The iPhone has a built in PDF viewer that works really well. It also displays Word documents and other formats decently well. In gets a little bit freaked out by complex Word documents in the new DOCX format, but otherwise it is great. It also allows you to zoom in and out using multi-touch and double-click.

The G1 looks like it uses Google Docs online viewer or some type of hacky internal viewer. Not really sure about which one, but it does a very poor job of displaying documents and files, including PDF (I mean really? PDF? It should perfectly display all PDFs). Images are also displayed poorly and some don’t render correctly, such as JPGs. Plus, no zoom (ouch!).

Apps

The winner: OS X

This is based purely on the most fundamental of all applications, solitaire. There are a number of choices on both phones, but overall the solitaire on the iPhone is much nicely in terms of design, features, etc.

App stores

The winner: OS X

Apple’s store has a much cleaner interface and includes pictures, better details, better commenting system and more interactivity. The Android market looks pretty shabby comparatively.

Accelerometer/Orientation

The winner: OS X

The iPhone uses the accelerometer all over the place and it does it really well. Orientation of the phone is really helpful in most applications as it makes the phone easy to use.

Android’s support for orientation and the G1’s accelerometer is just garbage. Even the browser requires 3-4 clicks before you can change the orientation without opening the keyboard. I mean come on guys, just use the tools you have and make people’s lives simple. Plus, HTC seems like they added a pretty low end accelerometer and it isn’t calibrated very well. Plus, you can’t really calibrate it.

Development

The winner: Android

I’ve talked at length about how I think Objective-C is really keeping Apple back, but here’s another way to look at it. If you take the years that technologies were introduced and line them up so that you have language, RAM, and CPU (based on speed), here are the results:

iPhone: 1986 1989 2000
G1: 1995 1996 2000

I definitely like the G1 and Android numbers much better.

The Final Score

If we add all these up, it looks like this:

G1/Android: 5

iPhone/OS X: 11

The final winner? iPhone/OS X

Visual Studio sucks, NetBeans is coming along, IJ is slipping

Friday, December 5th, 2008

I’ve been working on a decent sized C++ project recently and since the application will be used on a Windows server, I wanted to stay close to that platform. I fired up the latest Visual Studio 2008 version hot off the presses with my MSDN subscription and boy is that thing a piece of junk. It is like working in the stone ages. I mean writing C++ is bad enough and then I have to battle with the worse IDE imaginable?

I think not.

So, I grabbed Eclipse and NetBeans and fired both up. Eclipse, is a beast and I wanted to avoid it at all costs if possible. I’ve never liked Eclipse, no matter the version, and they haven’t improved the issues enough for me to really use it for Java development. However, I found the Eclipse C++ integration decent, but still pretty rough. The Eclipse interface is so clunky that it makes it hard to be productive.

Next I grabbed the latest NetBeans (6.5) and fired it up. I have to say that it started pretty darn fast for a Java IDE. It also has a really decent layout and configuration system. The C++ support, although experimental for on the fly error highlighting, is impressive. After tweaking my colors and battling through keymappings I’m actually productive. NetBeans lacks a number of editor features that are required these days, including multiple clipboards, duplicate lines (has this but no keyboard shortcut), join lines, etc. Besides this problems, I like it.

On the flip side, IntelliJ is still great. 8.0 is just out and it adds a number of new great features and more language support. However, I think that IJ is probably getting close to needing a good chunk rewritten. The configuration system is becoming clunky, the projects difficult to manage, and most aspects of the IDE are beginning to fail.

The speed is horrible, the memory consumption off the charts and the productivity increases that we all used IntelliJ for are is slowly being integrated into the other IDEs. I think IJ is still the best, but their margin is slowing being reduced. If the folks over at JetBrains want to stay competitive they are gonna need more speed, more productivity, more simplicity and more power. These things are all hard to get at the same time, but I’m confident that they will find at way.

For now, I’m gonna give NetBeans the full shake-down, log a ton of bugs and wait for 7.0 to see how many they fix. I’d say my list is pretty short at this point and I could envision a full switch to NetBeans with 5-10 enhancements if IntelliJ continues its slow decline.

Only time will tell.

Savant command-line tool and plugins are almost ready

Friday, November 14th, 2008

Been working this week on Savant 2.0. My first thought when I started writing Savant 2.0 was to write a complete replacement for both Maven and Ant that used Groovy and allowed for both a plugin model as well as a simple build script approach. This was too much to bite off when you consider all of the other changes to the dependency management part of Savant we made for 2.0.

For JCatapult we created a set of Ant build scripts that could be plugged into any build file and reused. It looks like this:

<project name="foo">
  <import file="${jcatapult.home}/ant/plugins/java/1.0/compile.xml"/>
  ...
</project>

This model meant that the build.xml file had nothing but import statements in it. It made life much simpler when working with numerous projects that were virtually the same.

The part I didn’t like was that I loved this model. I liked it so much I started using them for everything including Java.net Commons, Savant and internal Inversoft projects. This meant that I had a dependency on JCatapult, which for all intents and purposes is a webapp platform. This seemed strange.

I started thinking about moving these files over to Savant. At first I just figured I would migrate the entire set of Ant plugins from JCatapult over and be done. However, once I moved them over it meant that I would need to start pulling in plugins for a variety of projects. Some would come from Savant and others might come from JCatapult or elsewhere. This was due to the fact that some of the JCatapult plugins were very specific to JCatapult projects. I could force developers to download each plugin they needed from various places, install them in a specific directory and then update their build files before they could build any projects. It all started to look very clunky.

Then I remembered (duh!) that Savant is a dependency management tool and it can find, version and download ANYTHING. Why not apply this pattern to Ant build files in the form of plugins?

So, I did just that!

It works great. The way it works is that I wrote a simple Java class that figures everything out and then generates an ant build file. The full process looks like this:

  1. New script called svnt invokes a Savant class
  2. This new class parses the project.xml file, which defines the plugins the project will be using
  3. It downloads any missing plugins to the Savant local cache
  4. Since the plugins are JAR files, it explodes the JAR file to ~/.savant/plugins under a specific directory just for that plugin
  5. This class then generates a temporary build.xml file that imports all of the plugins the project needs
  6. It outputs the location of this temporary build.xml file
  7. The svnt script executes Ant passing it the location of this build file (i.e. ant -f /tmp/tmpbuild.xml)

And that’s it. Nothing fancy, just a little sugar on top of Ant to provide downloading of plugins and build files automatically.

The last part of this exercise is to write a bunch of plugins. Since these are just Ant build scripts and we’ve all created hundreds of those so it should be a simple matter of tweaking them ever so slightly to work when imported.

My new projects don’t have a build.xml file (but if they do it is imported to add additional targets or override targets from the plugins) and just contain the Savant project.xml file. This file now defines plugins and it looks like this:

<project name="foo" group="inversoft.org" version="1.0">
  <plugin group="plugins.savant.inversoft.org" name="clean" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="java" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="junit" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="release-svn" version="1.0"/>
  ...
</project>

That’s it. If anyone is interested in trying it out, I should have a release available in the next few days along with some documentation for the 5-10 plugins I will have ready. If you want to try and build all this by hand right now, you’ll need to install JCatapult since Savant uses that until it can be self building.