Archive for the ‘Open Source Software’ Category

OmniObjectMeter v2.6 is Now Free!

Wednesday, February 25th, 2009

OmniObjectMeter.jpg

The OmniGroup are now giving away four of their lesser-developed applications, and of these, one is something I've wanted to have for a while - OmniObjectMeter. Back in the NeXTSTEP/OPENSTEP days, OmniObjectMeter was the tool for finding object leaks. And on the Mac, that's about the only memory issue you should run into. So having it is a real feather in your cap. But it was expensive for as often as I needed it. Now that's not the issue any longer.

If you are having issues with memory allocation in Mac OS X - get it. Trust me, it's worth the time.

Blender 2.48a is Out

Tuesday, February 24th, 2009

Blender.jpg

Well... the Blender folks have once again released a new version of the interesting 3D modeling software. I know I need to take time to learn to use this thing, but I just haven't had the time yet to do it. But I keep getting the updates so that when I do have the time, I've got the latest version to work with.

Fixing CorePlot’s CPPlotRange Core Animation Type Encoding

Monday, February 23rd, 2009

CorePlot.jpg

A few days ago, I started working on Issue #2 for CorePlot. I worked on this for quite a while trying to get the NSDecimal ivars on the CPCartesianPlotSpace to encode properly in Core Animation, but to no avail. The things I read on Google are basically that if it's not an object that conforms to the NSCoder protocol, then the data type has to be understood by Core Animation. That means it has to be a CG-prefaced data type. Fair enough.

The problem manifests itself as a run-time error message like:

2009-02-11 13:49:39.126 CPTestApp[26427:10b] unhandled property type encoding: 
`{_CPPlotRange="location"{?
="_exponent"b8"_length"b4"_isNegative"b1"_isCompact"b1"_reserved"b18"_mantissa"[8S]}
"length"{?="_exponent"b8"_length"b4"_isNegative"b1"_isCompact"b1"_reserved"b18"
_mantissa"[8S]}}'
2009-02-11 13:49:39.128 CPTestApp[26427:10b] unhandled property type encoding: 
`{_CPPlotRange="location"{?
="_exponent"b8"_length"b4"_isNegative"b1"_isCompact"b1"_reserved"b18"_mantissa"[8S]}
"length
"{?="_exponent"b8"_length"b4"_isNegative"b1"_isCompact"b1"_reserved"b18"
_mantissa"[8S]}}'

I talked to Drew about this and told him that the only way I could see to fix it was to either drop the precision on the CPPlotRange by using CPDoubles or to update the CPPlotRange to a full-blown class with instance variables that are (NSDecimalNumber *). These guys implement the NSCoder protocol, and with a little extra logic, the new CPPlotRange can fit into the codebase nicely.

So that's what I did. It was a blast. I then checked it in and sent Drew an email and updated the issue on Google groups. I asked Drew for comments on the code, and we'll see if he thinks I went overboard on the comments (I didn't), or if there's something he thinks I should have done and didn't do.

All in all - very exciting.

MacVim Snapshot 43 is Out

Saturday, February 21st, 2009

MacVim.jpg

The mailing list alerted me that MacVim Snapshot 43 is out and while the changes aren't earth-shaking, there are new icons, and there are gains in the way the forking is done so as to improve the startup time of the windows. Not bad at all.

I have to say, it's nice to have this reliable tool on my machine as I'm moving from one job to another. It's a constant companion.

Building the Latest CPTestApp in the CorePlot Project

Friday, February 20th, 2009

CorePlot.jpg

Well... I'm stumped. I had been working on a few things for the unit testing framework yesterday, and today I wanted to look at this problem that had been reported on the Google Code site. Basically, there's a build problem, and I wanted to track it down.

First thing: build the code and reproduce the issue. It builds fine - I can't see the error, but when I run it within Xcode, I get the following on the Console:

    [Session started at 2009-02-20 12:05:37 -0600.]
    dyld: Library not loaded: @loader_path/../Frameworks/CorePlot.framework/Versions/
        A/CorePlot
    Referenced from: /Users/drbob/Developer/core-plot/examples/CPTestApp/build/Debug/
        CPTestApp.app/Contents/MacOS/CPTestApp
    Reason: image not found

  The Debugger has exited due to signal 5 (SIGTRAP).The Debugger has exited due to
      signal 5 (SIGTRAP).

OK, this should be easy - it's got to be that the CorePlot.framework isn't properly in the project and that's what's missing. So I looked into that. But it's there. Just where it should be. Then I dug into the built CPTestApp.app wrapper and right where it's supposed to be is the framework! I'm stumped.

I looked at the project settings... nothing popped out at me. I cleared the Xcode project file and reloaded it from the repo... no difference. I even did what I thought should have been done and added in the CorePlot.framework to the Linked Frameworks 'folder' in the project, and still nothing.

I'm blown away! So I finally shot an email to the mailing list and we'll see if we can't find out what's up. I'm really stumped. It used to work!

UPDATE: HA! I got it figured out. First, the path for the library is encoded into the Framework - not in the app using the framework. OK, now that I knew that, I started looking at the CorePlot Framework build parameters. I noticed the one that I was looking for in the Deployment section:

Target 201CCorePlot201D Info

Originally, the Installation Directory was set to:

  @loader_path/../Frameworks

and that was what was being set in the dynamic library, and compiled into the app's executable. What I needed to change was the path to:

  @loader_path/../Resources/Frameworks

and then it was able to find the framework and run.

OK, this wasn't obvious in the least. I Googled this guy and came up with nothing other than the fact that the name was in the shared library - which I had remembered as soon as I was reading the post. So, at least now, I can see the error, and hopefully get a handle on it.

UPDATE: Drew commented that he had changed the @loader_path to @executable_path a while back, but that there may have been issues in the merge that was done to get the testing code working. So I emailed back that he's free to change it back and I'll just pick up the right version in the next 'svn update'. Sounds good to me. Glad to see I wasn't totally missing it.

[2/21] UPDATE: Barry pointed out that @loader_path is the right value - but the project was not configured to copy the framework into the right location. So he fixed that. It builds fine now.

Adium 1.3.3 is Out

Friday, February 20th, 2009

Adium.jpg

I learned that Adium 1.3.3 was out this morning, but oddly enough, the built-in updater wasn't able to update from 1.3.2 to 1.3.3. I'm not sure if this is a server-side issue with the upgrade package, or that the Sparkle updater wasn't working in the 1.3.2 release. Not sure, but I have 1.3.3 now, and it's got a bunch of updates.

It's interesting that it's got Facebook connectivity, as we've been going through a bit of that at the house these days. I'll be interesting to see how that integrates. Should be fun.

Did a Little Work on CorePlot Test Cases

Thursday, February 19th, 2009

CorePlot.jpg

I'm trying to see how an Open Source plotting package for Cocoa on Mac OS X goes. It started a few weeks ago, and I think it's the right thing to do as it's the kind of thing I've wanted to have for the Mac for ages, and being a part of it almost guarantees that I'll understand it well enough to make use of it. So I'm trying my hand at this kind of thing.

Today I looked at the new testing framework someone put in. I can see the value of automated testing but I also see the problems. Today it was sloppy includes, poor test writing and missing test data. They were fixed easily enough, but it brings to mind the problems I see in automated testing in the first place: What do you really test?

I'm all for testing the public APIs of classes. That's what the class is supposed to do, and how it's supposed to do it. But private methods are another thing. I think that's asking for a ton of grief. If the method is useful enough, and important enough to test, then maybe it should be in the public API. If it's not that important, then testing the public API should exercise the private implementation details.

The guy that threw this test frame together didn't share my ideas. He's got compiler warnings testing private methods, and I just think that's not right - from several points of view. First, the testing, and then the compiler warnings. There just shouldn't be any. Period. It's so easy to remove these, and they are there for a reason - you're making a mistake. Maybe not a big one, but it's a mistake, and you need to stop right now and fix it.

Given that this is open source, it's not going to get fixed unless I fix it, but that's OK too. I don't mind being in that role for this project. It's interesting and the outcome is something I've wanted for a long time. We'll just have to roll with the punches and see where it goes.

GIMP on Mac OS X 2.6.5 is Out

Wednesday, February 18th, 2009

Gimp.jpg

I've been a user of GIMP for more than a decade, and it's always been a solid graphics tool - invaluable on some platforms that have nothing else, but even a nice to have on the Mac. There are just some things that it does exceptionally well. But of late, the builds of GIMP for Mac OS X for Leopard have required that you update the X11 package to a more recent build of the XQuartz project - the basis of Apple's X11 package. While I've wanted to stay current with GIMP, I did not want to have a non-standard X11 install. So I was stuck.

Until now. Today I saw that GIMP for Mac OS X 2.6.5 was released, and I decided to download it on the off-chance that it would run on a stock Leopard install. It did! Fantastic!

While it's not going to be something I run all the time, like Acorn, it's something I'm really glad I have at my disposal when I need it. This is wonderful news.

Cleaning Up the PrettyPrint in Python’s xml.dom.minidom

Thursday, February 12th, 2009

python.jpg

OK... well, this has been an interesting exercise. I've been working on a Python script to grab data out of a system here, and generate an XML file for a vendor upload. It's a big file, and there's a lot of things that have to go into it, but I wanted to be able to do as much as possible from within the Python code itself. If I had to post-process it and add tags later, then that's OK, but I didn't want to start with that plan. I wanted to make the utmost of python's capabilities for this task.

For the most part, I haven't been disappointed. Python has a pretty nice XML DOM system (xml.dom.minidom) built-in, and I was able to create the document very easily. The problem came in dumping it to a file. There were two basic ways I could dump it:

<exchangeTraded><id type="SEDOL">B10RB15</id>
<positionName>1605=JP</positionName><amount>-214.0</amount></exchangeTraded>

where it all appeared on one 'line' and no spaces were to be found, for the 'simple' XML output, and:

<exchangeTraded>
    <id type="SEDOL">
        B10RB15
    </id>
    <name>
        1605=JP
    </name>
    <amount>
        -214.0
    </amount>
</exchangeTraded>

for the 'Pretty Print' output. Neither was really good, but as the lesser of two evils, the second one was far more readable for the size of the file I'd be sending. But I knew that I needed to get back to this as soon as reasonably possible and fix this up with a decent output processor.

Today has been that day. I was quite lucky that I got a good head-start with Google, and was able to put together the following replacement for writexml():

def new_writexml(self, writer, indent="", addindent="", newl=""):
    # indent = current indentation
    # addindent = indentation to add to higher levels
    # newl = newline string
    writer.write(indent + "<" + self.tagName)
 
    attrs = self._get_attributes()
    a_names = attrs.keys()
    a_names.sort()
    # lay down the attributes on the tag
    for a_name in a_names:
        writer.write(" %s=\"" % a_name)
        xml.dom.minidom._write_data(writer, attrs[a_name].value)
        writer.write("\"")
    # now lay down the child nodes
    if self.childNodes:
        if len(self.childNodes) == 1 and \
                self.childNodes[0].nodeType == xml.dom.minidom.Node.TEXT_NODE:
            writer.write(">%s</%s>%s" % (self.childNodes[0].data, self.tagName, \
                        newl))
            return
        writer.write(">%s" % (newl))
        for node in self.childNodes:
            node.writexml(writer, indent + addindent, addindent, newl)
        writer.write("%s</%s>%s" % (indent, self.tagName, newl))
    else:
        writer.write("/>%s" % (newl))

where the arguments are exactly the same as the original version, we've just cleaned up the printing of the child nodes when there's only one and that one is a text field. To install it into the proper place in the runtime, I simply need to:

#
# This is the main working section of the script
#
def main(argv):
    # hook in our new XML DOM writing code
    old_writexml = xml.dom.minidom.Element.writexml
    xml.dom.minidom.Element.writexml = new_writexml

and it's good to go with the same old code.

The results are perfect:

<exchangeTraded>
    <id type="SEDOL">B10RB15</id>
    <name>1605=JP</name>
    <amount>-214.0</amount>
</exchangeTraded>

I'm sure I'll be using this again very soon, and I wanted to document it so I didn't forget it. Really quite simple, but the effects are quite dramatic on a large file with thousands of nodes.

Interesting Limitation with Apache 2 and mod_proxy_ajp

Saturday, February 7th, 2009

WebDevel.jpg

I was rebuilding a few machines today - web servers, that were using the mod_proxy_ajp now a part of Apache to forward the non-static requests to the co-resident Tomcat instance on the box. As a part of that set-up, we had a custom conf file that we loaded into /etc/httpd/conf.d/ to handle all the configuration of the web server. Well... 99% of it, but still - all the proxy forwarding and virtual hosting is in this one file.

The wrinkle came in with a Redirect line in the VirtualHost section of the file:

  <VirtualHost yummy>
      Redirect /index.html http://localhost:8888/yummy/app
      Redirect /UAT http://slushy.funstuff.com:8888/yummy/app
      ...
  </VirtualHost>

where the primary machine has a DNS entry for yummy and that's how most folks get to the web site. The UAT box is called slushy, and this way, the users can hit the URL http://yummy/UAT and get right to the UAT box. Pretty nice.

Or so I thought.

The problem with Apache and the mod_alias, it seems, is the use of localhost in the redirection of index.html to the local machine. When I try to hit it, I get that the web site is not available - like the URL doesn't point to the right sight.

But when I go directly to http://yummy:8888/yummy/app I see the web site - so I know it's there. Also, if I use wget to grab http://localhost:8888/yummy/app on that box, I get the initial page.

It's as if the Apache mod_alias or the mod_proxy_ajp are somehow not using the standard methods of name-to-IP resolution. For if I change the configuration to:

  <VirtualHost yummy>
      Redirect /index.html http://yummy.funstuff.com:8888/yummy/app
      Redirect /UAT http://slushy.funstuff.com:8888/yummy/app
      ...
  </VirtualHost>

Everything works. I looked at the Apache docs for the Redirect command, and it says it needs a fully qualified URL. I have given it that - and verified with wget that it's working. But something in there isn't working.

What this means is that we need to customize these configuration files for each machine so that they can properly redirect to the host it's on. Odd. Very odd. But it's a work-around for now. If this comes up again and again, I'll look into it to see what I might have to do, but very odd.