Archive for the ‘Open Source Software’ Category

NeoOffice 3.0 Patch 4 is Out

Thursday, June 18th, 2009

NeoOffice.jpg

I don't worry about staying too up-to-date with NeoOffice because for the most part I don't use it. But every now and then I use it to read a file someone sends me that can't be read by the other apps I have to fake MS Word or some older word processor. It's been a while since I've updated, and so this morning when I heard about Patch 4 being released, I decided that today was the day to get up to date.

Good enough. I'm ready for the next time I need it.

Firefox 3.0.11 is Out

Friday, June 12th, 2009

Firefox.jpg

I noticed this morning that Firefox 3.0.11 is out and from the release notes it looks like it's a security update with a single bookmark database fix. Well... at least it's progress.

I have to say, with Safari 4 out and Google Chrome on Mac OS X making progress, the update for Firefox 3.5 should hurry up or look to be significantly lagging behind. Hope to see it soon.

Tomcat 6 and log4j Logging is Not Really Complete

Wednesday, June 3rd, 2009

WebDevel.jpg

I have been messing with Tomcat 6 and log4J logging today because this web app I've been working with had to add log4j for an external dependency that was added today. In general, I'm a fan of log4j if you go through the effort of using it properly, it's not bad. But adding it turned out to be a pain that I couldn't have imagined. In the end, I should have gone directly to the Tomcat 6 website and looked at the docs there and not questioned it. But I had done this before, and I was convinced that I could whip this up without any grief. (Ha)

The simplest thing was to create a log4j.properties file like:

  log4j.rootLogger=INFO,A1
      log4j.appender.A1=org.apache.log4j.ConsoleAppender
      log4j.appender.A1.layout=org.apache.log4j.PatternLayout
      log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

and place it in the WEB-INF/lib directory of the web app. I also placed the log4j.jar (version 1.2.15) into the same directory, deployed it and it worked. Almost.

Actually, it worked about half the time. The other half the time I got a warning from log4j saying it couldn't find the properties file. Very odd. If I edited the file, it was there and OK, but sometimes it'd work and sometimes not.

I looked into this from a lot of angles, and there was nothing I could do to get it to reliably recognize the log4j.properties file in the WEB-INF/lib directory of the web app. Then I read this from the Tomcat 6 website.

Seems they are saying that you have to place the log4j.properties file in the $CATALINA_HOME/lib directory. No choice. That means it's the same logging for all web apps on that instance. In general, I can see why that's required, but then I'm a little blown away that it wasn't working where it was. But it was... and it wasn't.

So in the end, I put the files (jar and properties file) into the $CATALINA_HOME/lib directory and restarted things and it's working fine. Kind of a pain to tease me with the possible working within the web app, and that would be exceptionally cool, but it's just not going to happen in this release of Tomcat 6.

Multi-Threaded JavaScript – Not What You’d Wish For Exactly

Monday, May 11th, 2009

SquirrelFish.jpg

I ran into a bug in my web app today that I should have seen coming, but my head hadn't been in the multi-threaded space at the time, so I missed it. The core concept is that JavaScript can be driven on multiple threads (timer, user interaction, callback, etc.) and if there are multiple threads doing things to the same codebase, you have a multi-threaded program, and you'd like all the tools a general multi-threaded language.

In my reading, I have heard that certain JavaScript engine implementations are single-threaded, but that's not part of the specification, and it's up to the implementors to decide whether or not to make the engine multi-core. In general, I think it's more likely that as time goes on, more engines will be multi-threaded rather than less.

The code I was having problems with this morning looked like this:

  prevRange = graph.getVisibleChartRange();
  if ((prevRange.start.getTime() == maxGraphRange.start.getTime()) &&
      (prevRange.end.getTime() == maxGraphRange.end.getTime()))) {
    prevRange = null;
  }

where I'm getting the selected range on the Google Visualization AnnotatedTimeLine widget and comparing that to the original (un-zoomed) values, and if they are the same, I'm nulling it out. The reason for this is to preserve the zoom level across changes to the graph, but the problem is very tricky.

Since JavaScript is inherently multi-threaded, I have to be aware of the possibility that things are being changed underneath you from timers and AJAX requests... so there's the possibility that while you're running this code, the graph itself is updated with data and redrawn, and in that redrawing, the data is invalid, and there will be no valid range on the graph. Resulting in the first line returning null.

This null then creates a null pointer exception in the code when it's asked for start in the second line. Not nice. So I had to protect the code from that possibility by saying:

  prevRange = graph.getVisibleChartRange();
  if ((prevRange != null) &&
      (prevRange.start.getTime() == maxGraphRange.start.getTime()) &&
      (prevRange.end.getTime() == maxGraphRange.end.getTime()))) {
    prevRange = null;
  }

The problem with this is that it's possible that there was a zoomed range, and in the redraw, and just plain bad timing, we're going to loose that because the method getVisibleChartRange() is going to return null when it was just incapable of returning anything meaningful. The better solution would be to have a mutex on the graph, and have it not return anything while it's redrawing, and then when it's done, return the answer.

But that would presume the concept of a JavaScript mutex. But nothing like it exists. Odd, isn't it? It just hit me this morning, and I did a bit of Googling to see if there were anything I was missing in JavaScript or a library that might act as a mutex, but there really isn't. That's too bad. Really too bad.

What it means is that there's going to be something like it one day, and that's going to make coding in JavaScript much nicer, and it also means that there's nothing I can really do to fix up the code. There is a slim possibility that there will be an update to the graph while hitting that one section of code that will be invalidated by the inability to lock (block) the update.

I suppose I could think about setting a value before the update and then restoring it afterwards... Hmmm... something to think about.

FIrefox 3.0.10 is Out

Tuesday, April 28th, 2009

Firefox.jpg

This morning I noticed that Firefox 3.0.10 was out with the complete set of release notes consisting of:

and that's it. Certainly sounds serious, so I got the latest version and will run with that. It's a nice thing that they have the auto-updating feature as I'm not sure how many folks would take the time to go to the web site every time there's a security update.

GraphicConverter 6.4.1 is Out

Monday, April 27th, 2009

GraphicConverter.jpg

This morning I saw that GraphicConverter 6.4.1 is out with quite a few updates and improvements. While I'm not using it a lot after I started using Acorn, I still like to have it around for those times when I need to convert a very odd graphics data file to something a little more standard. Like the name says, this is what it's really good at.

Nice to see they are still working on it.

Cyberduck 3.2 is Out

Monday, April 27th, 2009

Cyberduck.jpg

This morning I saw that Cyberduck 3.2 is out with quite a few fixes and additional features. While I'm not hip-deep in SFTP, it's something I use from time to time, and Cyberduck is certainly the easiest to use on the Mac that I've run into. It's small, fast, and works like you'd expect it to. Nice.

Interesting Way to Print Complete JavaScript Object Heirarchy

Thursday, April 23rd, 2009

SquirrelFish.jpg

I was working with the JSON response from my servlet and needed to be able to print the complete structure of a JavaScript object. I wanted to make sure that I was evaluating what I was receiving from the servlet properly. Well... there isn't something that's a part of JavaScript natively, but you can do something simple and you'll get something pretty close:

  var data = eval('(' + xhr.responseText + ')');
  var guts = '';
  for (var key in data) {
    guts += key + ' : ' + data[key] + '\n';
  }

and you get the keys and values for those keys. You aren't not going to get a complete recursive output, but if you wanted to, it's easy to imagine making a print function and you're good to go.

Just a neat little trick.

iTerm 0.9.6.20090415 is Out

Thursday, April 23rd, 2009

iTerm.jpg

OK, once again, we have an update from the iTerm group - this one appears to have been release on 4/15 and I just missed it. Fair enough. It's update says:

  • Fixed clipping bottom of fonts that are not Monaco (#2735995)
  • Smart window placement remembers initial window (#2736180)
  • Windows will no longer be placed under the dock (#2740187)
  • Fixed default background colour being drawn over background image
  • Fixed a bug when pasting more than 1024 characters of text
  • Fix overwriting of static window/bookmark titles (#2744363)
  • Revert to old force screen update behaviour for 10.4 (#2738986)
  • Rewrote large parts of PTYTask

all of which aren't a big deal to me, but nice to see movement is being made. My remaining issue is the lack of "Workspace" support where Terminal.app has it. If it weren't for that, I'd be able to switch back to iTerm. Because I sure do like the absence of the scrollbars on the windows.

UPDATE: I decided to send in a feature request about the 'workspaces' feature. I don't have high hopes for this as it's probably not what they are interested in adding, but you never know. No harm in asking.

Detecting Installed Plug-Ins in JavaScript

Wednesday, April 22nd, 2009

WebDevel.jpg

The support guys at the Shop have asked me if I could detect the presence/absence of the Flash plug-in on the allowed browsers for my web app. Currently, I check for IE and toss it out due to it's horrible JavaScript memory management. I also toss out versions of Firefox prior to 3 for the same reason. But after that, I was letting the browser deal with the existence of Flash and Java applet support. This was a mistake, as a lot of the folks didn't have these and it made for a bad user experience.

So I set about getting the detection code working. It turns out that it's really pretty easy to do because it's all pretty much there in the data within the browser, you just have to know how to parse it up. The method I came up with was part of a browser detection script, as it seemed most logical that I extend that and add methods like BrowserDetect.gotFlash and BrowserDetect.gotJava.

The code looks at the MIME types for the existence of the plug-in and then looks at the list of plug-ins to see if the version matches the minimum versions for my application.

  var BrowserDetect = {
    init: function() {
      // ...checking code for browser, version, and OS
      // check for the Flash plug-in
      this.gotFlash = this.checkPlugin('application/x-shockwave-flash',
                                       'Shockwave Flash', 10);
      // check for the Java Applet plug-in
      if (this.OS == 'Windows') {
        this.gotJava = this.checkPlugin('application/x-java-applet',
                                        'Java Plug-in', 1.6);
      } else {
        this.gotJava = this.checkPlugin('application/x-java-applet',
                                        'Java(TM) Plug-in', 1.6);
      }
    },
 
    // ...more methods...
 
    checkPlugin: function(mime, descKey, minVer) {
      // assume there's no valid plug-in matching these requirements
      var flag = false;
      var plugin = (navigator.mimeTypes && navigator.mimeTypes[mime]) ?
                   navigator.mimeTypes[mime].enabledPlugin : 0;
      if (plugin) {
        var cnt = navigator.plugins.length;
        for (var p = 0; p < cnt; ++p) {
          if (navigator.plugins[p].description.indexOf(descKey) >= 0) {
            var words = navigator.plugins[p].description.split(' ');
            for (var i = 0; i < words.length; ++i) {
              if (isNaN(parseFloat(words[i])))
                continue;
              var pluginVersion = parseFloat(words[i]);
            }
            flag = (pluginVersion >= minVer);
            // no need to check any further
            break;
          }
        }
      }
      return flag;
    },
 
    // ...more methods...
  };
  // initialize this guy so we can be ready to read all the values
  BrowserDetect.init();

With this code, I'm able to use the BrowserDetect.gotFlash call to put out a little notice about downloading the latest Flash plug-in - which is great because I'm not only detecting the existence, I'm also checking the version. This has proven to be a major hassle with Flash as the Google Visualization widget appears to work, but there are subtle things that make it seem broken. It's always been the version of Flash being less than 9. With version 10, we're good to go. That's a load off.

In general, I can see all these AJAX frameworks popping up. If I had known of one that had all this built-in, it'd be really nice. As it's already built, I'll look after-the-fact and if I run across something, I'll look at using it. But I can see why folks write these frameworks, and then use them over and over again.

Great code.