.::output >> /dev/null::.

where otherwise good ideas go to waste

Making Objective-C Land More Habitable

Posted by Nicholas Chen Thu, 17 Dec 2009 21:58:00 GMT

Over these past few months, I have been working on a long-term class project using OS X technologies in both Objective-C and Javascript. Overall, the experience was pretty good (except for the Javascript part) -- and I suspect much easier compared to having to use Java. Using Java would require us to hunt down various libraries and then filter through them since there are probably 10++ different libraries for each thing that we need to do. So using OS X was a good choice.

However, there are a few tools that I wished I had known earlier....

GHUnit

Unit testing using Cocoa is pretty complicated. In fact, it's unnecessarily more complicated than Java, Ruby or Smalltalk. It's only less complicated than unit testing C++ (which doesn't say much)! There are two things that particularly irk me:

  • Not seeing green/red! - You have to actually read the text in the build log to see which of your tests pass and fail. This is completely ridiculous - it's so easy to miss a failing test case because of this. Anyone who has used the Xunit testing framework family is accustomed to seeing green for passing tests and red for failing tests.
    A Failed Test Logged in the Xcode Build Results Window
    A Failed Test Logged in the Xcode Build Results Window

  • Not being able to debug your unit tests - You have to perform some boilerplate steps on your own. Such steps should be automated for you!

Fortunately, GHUNit comes along. And at least solves those two problems. It has become my choice for unit testing in Cocoa and all my future projects will use it. It's released under a very liberal open source license so using it in your own project shouldn't be a problem. Apple and the Xcode team should integrate this directly into Xcode.

GHUnit in action
GHUnit in action

F-Script

The cocoa libraries are nice. But sometimes the documentation can be a bit confusing. So, the best way to find out what a method or class does it to write some code for it and try it out. But honestly, would you like writing a small program each time to try a method or class out?

That's when you need F-Script which allows you to call run Objective-C like you would run a scripting language. Need to find out how that NSString method behaves? Just type in into the F-Script REPL workspace. You can even play around with Core Image easily in the F-Script workspace!

GHUnit in action
F-Script shell in action

But wait! F-Script has even more to offer. Using F-Script Anywhere allows you to inject the F-Script environment into any Cocoa application. That way you can quickly figure out and play around with other people's application!

The only thing you need to do is spend about 20 minutes learning the F-Script syntax which is very similar to Smalltalk's - so it only took me about 5 minutes.

Clang Static Analyzer

One area where Java really shines is the abundance of high-quality tools for static analysis. Using these tools allow you to avoid a lot of silly mistakes before you even compile or run your Java code.

Previously, Objective-C was definitely lacking in this area. However, the Clang Static Analyzer hopes to change that. In fact, if you are using the latest version of Xcode under Snow Leopard, it should be integrated already. Here's the static analyzer in action:

GHUnit in action
Uninitialized Variable Error

For our particular project, we needed to use OS X Leopard so followed these steps to get the static analyzer to work. Even though it took a few more steps, the extra trouble is worth it since it catches a lot of garbage collection issues that we might have missed otherwise.

The Clang Static Analyzer is based on the LLVM compiler infrastructure developed here the University of Illinois at Urbana-Champaign.

BWToolkit

Interface Builder is awesome. It definitely beats any other interface builder that I have tried. However, it can be too basic at times. It works very well, if you are doing a simple UI. But it lacks the palettes for some of the more advanced (but pretty commonplace) UI that you see in Mail.app, iCal.app, etc.

That's when BWToolkit comes in. It offers a plethora of different palettes which makes designing your UI extremely easy. And you can use all of them using drag-and-drop from Interface Builder.

BWToolkit
BWToolkit's suite of controls for HUD windows

It's released under the liberal BSD license so you don't need to worry about using it for your projects. GHUnit itself uses it and that's actually how I discovered this wonderful toolkit.


Overall, OS X has a lot to offer in both libraries and tools. And when it falls short, some other developer out there is usually passionate enough to create and share their tools with you. It just takes too long sometimes to find those tools. So hopefully, this list will be useful to some other aspiring OS X developer.

Posted in , | 5 comments |

Modifying plugin.xml of Existing Eclipse plugins

Posted by Nicholas Chen Mon, 12 Oct 2009 00:10:00 GMT

I have been taking a deeper look at Mercurial for some of my projects. And I was interested in looking at its source code. I usually do a lot of Java development and have gotten used to all the nifty navigation features that Eclipse/NetBeans/IntelliJ have to offer such as "Jump to Declaration", "Open Type Herarchy", etc. So I wanted to find a good IDE for going through the Mercurial source code, which is written in Python. Apparently, there isn't a de-facto IDE for Python. But PyDev comes close.

Unfortunately – I am not sure whether this was intentional or not – the keyboard shortcuts for PyDev aren't very platform friendly. Instead of the default modifier key (Ctrl on Windows/Linux and ⌘ on Mac) the developers have hardcoded the modifier to Ctrl for all platforms. So to invoke the I would have to use Ctrl + Shift + T instead of ⌘ + Shift + T.

So how do we change the keybindings? Well, there is an extension point in the Eclipse plugin architecture for specifying the keybindings. Take a look at org.eclipse.ui.bindings And those keybindings are stored as plain text in a plugin.xml file. For PyDev, it would be in the plugins folder of your Eclipse installation. In my case, it was under eclipse-galileo/plugins/org.python.pydev_1.5.0.1251989166/plugin.xml

So we can edit the plugin.xml file by looking for the

      ...
      <key
            sequence="Ctrl+Shift+T"
            contextId="org.python.pydev.ui.editor.scope"
            commandId="org.python.pydev.editor.actions.pyShowBrowser"
            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
      </key>
      ...
and changing the Ctrl to M1 which stands for the default modifier key on your platform i.e.
      ...
      <key
            sequence="M1+Shift+T"
            contextId="org.python.pydev.ui.editor.scope"
            commandId="org.python.pydev.editor.actions.pyShowBrowser"
            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration">
      </key>
      ...

Unfortunately, we are not done. And it took me some time to figure out the problem. Apparently, Eclipse doesn't read the plugin.xml every time. Instead, it caches a version of it somewhere. So even if we modify the plugin.xml, Eclipse might not know about it.

What we have to do is to tell Eclipse to clean its cache. And we can do that by using the -clean option in its eclipse.ini file. On the Mac, this file in located in Eclipse.app/Contents/MacOS/eclipse.ini (you need to right-click on the Eclipse application and select "Show Package Contents").

Change the first line so that it read something like this:

-clean
-startup
../../../plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
--launcher.library
...

Now when Eclipse starts up, it will clean its cache and read the newly modified plugin.xml file. Once we are done with this step, we should remove the -clean option since this causes Eclipse to start up slower. And who would want Eclipse to start up any slower than it already does?!

And this is what the keybindings look like after the changes:

PyDev with Mac-friendly Keybindings

Posted in , |

Hacking Lua (in Xcode)

Posted by Nicholas Chen Sun, 15 Feb 2009 21:03:00 GMT

I have always been fascinated by application virtual machines. And I have been trying to find a simple but well-documented one to work on for fun. There is a proliferation of Javascript VMs out there but they are pretty big (V8 is the latest kid on the block and it's about 100 000 lines of C++, not my favorite language) and aren't as well documented.

There are some smaller ones like tinyrb and tinypy but the goal of such projects aren't really clear. I am not sure how much of Ruby/Python they are trying to support. They are great for hacking on if you have some experience with VMs already and can contribute to the design/implementation. But otherwise, it can be pretty hard to comprehend what is going on.

Both tinyrb and tinypy did mention that they were trying to emulate the Lua VM. So I decided to check it out. The Lua VM (like the Parrot VM) is a register-based VM, which is pretty unusual since most VMs are stack-based. Its use of registers instead of a stack makes it more fascinating to study.

And I like what I have seen so far. There is good documentation on multiple levels: the language itself, the architecture of the VM and plenty of examples. Also, the code is in C which is less messy than C++. The Makefile is simple and isn't using any cryptic tricks. And Lua itself seems like a simple language to learn.

So my plan is to dive into the source for Lua and then see what can be done to improve tinyrb. But first, I need to set up an environment to develop in.

I could certainly continue to use vim/TextMate, but I have been using Xcode more because I am doing some iPhone development and have gotten use to some of its features. And I like its built-in debugger which saves me from having to interact with gdb directly for the common tasks. In fact, I am not sure if there are better C/C++ IDEs for OS X. The Eclipse CDT project is the closest that I can think of but I haven't used it much.

So here are my steps for doing this: from getting the source into Xcode and also starting a debugging session. I am using the All-in-one look for Xcode so your UI might look different.

Grab the source for Lua-5.1.4 from http://www.lua.org/ftp/lua-5.1.4.tar.gz. Unarchive it. For this article, I will be unarchiving it in ~/Xcode.

Create an External Build System project

Fire up Xcode and create a new External Build System project. I called my project Lua. You can put the project wherever you want. It doesn't need to be in the same directory where you unarchived the Lua source code since we will be referencing the source files anyway.

Add the existing Lua files

Right-click on the project and add the entire directory where you unarchived the Lua source code. In my case it would be ~/Xcode/lua-5.1.4.

After adding the files

This is what it looks like after adding all the files.

Make changes to the Makefile for OS X

Next, we need to edit two of the Makefiles. First, we need to edit the top level Makefile in ~/Xcode/lua-5.1.4. Change line 8 to PLAT= macosx since we are targeting the OS X platform. Then, we need to make changes to the Makefile in ~/Xcode/lua-5.1.4/src. Change line 17 to MYCFLAGS+= (we want the + symbol). Change line 108 to $(MAKE) all MYCFLAGS+=-DLUA_USE_LINUX MYLIBS="-lreadline" (again, we want the + symbol). In fact, by default, it should have the + symbol so that we can easily accumulate our own settings. I suspect that this is a careless omission in the Makefile for Lua.

Changing the parameters of the Lua target

We need to make some changes to the Target configuration for our Project. So navigate to the Lua target in your Groups & Files (it's the left navigation pane). And double-click the Lua target. Then edit it so that it resembles the image above. Notice the line that says "Settings show Debug" near the top of the window; we are changing the settings for Debug (and not Release).

You need to change the directory to the location where you unarchived the Lua source so that it can find the top-level Makefile.

Then you need to add a new build setting, MYCFLAGS so that we can pass the -g flag (for debug) to the compiler. Without this flag, we cannot debug our program effectively with the debugger (it doesn't have all the necessary debugging information).

The result of the build (for debug)

Now we can build our project by going to Build > Build. And notice that we are building for the Debug configuration i.e. on the menu item at the top it says 10.5 | Debug | i386. The settings that we made for our Lua target are reflected in the output of the build e.g. gcc -O2 -Wall -g .... (the -g flag that we specified in the settings).

Executing Lua in the command line

Now that the project builds, we can proceed to debug it (or rather we just want to step through its execution in the debugger to find out how it works). The image above shows how we would run that executable (notice that we are passing some arguments to it). We want mimic this and run the program in the debugger.

Create a new executable that you can launch from Xcode

So we create a new Custom Executable. We call it Lua.

Parameters for Lua custom executable

In the dialog that pops-up, remember to specify the location of the lua executable (you will only have it after you have built the project).

Don't load symbols lazily

Before we can debug the lua executable, there is one more setting that we have to perform: change the way debugging symbols are loaded. So, open up the preferences for Xcode, and switch to the debugging tab. Ensure that the "Load symbols lazily" is unchecked.

Build and Debug your program

Now we need to set a breakpoint. Notice in the image above that I have set one on line 378 in the lua.c (Xcode/lua-5.1.4/src/lua.c) file. After that we can invoke the debugger from the Build > Build and Debug menu.

Debugger in action

And finally we have our debugger in action.

The steps above are applicable for any other external project that you need to work on (sans the modifications to the Makefiles since that is Lua-specific).

Posted in , | 1 comment |

Session restore (sort of) in Eclipse with Mylyn

Posted by Nicholas Chen Sat, 02 Feb 2008 22:59:00 GMT

This was something that I really wanted to blog about for a long time...

Last year I wanted to know a way to save sessions in Eclipse like I could for Firefox. For instance, Firefox allows you to save the open tabs and windows into a new session and restore that session in the future. That way if you ever need to recall a set of tabs for reference, they can be easily activated by restoring the saved session.

In fact, any decent, editor or IDE should the option to save sessions. Heck, Vim and Emacs have this feature out-of-the-box. Sessions are really useful when you have to work on groups of related files at the same time but don't want to have to remember which they are.

So why was there apparently no way to do this in Eclipse? Initially, I thought that Working Sets might be the solution. However, they only allowed you to group files into sets. They don't actually remember the editors that are opened and what state you were in. So Working Sets were not even a poor man's implementation of sessions.

Then epiphany struck! We could use the Mylyn plug-in to accomplish this. In fact, as you shall see, Mylyn can do even better than just saving sessions - it infers them automatically based on what you are doing! Mylyn comes installed standard now on Eclipse 3.3 and higher. In fact, the Mylyn view is even shown by default; it's not activated though.

Anyone who does not use sessions has a) an incredible memory, b) an inhumane ability to do context switching between tasks AND c) the luxury of not having to close his IDE ever. Or the developer just doesn't know that such an excellent tool exists out there...

The Mylyn View
This is Mylyn
I have readjusted my perspective a bit so that everything can fit nicely in a 800x600 window. The picture above shows the Mylyn view with some sample local tasks.

Activate a previous context
Activating a previous session
I am activating a previous session. By default, Mylyn automatically remembers the last context that you were in before closing the editor and will restore that.

The editors from a previous context are restored
Previous session restored
You can see that Mylyn remembers the files that were opened in that session and has restored them in the editors. The current active task (see the Task List view) has a blue bullet next to it. In the Package Explorer view, you can even see the other files that I might have referred to in a previous session but did not open in any editor.

Creating a new local task
Creating a new local task (context)
Mylyn allows you to create local task for your own use. With the proper server, you can also create sharable tasks in a Bugzilla or JIRA repository. That way, you can share the same session with yourself when you are working on a different machine or with your other teammates so that they can take a look at the same things that you are looking at.

Editing a local task
Editing a local task (context)
You can easily associate other metadata with each task. In fact, Mylyn was originally created to be a task-oriented system. It allows you to split your work into little tasks to help you focus.

Reveal all files or focus on active task
Deciding to show everything or just the active task
You can easily switch between showing all the files in the Package Explorer or focusing on the active task by clicking on the Mylyn button.

Mylyn has a whole bunch of other features. Some of the interesting ones include:

  • The ability to share a context with different tasks. You can clone the current context and paste it into a different task.
  • It cleverly remembers what editors and files that you have accessed and stores those into its session.
  • It intelligently forgets editors and files that you have not looked at for extended periods.
  • You are always in control - you can override the behavior easily and promote/demote certain files from sessions.
  • It records how long you spent on each task so that you can actually report that figure with certainty.
  • It's well integrated with different perspective and views in Eclipse. And it is constantly being improved upon.

Mylyn is great for helping you focus on your programming tasks. It stays out of your way for the most part but is easily accessible when you need it. Once you start using it, you really wished that every IDE out there (including the venerable IntelliJ) supported it.

Posted in , | no comments |

Why tools can make it a pleasure to learn a new framework

Posted by Nicholas Chen Tue, 15 Jan 2008 19:23:08 GMT

I was reading the book Spring In Action in my attempt to learn about Spring. More importantly, I needed to know enough to be able to incorporate refactoring support for it as part of my project.

Unfortunately, the book had some typos which were actually technical errors. And this was just in Chapter 1! If you are trying to learn something for the first time and there are typos, you might not be able to detect it. And this can lead to hours of frustration....

Fortunately, IntelliJ has support Spring. And it detects the errors for you! So even if the technical reviewers did not detect the error, at least your IDE (a good one) can do it for you and save you time.

Error detection
IntelliJ 7 has support for Spring. In this case, it detected that something was wrong with the xml configuration file.

Error correction
It even offers the ability to correct the error!

I wonder if the error in the book could have been detected had the reviewers use a better tool. Or at least attempt to run it using some automated tool.

Posted in , | no comments |

Convention Preserving Refactorings

Posted by Nicholas Chen Thu, 18 Oct 2007 01:55:10 GMT

Refactoring Dynamic Code:

"These tools, along with the relatively small amount of Ruby code required to implement the desired features, made life easy during the first few iterations. With each new feature, however, the amount of refactoring required to keep the codebase clean increased. Although Rails' adherence to the DRY principle helped reduce duplication, each refactoring had to change numerous code artifacts. Some of the changes, admittedly, were needed to keep the code in line with Rails' convention-over-configuration philosophy.
Renaming an entity class, for instance, requires renaming the corresponding database tables, including other columns and indexes referencing the model's table, renaming the model class, changing the corresponding controller, helper classes, and every reference to the entity class in the views, as well as renaming the directory containing the view classes and templates. And, of course, you have to similarly rename the associated tests and all references to the model, controller, and views in the tests and fixtures."

One of the advantages of being under Prof. Ralph Johnson is that we are indoctrinated to think of programming as a series of program transformation. From the humble HelloWorld program (just think of when you are reediting the program to add some comments or change what gets printed out to the console) to more complex programs out there, almost everything can be viewed as a series of transformations.

Refactoring is as a form of program transformation. Refactoring is a process where you restructure your code without affecting its observable behavior -- where behavior is defined pretty loosely. Why would anyone want to do something like this? If you have never done refactoring before this might seem like a worthless task. After all, if you aren't modifying the behavior of the program, you aren't adding new features to it. And features are what the customer cares about, right?1

Well, turns out that you refactor to make your code easier to understand. Code that is easier to understand is also easier to modify. So essentially, refactoring helps prepare your program for the next feature, and the next feature, and the next feature... that you want to add; making those features easier to add.

Certain refactorings can now be automated through an intelligent IDE. And IDEs have generally done a very good job of it -- until you being to cross the traditional language barrier. For instance, look at Rails. Rails is a framework that relies on Ruby, erb, Javascript, SQL, etc. When you perform a refactoring on your Ruby code does that refactoring percolated correctly through the entire program? If you rename a method in your Ruby code, will it change the name of the method to the new one everywhere that it was called before? Would it also be able to change the method call inside the erb file?

Furthermore, because Rails relies on the convention-over-configuration idea, it is desirable that your refactoring preserves those conventions as well. So now, your refactoring tool not only needs to know Ruby but it must be configured to understand the Rails framework itself! Renaming your Rails model should also make the appropriate changes to the controller and your erb file just because the framework expects them to be related by name in a predetermined manner. Failing to do so would actually cause your program to fail.

If another framework comes along, your tool has to be taught to function for that framework too. And a programmer might choose to use numerous frameworks together. How would you ensure that the refactoring tool would work for any combination of frameworks?

The point of this post is to illustrate the need for multi-language refactoring support. We can think of complex frameworks as basically an extension of the language itself. Frameworks have their own set of conventions to be followed. Following those conventions is essential for a framework such as Rails. For other frameworks, following those conventions would be desirable to make the code easier to reason about.

So the main challenge is how to capture those rules that a framework specifies so that our refactoring tool can understand them and make the appropriate changes toward the entire code base.


1 You can actually think about adding features as another form of program transformation but it is not really viewed as a refactoring since adding a feature is not behavior preserving.

Posted in , , | 2 comments |

Metrics and Code Coverage in Eclipse 3.3 Europa

Posted by Nicholas Chen Sun, 30 Sep 2007 23:50:44 GMT

This is actually something that I spent two days on trying to get to work properly. There were a couple of variables that made this harder than necessary: the documentation on getting the latest version of Photran to compile was a bit out-dated (we need the latest version of the CDT from HEAD for the tests to run) and the fact that we are switching to Eclipse 3.3 which might not work well with all the plug-ins out there.

The plan was to run some metrics and code coverage measurements on the Photran code base. Using the data that we gathered we could evaluate sections of code that needed refactoring and/or testing. We could only use free tools since we wanted the students to be able to run them on their own computers. Naturally, if we did not have this major restriction we would have chosen some better commercial tools.

The State of Flow Metrics was the first one I tried but it does not do a good job. The UI and visual feedback were so bad that I did not even know if it was working. So, I ran the tool on a smaller project; it completed the analysis. However the information it provides is not presented intuitively. Instead it adds a little icon on the left margin of the editor that does nothing more than indicate that it had analyzed that method. Then the data is presented in the Problems view along with all the other errors and warnings. For small projects, this is fine but for larger ones with 100s (or 1000s like the CDT) of warnings, you cannot even determine which are warnings from the metrics tool (vs warnings from the Java compiler). So this is pretty much useless for large projects or workspaces with 1000s of warnings. It has an export feature that is supposed to export the data to HTML and CSV forms but it refuses to complete for me.

The second metrics plug-in I tested was much better. It had failed to work the first time I used it because it was not able to access the data that it had collected from the analysis. However, after upgrading to the latest version of Eclipse 3.3 (Version: 3.3.1 Build id: M20070921-1145) this problem vanished.


Metrics view using the Metrics Eclipse plug-in

So, now we needed a code coverage tool or more specifically one that could analyze the tests that have been written for Photran. This is slightly more tricky. We need code coverage tools that can measure coverage on JUnit plug-in tests (vs the normal JUnit tests). JUnit plug-in tests must launch an instance of Eclipse to successfully execute to completion. So a majority of the test coverage tools mentioned here cannot do a decent job.

For instance, in Photran, if you just ran the normal JUnit tests there are only 125 such tests vs 1566 if you run the JUnit plug-in tests. So the coverage is going to be low for the former execution.

There was only one free tool that I could find that offered support for measuring JUnit plug-in tests: EclEmma. The first time I installed EclEmma it corrupted my entire workspace and I had to restore everything from the repository. I installed EclEmma again today on the latest version of Eclipse 3.3 and I think I know the proper way to invoke it so that it will not corrupt the workspace: always create two different run configurations and never mix them. So, when running the Photran, you should always create 2 configurations — one that EclEmma will run and one that normal Eclipse will execute without coverage. And the workspace should also always be cleaned after running EclEmma.


EclEmma code coverage in action.

I believe that the Eclipse update fixed something to make EclEmma work properly on Mac OS X. Yesterday, there was no clean separation of an EclEmma run-time from a normal run-time. In fact, both of them were always merged in the same dialog. This could be why the workspace was being corrupted since EclEmma's instrumentation was replacing the normal ones.

Bottom line, if you want to a good metrics and code coverage tool, go with the Metrics and EclEmma plug-ins. Of course, if you can afford it, go for a commercial tool like Clover.

Posted in , | no comments |

Setup Struts project in Eclipse - more choices than necessary

Posted by Nicholas Chen Fri, 27 Jul 2007 22:26:56 GMT

One would expect that that given the popularity of Eclipse that there would be an easy way to setup Struts with it. However, this does not seem to be the case. There are various resources on how to use some non-standard Eclipse installation (EasyEclipse, MyEclipse) or some outdated plug-in (StrutsConsole, EasyStruts). But it is really hard to find one on how to use a standard Eclipse installation. The definition of what is a standard Eclipse installation is debatable since there are just so many different combinations of it.

In fact, here is a list:

However, in my case, I would like just like to use a simple installation that just enables me to launch my Struts application from within Eclipse. I don't really need any of the more complicated features. If I needed those features, I would be using IntelliJ which has great integration with Struts (and almost everything else that you usually use Java with e.g. Hibernate, Spring, etc) built-in.

Fortunately, I found this thread after some searching. The instructions are a bit terse but you can definitely follow along with some trial and error. Just make sure that you have one of the supported servers installed. In my case, I was using the Apache Tomcat server but there are adapters for other servers as well. Also, make sure that you follow (or to be more specific, obey) the folder structure imposed. It's a pretty conventional and there should not be a reason to not put things in their recommended folders.

All that is required is to have the Web Tools Platform (WTP) plug-in installed. My past experience with installing the Web Tools Platform had me downloading a whole bunch of required plug-ins before it could work. Needless to say, it was not a pleasant experience. So I was happy to see that they have released all-in-one package for the WTP project here. This is definitely a time-saver. The WTP is a comprehensive project that is maturing toward the usability and stability that one associates with the Eclipse Java Development Tools (JDT).

Now that everything is working - after much time-wasting - I believe that I have reconfirmed my view that having too many choices is not always good! It's really annoying when all you are trying to do is get some prototype up quickly and you are not able to do that because you have to make a decision between product A, B or C. Sure you can go ahead and read the comparisons and user reviews but most of it is not going to make that much sense to you if you have never used similar products before. And the reason you have never used them before is because you are just beginning to create your first prototype!

I find the situation of having too many choices to be really prevalent in the Java world. I am not against having different choices but I know that when I am just beginning to use some new tool, I would really like everything bundled together so that it just works out of the box! I don't want to select product AA only to be told that before I can use product AA I need to install either product A.1 or product A.2! Just give me a working combination that I can quickly use to see if my prototype can even work in the first place!

And don't get me started on the XML configuration files that are necessary before you can begin running that Java application....

Posted in , , | no comments |

Setup Struts project in Eclipse - more choices than necessary

Posted by Nicholas Chen Fri, 27 Jul 2007 22:26:56 GMT

One would expect that that given the popularity of Eclipse that there would be an easy way to setup Struts with it. However, this does not seem to be the case. There are various resources on how to use some non-standard Eclipse installation (EasyEclipse, MyEclipse) or some outdated plug-in (StrutsConsole, EasyStruts). But it is really hard to find one on how to use a standard Eclipse installation. The definition of what is a standard Eclipse installation is debatable since there are just so many different combinations of it.

In fact, here is a list:

However, in my case, I would like just like to use a simple installation that just enables me to launch my Struts application from within Eclipse. I don't really need any of the more complicated features. If I needed those features, I would be using IntelliJ which has great integration with Struts (and almost everything else that you usually use Java with e.g. Hibernate, Spring, etc) built-in.

Fortunately, I found this thread after some searching. The instructions are a bit terse but you can definitely follow along with some trial and error. Just make sure that you have one of the supported servers installed. In my case, I was using the Apache Tomcat server but there are adapters for other servers as well. Also, make sure that you follow (or to be more specific, obey) the folder structure imposed. It's a pretty conventional and there should not be a reason to not put things in their recommended folders.

All that is required is to have the Web Tools Platform (WTP) plug-in installed. My past experience with installing the Web Tools Platform had me downloading a whole bunch of required plug-ins before it could work. Needless to say, it was not a pleasant experience. So I was happy to see that they have released all-in-one package for the WTP project here. This is definitely a time-saver. The WTP is a comprehensive project that is maturing toward the usability and stability that one associates with the Eclipse Java Development Tools (JDT).

Now that everything is working - after much time-wasting - I believe that I have reconfirmed my view that having too many choices is not always good! It's really annoying when all you are trying to do is get some prototype up quickly and you are not able to do that because you have to make a decision between product A, B or C. Sure you can go ahead and read the comparisons and user reviews but most of it is not going to make that much sense to you if you have never used similar products before. And the reason you have never used them before is because you are just beginning to create your first prototype!

I find the situation of having too many choices to be really prevalent in the Java world. I am not against having different choices but I know that when I am just beginning to use some new tool, I would really like everything bundled together so that it just works out of the box! I don't want to select product AA only to be told that before I can use product AA I need to install either product A.1 or product A.2! Just give me a working combination that I can quickly use to see if my prototype can even work in the first place!

And don't get me started on the XML configuration files that are necessary before you can begin running that Java application....

Posted in , , | no comments |

flickrPreviewR

Posted by Nicholas Chen Mon, 16 Jul 2007 17:02:00 GMT

For the past couple of days I have been creating an application that I think I would use. And maybe some other people might find it useful too (possibly as an example for doing things in RubyCocoa). For the lack of a better name, I decided to call it flickrPreviewR and hopefully I would not be sued.

flickrPreviewR
flickrPreviewR screen. It even has the typical flickr logo design from flickrlogomakr. The line to the right is the the side of a window that apparently shifted a bit to my other screen and included in the image capture.

It all started when Flock released a new version of their browser sometime last week. I downloaded it since I was eager to see what the perpetually-in-beta browser has created this time. This time I was really disappointed. The only reason for my using Flock was its integration with Flickr. I just like to quickly browse photos without having to use Flickr's interface. Unfortunately, this new version of Flock really left a sour taste in my mouth. Its interface is hideous and the newly revamped Flickr integration seems buggy and really slow. What does it need to do that requires that much computation power? It just needs to fetch the damn photos damnit!

Anyway, this provided the motivation and gave me another reason to play with RubyCocoa. The last time I dabbled with RubyCocoa, I created a version of the RaiseMan application from the book Cocoa Programming for Mac OS X with bindings. Since then, RubyCocoa has had additional changes and I was curious whether it is now easier to develop programs for it. My conclusion: nothing much has changed in terms of the cosmetics of language (there are underlying changes for optimizations, etc), but overall there was nothing new to pick up.

For the backend of this application, I relied on rflickr, the Ruby API kit for accessing flickr. I needed to make some slight changes to the code to accommodate some changes in the flicrk API. rflickr source is bunbled as part of the source code. I did want to not rely on it being a gem since I am not sure how RubyCocoa handles gems and I did not want to add a dependency for the gem; so I just bundled it. flickrPreviewR is under the Creative Commons Attributions License. This might violate the rflickr license and if it does, then let me know and I will see what I can do.

You can find the set of images on my flickr account. I do not have a pro account so I cannot create a set for it. You should read the description of each photo if you are planning on using this. As usual, use this at your own risk. I am doing this as a personal application that I would use and as the developer, I am aware of its limitations and I do not push them while using the application.

One very important limitation that I need to stress is the inability for it to update itself.

There is a weird quirk with using threads in RubyCocoa and NSNotifications. I have not figured out how to get the view to refresh once all the images have been downloaded. Right now, there is the VERY cumbersome need to click on ANOTHER favorite or photoset to force a refresh. The best way to see if the photos have finished loading is to view the progress bar at the drawer.

THIS NEEDS TO BE FIXED once I figure out how.

Here are some things that I picked up while doing this:

  • Interface Builder is a great tool for quickly laying out the interface. I cannot imagine how I would have done this with some other GUI toolkit. Even with my familiarity with Java, it would taken much longer just to get all the pieces aligned properly.
  • CocoaDev is the site for almost all the questions that you can have on how to do things in Cocoa. Without CocoaDev, it would have taken me a longer time to get things done.
  • Cocoa Programming for Mac OS X is a decent reference book once you know your way around how certain things in Cocoa work. That still does not make it a good book to start learning Cocoa programming.
  • You can save yourself great pains if you make all your classes subclasses of OSX::NSObject explicitly instead of normal Ruby classes. This will save you trouble when you get weird behavior and crashes. Like me, you might want to use normal Ruby classes sometimes because YAML works well with the regular Ruby classes. In that case, make sure that your class is being used as simple data structure with simple functions that do not rely on any of the Cocoa libraries.
  • Threading is hard to do with RubyCocoa and there is little reference on what works and what does not.
  • Downloading images with Ruby net/http library did not work for me. The image will always end up corrupted. Thus, I had to rely on curl to download the images.
  • WebKit is an excellent piece of work. I used it as the primary backend for displaying the images. To intercept the handlers, I made each preview image be a link an imaginary 'flickr://' protocol. I then overwrote webView_decidePolicyForNavigationAction_request_frame_decisionListener to intercept the call and perform the appropriate actions.

For those who are interested, the source code is here. I did not package it as a stand-alone application because I am not sure what you actually need to run this application. You probably need RubyCocoa and the Ruby 1.8.5. So for simplicity, I just provided the project folder for XCode. If you can build it then you can probably run it.

Posted in , | no comments |