Tuesday, November 06, 2012

nbnotify.com is back up


I forgot to publish this, but it's been a month since I uploaded a new version of nbnotify.com, the OSX notification plugin.

Based on Bootstrap, this new site is as simple as it gets: all static, a stark contract to the old PHP Wordpress.

I brought the old site down in August because the Wordpress I had there was too insecure.

Right now this plugin is looking a bit old. After all, it needs the original Growl, not the new commercial Growl. Also, OSX Mountain Lion has its own notification API which I do not support yet.

Friday, June 29, 2012

Everything takes time

I read somewhere that as you get older you don't necessarily get slower, you just trade speed for quality. This sounds about right.

Here is my time with an UI regression in the new version of a large Swing app:

I start investigating the problem manually and look at the code to see what might be the cause.

I find a quick way to duplicate it.

I deduce from the code what might be the cause but I'm wrong, it could be that, but it isn't, because there is extra code to check for that condition.

I start probing with a BTrace script to see the Swing events.

I finally find the actual cause and I'm stupefied - it's a failure of an underlying system and not of the UI.

I make an unit test that fails for the regression. I also find a possible fix.

Since I'm a bit surprised by how that system worked, I go and check the problem in the previous version of the Swing app. The problem is not there! It is a regression indeed.

Now I'm really surprised - what changed?

I start debugging the unit test on the old version in order to figure out what behavior changed and I finally figure it out when I look at the diff between the versions.

This diff gives me a 2nd way to fix the code. I patch the new code but it fails subtly in another way -- it wasn't changed for nothing, after all.

I decide that the initial fix is the right one and I apply it.

I am finally done!

At this point my fix was a few lines of code and a large unit test.

But besides this I have various byproducts: the BTrace script, the 2nd fix that didn't work as well as my notes file with my remarks, various stacktraces from the BTrace script and the debugger and errors.

Investigating, writing little scripts, running in various configurations and on top of various versions then finally checking the final fix and wrapping up took a lot of time.

Thursday, June 28, 2012

A Swing window is just as transparent as a web page

I'm a fan of the web and I admire how powerful the browser has become. Since I'm almost always in a browser (even to type this blog) I would certainly love to see even more useful apps, like, perhaps, an online IDE. So, although I work with desktop apps I like this cloud and web app kool-aid a whole lot.

One of the advantages I see in web apps is how transparent they are. It's all text, with code in an easy scriptable language. It's easy to inspect and change. Easy to deploy.

But I don't work with web apps. I work with large desktop Swing applications, usually on top of the NetBeans Platform.

I routinely debug these Swing apps with the debugger, VisualVM, BTrace and simple apps or unit-tests that reproduce the issue.

And it occurred to me after a debugging session to me that Swing apps are quite transparent too! The fact that Java code is compiled is just a decoy. As a developer you have access to the source code anyhow but, even as an user, you have about the same freedoms as you have with a web app.

Just as I could look into the DOM hierarchy in the browser, I have the Swing hierarchy of components.

Just as I could add my own Javascript event handlers, I have Swing listeners.

Although existing code is compiled, I could make a small BTrace script to see its execution and inspect parameters and values.

Without having to recompile, I can easily use reflection to look into private data and even tweak it.

So, although Swing would seem pure binary, there is nothing you don't have access to. It's an open book!

Monday, May 14, 2012

Our own NetBeans Summer of Code

My company is having a Summer of Code for students.

We suggested a list of project that might interest students and we are offering them a paid summer internship to complete their favorite pick.

Since most of what we do touches NetBeans or the NetBeans Platform in some way, a big part of the list is a valid suggestion for the community too.

So, today, we are opening the projects for NetBeans community members too!

Let's see, excluding the items that don't apply, the list has:

#1. Swing based Git Repository Browser

We want this as a standalone app, but it could also be used to enhance NetBeans.

#2. UnQL interpreter

An ANTLR-based parser is needed and a simple UnQL interpreter. This could easily be integrated into NetBeans to provide syntax highlight and perhaps even completion. The interpreter might be just a simple executor or something that visually explores the database.

#5 NetBeans Linux notifications

Just as NBnotify.com displays OSX notifications using native calls, we need something for Ubuntu and Chrome(OS). People seem to want to be notified about long builds and other IDE events and we should provide this natively on more OSes.

#8. Dynamically compiled NetBeans

This is my favorite idea: how about distributing NetBeans only as source code? With some binary bootstrap and a smarter module system I think we could actually have an usable system that compiles everything on demand. Plus -- imagine getting updates as simple text patch files!

If any of these interest you, please contact us! Or email me, tweet me, I'm easy to find.

For a Romanian student we could arrange an internship.

For a NetBeans community member we could provide the resources, mentoring and swag.

Saturday, March 03, 2012

Apple, job creation and the App economy

The Apple job creation page is pure PR: they claim to have "created" or "supported" over 500.000 jobs.

It sounds like the kind of thing a politician would say. Because they even add transportation, health care and "the app economy"!

It's kind of like you claiming to be a job creator because you buy local and burn electricity.

Anyhow, what's interesting is that the App economy is estimated at 210,000 US jobs and Apple has paid over $4 billion to App developers world-wide, ever!

Assuming those $4 billion were all to US app developers in a single year, that ends up to about $19.000 / job in total or about $1600 / month / US developer if that amount is split over 12 months.

What this shows is quite interesting: the App economy isn't self-sustaining.

If the 210,000 US jobs are real then App Store sellers are burning cash.

Considering the money sellers make must follow some sort of distribution then most of those "app economy" jobs aren't even making minimum wage in profit.

Now, one might say: "yes, but those App creators are making money some other way -- perhaps they are giving the apps for free". I disagree. There are few brands that afford to have developers doing apps just so they make money in another way.

If you think about it Apple wants their 30% on every sale you make through the app. That's why the Kindle app removed their Amazon store button.

So it must only be that most of these "jobs" will go away once they realize there is no profit to be made. Or that most of these jobs don't exist to begin with and are nothing more than hobbyists coding after their real job.

It might be just a coincidence, but my company just dropped out of the iOS Developer Program. We were too busy with out other Java-based projects and iOS demand seemed to have leveled anyhow so it made no sense to keep paying those $99/year.

It might just be the start of a trend.

Friday, March 02, 2012

Intellij needs to introduce the Lookup API

I'm looking today at the toolbar classes from IntelliJ IDEA and I'm surprised by the amount of instanceof I see.

For example, NavBarPresentation.getIcon looks like this:

public static Icon getIcon(final Object object, final boolean open) {
    if (!NavBarModel.isValid(object)) return null;
    if (object instanceof Project) return PROJECT_ICON;
    if (object instanceof Module) return ModuleType.get(((Module)object)).getNodeIcon(false);
    try {
      if (object instanceof PsiElement) {
        Icon icon = ApplicationManager.getApplication().runReadAction(new Computable() {
          public Icon compute() {
            return ((PsiElement)object).isValid() ? ((PsiElement)object)
              .getIcon(open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED) : null;
          }
        });
        
        if (icon != null && (icon.getIconHeight() > 16 || icon.getIconWidth() > 16)) {
          icon = IconUtil.cropIcon(icon, 16, 16);
        }
        return icon;
      }
    }
    catch (IndexNotReadyException e) {
      return null;
    }
    if (object instanceof JdkOrderEntry) return ((JdkOrderEntry)object).getJdk().getSdkType().getIcon();
    if (object instanceof LibraryOrderEntry) return IconLoader.getIcon("/nodes/ppLibClosed.png");
    if (object instanceof ModuleOrderEntry) return ModuleType.get(((ModuleOrderEntry)object).getModule()).getNodeIcon(false);
    return null;
  }

That's just horrendous!

What they need to do is introduce a mechanism similar to the Lookup API from NetBeans.

Then, if object is a Lookup.Provider, just call getLookup().lookup(Icon.class).

The above method becomes

public static Icon getIcon(final Object object, final boolean open) {
    if (!NavBarModel.isValid(object)) return null;
    if (!(object instanceof Lookup.Provider)) return null;
    Lookup lookup = ((Lookup.Provider)object).getLookup();
    return lookup.lookup(Icon.class);
  }

and each of the individual classes (Project, Module, PsiElement, JdkOrderEntry, LibraryOrderEntry, ModuleOrderEntry) will have to add into their lookup the given Icon.

As it is right now, the existing code has a lot of imports. What looks like a little Swing module (com.intellij.ide.navigationToolbar) imports hundreds of classes from all over the place and seems to be a pain to read and maintain.

Truth be told, the code is from 2008 -- perhaps the newer stuff already has a similar mechanism.

PS: While I am a NetBeans guy, I'm not trying to start a flamewar. I actually want to see if I can reuse navigationToolbar but all these imports are making it really difficult.

Tuesday, February 21, 2012

Magic is just programming without knowledge

There is nothing more cringe-inducing than seeing somebody try to program something without actually knowing what's going on. With some exceptions, programming allows you to know precisely what's going on. Not knowing how something works should trigger some alarm bells.

Magic might be an ancient form of "programming" nature where most of knowledge has actually been lost. Without factual information, only rituals were kept and some basic notions.

I wouldn't be surprised if in 1000 years or so we have a high-priest class of programmers that need to take care of computerized systems so old they forgot the logic behind them. They will basically become magicians.

Wednesday, February 15, 2012

LTS means ancient?

I was surprised today to see that Ubuntu 10.04 LTS comes with Mercurial 1.4! The latest Mercurial release is 2.1

Mercurial 1.7 also introduced a repository change, the dotencode requirement. This means any repository created after November 2010 with 1.7 and dotencode will not be accessible by the Mercurial from the Ubuntu LTS. This error should be familiar:

abort: requirement 'dotencode' not supported!

One solution is to use the Mercurial PPA to get a newer release.

But, it doesn't make sense to use an LTS if you are going to use software from PPAs, no?

With sun-jdk being pruned from the repositories, I'm starting to get annoyed by Ubuntu. I'm starting more and more to manage dependencies by hand instead of relying on the system. Which, imho, means the system is broken.

The Trouble with Harry time loop

I saw The Trouble with Harry (1955) a while back and it didn't have a big impression on me. But recently I rewatched it and was amazed a...