« November 2007 | Main | January 2008 »

December 2007

Dec 17, 2007

Pulse for Mac: first impressions

Genutic's Pulse is a new product aimed at making Eclipse installation simpler. The original Eclipse distributions were notoriously complex, which created a fertile ground for 3rd party distributions. Pulse was released a couple of months ago, but was out of scope for me, as a Mac user. Now, a Mac version is out and it's a chance to see how it works.

Pulse In General
Eclipse distributions improved over the years. It's very easy to download and install Eclipse from eclipse.org. It becomes more complex once you start customizing your Eclipse with plug-ins. I have many plug-ins and it would take me up to several hours of attended installation to be up and running in case I will need to reinstall my environment. The idea of having a simple and automatic process that does it for me sounds great.

However, that's not exactly what happens with Pulse. In Pulse you're limited to a set of plug-ins which were determined by the Pulse team. Pulse becomes a de-facto distribution channel for downloading and buying plug-ins. It's like iTunes for Eclipse plug-ins. iTunes is slick, cool and, best of all, free to download. But at what cost?  At the cost of creating a new monopoly that controls the music industry. That's not something we want around the Eclipse community.

Don't get me wrong, I don't think that's going to happen. The music market is very different from the Plug-ins market. However, it is my opinion that the catalog should be open to embrace whatever plug-in I desire. Otherwise, there are other solutions on the market to fill that purpose like Tikal Update Manager.

Pulse for Mac
The main download is a 2.1 MB disk image (DMG). It holds a Pulse.app file which is actually an installer. In most Mac DMGs you either get an app, which you drag into the applications folder, or an installer package, so this is unorthodox to say the least. After launching the application, it will start downloading and installing Pulse into the applications folder. The installer sets up a folder called "Pulse" inside your applications folder and installs the Pulse launcher inside the folder. The launcher is 2.1 MB, so I don't see why I had to wait for another download.

The installer is OK. It's not the standard Mac installer, but it looks fine. You can choose a standard profile or go to the full "Pulse Explorer" where you can see available profiles and build your own. The UI is based on Eclipse RCP. It is slow, since it incrementally downloads information. It is also a bit buggy and erratic, but keep in mind that this is still a beta version.

Once you finished building your profile, you can now execute it. Pulse will download and install the necessary files. The download is fast with up to 8 simultaneous connections. Eventually, it launches Eclipse and you're good to do. All the plug-ins are configured correctly and you can start with the actual work immediately. At the end of the day, Pulse delivers and saves you the time.

The Pulse plug-in stays inside your environment, so you can update and modify your configuration at any time. Checking for updates is very fast compared to the Eclipse built-in update manager. When adding and removing features, the best approach is to modify the profile and restart the workbench. The changes are done upon launch. It took me some time to figure this out, though.

Some little annoyances I came across:

  • After the first setup of my Pulse profile, a launcher was not created. I had to launch Pulse again and then it was created.
  • It executed Eclipse by executing Java, which is different than running the Eclipse.app package. On the Mac, this means you get "Java" on your dock (it does show the Eclipse icon). However, you cannot "dock" it (keep in dock), since you'll be docking "Java" and not "Eclipse". You can put the Pulse Launcher on the dock, but then it will launch Java and quit. It's counterintuitive to the native Mac environment and the original Eclipse distribution behaves better.
  • It adds a "Pulse" menu, which just clutters the menu bar. It could've been added to the help menu, where the native update manager sits. Luckily, you can just turn it off by customizing the perspective.

Summary
I'm not the target audience for Pulse. I'm an individual developer and I like to be able to pick my plug-ins from all over the net. Is it for large teams?  Well, when I was working with a large team of Eclipse developers we had a rather simple way of "distribution" - copying files from the server. This is one of the major advantages of Eclipse: you can install it by a simple copy operation. Another issue is that most large corporates have their own, in house developed, plug-ins. You cannot add these to the catalog. It can be a good start for a novice developer, making the first steps in the Eclipse world. However, in this case, the Eclipse distributions are mature enough to use directly.

Bottom line: other than a few glitches, Pulse is a good product that has a potential of saving time. I just wish Genuitec would be smart enough to open it up. This would give it a broader appeal.

Dec 12, 2007

Tracing Java execution using a Dynamic Proxy

In my previous post, I discussed five ways for tracing Java programs execution. Tracing execution can be done from a number of reasons. I focused on understanding the code. While it may be easy to read and understand a single method, understanding the whole flow may be a tough challenge. Since most design time tools fail to show a full end-to-end flow, tracing the program execution is the next best option.

I summarized my post with a conclusion that working with Aspects is the best option. I'm going to touch that in one of the next posts. In this post, I will introduce another approach: Dynamic Proxies. Although this method has its' limitations (see below), it is very easy to set-up and use.

What is a DynamicProxy?

DynamicProxy is a cool feature in Java. Most novice Java developers are not familiar with it. You can find the official tutorial here. I'll give a shorter one, focusing on tracing. The following diagram illustrates how it works:

Dynamic Proxy

  • Step 1: Client invokes Method A, which is part of an interface.
  • Step 2: The Dynamic Proxy intercepts the call, receives a call to a generic invoke method. This is the magic sauce.
  • Step 3: The dynamic proxy invokes the original method using reflection, along with more logic, e.g. logging the call.

There are two supernatural phenomena here:

  • You have a class which can take any shape - each instance of the class can decide, at runtime, which interfaces it will implement.
  • When the instance receives a call through any of these interfaces, it will actually receive a call to one invoke method with all the relevant details: the method which was invoked and the arguments.

Other than the above, it's all plain Java code which you control.

There are some limitations to dynamic proxies, derived directly from the way they work:

  • The invocations you're tracing must be part of an interface. If not, you'll need to extract the interface. Still, even if you do, it will only work for public methods invoked by outside callers.
  • You should control the instantiation of the target class' instances. It should be intercepted and replaced with your own instances.

The Debug Proxy

Sun provides an example of tracing using dynamic proxy. I made some modifications to the code and I'm attaching my own version of a DebugProxy. The main limitation in the original code is that it proxies only the immediate interfaces implemented by the original class. If the class extends a super-class which implements an interface, this interface will not be "proxied" (is that a word?). I also made some more modifications:

  • Used Apache commons logging to do the actual logging. The logging is done "on behalf" of the original class in trace level only.
  • Logging all the method arguments using toString.
  • Correctly throwing exceptions: will throw the original exception that occurred.
  • Using Java 5 features (Generics, for each loops, etc.).

You can download the file here: DebugProxy.java.

Using the Debug Proxy

First, download the DebugProxy and install it in your project. You may need to fix the package definition. If you're not using Commons Logging, you may want to change that as well.

Next, change the instantiation on your class. Here's the example:

  • Original code: MyInterface obj = new MyClass(...)
  • New code: MyInterface obj = (MyInterface)DebugProxy.newInstance(new MyClass(...))

That's it. You're all set. Just execute the program and check the results in the log. After the first time, you will have your proxy in place and the whole process becomes even simpler.

Conclusion

Using a DynamicProxy to trace runtime execution has several advantages:

  • It's very simple to set up. It's laser-targeted at the class which is interesting at the moment, ignoring the rest of the system.
  • You control the code, hence, you have the ultimate control on the way the events are logged. You have all the information and you can log it in any way you see fit. You can even set up a breakpoint inside your debug proxy and intercept all the calls.
  • Not much overhead on the system at runtime.

Of course, there are the limitations:

  • The intercepted calls must be made through an interface.
  • You need to control the instantiation of the original class.

Overall, it's great for specific cases, like understanding which events were received by an Event Handler and when. In the general case, you'll need to find another solution.