The amazing adventures of Doug Hughes

Archive for December, 2008

OSX 10.5 and FlexBuilder 3: You CAN have JVM Goodness(tm)

Over the course of the last 48 hours I’ve been trying to nail down the last few issues in moving to OSX 10.5 64-bit. I’ve run into ColdFusion/Apache 2.2 configuration issues (that’s a whole other blog post), I’ve run into issues that one always runs into when changing systems, and I ran into one file, and potentially excruciating issue that I want to address here. That issue is (in my opinion incorrectly) addressed in Adobe technote kb405284 titled "Flex Builder 3.x not supported with 64 bit Java 1.6 on Mac OS X" wherein Adobe asserts that the only solution to running FlexBuilder 3 on OSX is to revert the JVM to the 32-bit Java 1.5.0 that comes with the computer. This posed a serious dilemma.

I had just spent 12 hours getting around install issues, connector config issues, migration issues, and the rest of the issues that you encounter with a major change, and I wasn’t about to sacrifice my ability to run 64-bit ColdFusion for the sake of FlexBuilder 3. So I started experimenting… shell scripts are marvelous things that I’ve been playing with a lot lately and I tried swapping VMs around before launching apps, I tried launching applications with explicit paths to the JVM I wanted it to use, I tried all kinds of things. Then, in a brief IM conversation with my friend Simeon Bateman, he reminded me that launch-time directives go in the .ini file included with the install.

So I ran off to do a bit more Googling, which led me to this post in the Eclipse wiki, dealing specifically with Eclipse.ini. On OSX, it’s located at /Applications/Adobe Flex Builder3/Flex Builder.app/Contents/MacOS/FlexBuilder.ini, and it’s sooooo easy to specify the VM you want to use:

-vm
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0
-vmargs
-Xdock:icon=../Resources/flexbuilder.icns
-Xdock:name=Flex Builder
-XstartOnFirstThread
-Xms128m
-Xmx512m
-XX:MaxPermSize=256m
-XX:PermSize=64m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-Dorg.eclipse.swt.internal.carbon.noFocusRing

Those first 2 lines: “-vm /path/to/your/vm/1.x.x” Yeah, that’s it.

The only gotcha is that they have to be on separate lines in the .ini file and they have to appear before the -vmargs directive because everything after that is passed as VM arguments when Java is being launched.

If you’re running Eclipse proper, the same concept applies only it should be at /Applications/eclipse/Eclipse.app/Contents/MacOS/eclipse.ini, or you can launch Eclipse using the symlink located at /Appplications/eclipse/eclipse and pass the -vm argument directly in (but why on earth would you want to do that?)

The reason I say that the above-mentioned Adobe KB article is incorrect is for a couple of reasons:

  1. The Eclipse Foundation specifies that an explicit JVM path is a Good Thing™
  2. On OSX, the JVM path is pretty much universal, since Apple considers the JVM to be part of the OS
  3. Having the Flex Builder 3 installer include the -vm argument in the .ini file is trivial.
  4. Since Apple only releases major versions of Java with a new OS, chances are that the highest-rev JVM on a Mac is not going to change, and if it does, well, there are other ways to deal with that issue.

So I don’t really understand why Adobe would insist that we run an older JVM just to get Flex Builder running when there’s such an excellent alternative. Right now I’m running CF8 on Java 1.6 64-bit and Flex Builder 3 on 32-bit Java 1.5.0 and everything is co-existing happily. Give it a try and let me know how it works for you?

Bind Error Alert Messages: My Most Despised ColdFusion Feature (And a Solution!)

I usually try to remain fairly positive on this blog and not be outright negative about, well, anything. But this time I simply don’t have any way to look positively on my most despised feature of ColdFusion. To put it simply, I hate how ColdFusion shows a JavaScript alert every time there’s a problem with anything related to cfajax.

Right now, I’m working on an absolutely insane HTML form. When done it will probably have multi-hundreds of fields. (Before anyone blasts me on this, there are business processes which require such a complex form and processes are in place to make it less cumbersome.) This form has a lot of fields which are bound to other fields. Furthermore, this is a Model-Glue application and if you run into a ColdFusion error an error event handler is displayed, not an inline error message as with traditional ColdFusion development. This means that every time I get a ColdFusion error all my bindings fail and I have to click through a metric ton of alert messages.

And, to make matters worse, I’m on a Mac where alert messages slide in from the top of the browser so they take longer. Today this chaffed me for the last time and I’ve decided to switch to PHP! (Just Kidding!!) Actually, I tracked down where CF’s JavaScript was showing these bloody alert messages. This is within a function called handleError within cfajax.js. In this function the code looks to see if you’re logging errors (via that cf ajax logging interface), or if there’s a global error handler, and, failing that, it shows an alert message. I tracked down the code on the global error handler and it turns out that there’s an undocumented feature of the ColdFusion Ajax features that lets you handle errors your own way. Once I figured that out, redirecting the error messages to the FireBug console became extremely easy with this small chunk of code:

// this overrides the default CF error handling alert message!
ColdFusion.setGlobalErrorHandler(function (error) {
    if (typeof console != & quot; undefined & quot;) {
        console.log(error);
    } else {
        alert(error);
    }
});

This code should be compatible with all browser configurations as well in that if the console does not exist the alert messages will be shown instead.

Viewing MJPEG Streams in Flex

So, I’m learning Flex at long last. The reason for me finally taking up this challenge is that I finally found a project I believed it well suited to. You see, my family has lots of digital photos. About 9000 at last count. We keep these stored on a NAS in my office. All of our computers are set to show these photos as our screen savers. However, I’ve wanted a nice wireless digital picture frame that would randomly pull from this pool of images. Well, to make a long story short, I was unable to find a single wireless picture frame that could read from a Samba share. (And trust me, I’ve tried a lot of things.)

So, finally I became frustrated enough to take this into my own hands. I plan make my own ideal digital picture frame. I’m currently working on an Air application that will run in full screen and provide access to a range of picture frame components. Obviously, a part of this will display pictures. Other components will display weather information, stats on Alagad, and pretty much anything else I want to wire into my picture frame. Eventually, I’ll buy a nice, thin, touch screen tablet PC, configure it to run my air app on load, get it professionally framed and hang it on the wall.

Now, one of the components I want this picture frame to show is a video stream from my daughters baby monitor camera. Actually, it’s not really a baby monitor camera it’s a more-or-less generic wireless surveillance camera. I don’t have the model information any more and it’s not branded at all. But, from research I’ve done there are a lot of these cameras which run the same software.

The camera runs a basic web server so I can pull up the camera and see either a still photo or a video stream in a Java Applet or ActiveX Control. I did a little playing around with the camera and discovered that the still photo is returned from a file called “image.jpg”. Any time you request this file you get the latest image from the camera. So, my first attempt a hooking into the video camera was simply to request this photo over and over again and use that as the source for an Image object. This worked to an extent, but the Image object wouldn’t refresh quickly enough and would as a result flicker. Beyond that, I had to make a complete HTTP request for each frame of the video and it had a very slow refresh rate. I was able to solve the flickering problem by having two images on my canvas and alternate setting the source of each image and hiding the other image.

I was happy to have accomplished that, but it just wasn’t very nice. So I decided to do a little more research. The Java Applet on the camera was called xplug.class. Googling that revealed a few people who had decompiled the class and used that to discover that the camera actually streams video from a file named mjpeg.cgi. If you access this file directly you’ll simply get a long stream of binary data which makes up the video feed from the camera. Obviously the Java Applet and Active X Control could read this stream and use it to display the video feed.

A little more research revealed that, sadly, mjpeg is not a standard but more of a technique. Mjpeg really is just a concatenated stream of jpeg images, one after another. I’m familiar with the JPEG format (at least to some degree) from my work on the Image Component. At least, I knew enough to know the first few bytes that mark a JPEG image (FF D8). So, I figured I’d look at the data in the video stream to see if I could figure it out. I captured a few seconds of the video to disk using Curl and opened it up in a hex editor. The first thing I noticed was that each frame of the video was denoted by an ascii string “–video boundary–“. Looking a bit further into the file I discovered that I could find the markers that start an image. I tested cutting the bytes from the beginning of where I thought the JPEG would start to the last byte before the video boundary into a new file and saved it as a jpeg, which I was subsequently able to read!

I knew that if I could read the feed by simply starting at the top of the feed, find the start of an image and the end, cutting out that image, displaying it and repeating the process forever.

Simeon Bateman filled in the last little piece of data I needed to know to make this work. Namely, that you can simply provide binary data to the source property of an Image object and Flex will display the image.

So, after figuring out how to make a socket connection from Flex I was able to parse the video feed and display the video feed! I did still have the flickering problem but I solved it in a similar manner.

Attached to this blog entry is a final Flex Component which connects to the camera by URL and streams the feed. Anyone who has a use or it may use it, assuming your video feed is the same format as mine. This is my first real bit of AS3/Flex development though so don’t be offended if I’m not doing things in the best way possible.

Here’s an example usage of the component:

<webcam:webcamImage left="0" top="0" right="0" bottom="0" host="mycamera.com" port="80" />

You can also supply username and password properties to access password protected cameras.

Flex Builder ColdFusion Flash Remoting Problem and Resolution

This entry covers some problems I ran into configuring a Flex application to work with ColdFusion Flash Remoting on Mac OS X. I am working on an Air application which will talk to ColdFusion via Flash Remoting. My components are accessible via an Apache virtual host. My virtual host answered to the domain http://photoframe, which I configured, tested and was working correctly. IE: I could put a file in the directory for that URL and pull it up via a web browser.

My next step was to create a new Flex Project in Eclipse. For the first page I provided the path to my project directory (up one level from my www directory). I indicated I’m creating an Air app. Finally, I selected ColdFusion as my server technology and that I was using ColdFusion Flash Remoting for my remote access service and clicked next to continue.

Now, honestly, I’m new to Flex. (Most of my team has been working with Flex a lot longer.) The next step in creating a Flex project has always stymied me. I never knew the correct values to to provide for this screen and, frankly, the documentation was next to useless and the default values were misleading. Tonight I realized it’s really not that complicated. In the past I thought that web root and root url fields were asking for the ColdFusion instance’s web server root. To clarify, when you install CF as either stand alone without a web server or multi-server you end up with a server you can hit via HTTP. IE: http://localhost:8500. And, if you’re running more than one instance of CF you might need a context root appended to that URL.

I figured this told Flex where to access whatever it needed to make remote calls. Turns out I was mostly incorrect. If you have ColdFusion connected to a web server (like most of the normal world) you actually simply need to create a new site, like my http://photoFrame, and provide the path to its webroot, and the URL you use to access it. So, in my case the web root was “/users/dhughes/sites/photoFrame/www” and the url was http://photoFrame. Because I’m using a web server I don’t need to provide a context root. For the ColdFusion war folder I provided the path as I expected. I simply provided “/Applications/JRun/servers/cfusion/cfusion-ear/cfusion-war”. I left the compiled location at it’s default.

Now, this is where I began to run into problems. When I clicked the button to validate the configuration I received this warning message: “Cannot access the web server. The server may not be running, or the web root folder or root URL may be invalid.” It wasn’t an error and I could click next. But, I didn’t like seeing the warning so I did a little research to see if I could figure out what’s going on.

It seems that when you click the validate button Flex Builder it writes a temporary file to disk and tries to access it via the URL you specified. I noticed in my Apache error log I was seeing messages like these:

[Sat Dec 13 18:59:19 2008] [error] [client 127.0.0.1] File does not exist: /Users/dhughes/Sites/photoFeed/www/flex_wizard_project_test_script_server_7181.htm
[Sat Dec 13 20:56:35 2008] [error] [client 127.0.0.1] File does not exist: /Users/dhughes/Sites/photoFeed/www/flex_wizard_project_test_script_server_7227.htm

I’m not sure why Flex Builder wasn’t writing those files to the correct location, but at least I know it was hitting the correct virtual host. And, though I was receiving the warning, I could click next to create the project and I did.

Now that my project was created I threw together a simple hello world CFC and some quick MXML that used to call a saHi() method on the CFC. But, when that code was run I received this error message: RPC Fault faultString=”Send failed” faultCode=”Client.Error.MessageSend” faultDetail=”Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: ‘http://hotoFrame.swf/flex2gateway/'”

Now, take a close look at that error message. Note that it’s not trying to access “http://photoFrame”, it tried to access “http://hotoFrame.swf”! I have absolutely no idea why it’s using the name of the SWF, less the first letter of it’s name, as the URL instead of http://photoFrame. Very perplexing. I spent a good long time Googling this and found absolutely nothing useful. Maybe one of my blog readers knows the answer to this.

So I went into the next best thing and asked around on #ColdFusion in IRC where Dan Wilson was luckily willing to help me. We determined that ColdFusion’s configuration was correct. (I won’t describe how it was configured because I’m still new to this. Suffice it to say it was the default.) We checked ColdFusion to confirm Flash Remoting was enabled too. Finally, Dan consulted with a friend of his who suggested we try copying five XML files from the ColdFusion WEB-INF/flex directory into our project. So, I copied these five files to a config directory I created under my project:

  • services-config.xml
  • remoting-config.xml
  • proxy-config.xml
  • messaging-config.xml
  • data-management-config.xml

Once these files were in place I edited the ColdFusion destination in the remoting-config.xml file to use a new channel, “PhotoFrame”. This could be named anything. I then edited my services-config.xml and created a new channel-definition based on the default “my-cfamf” but named “PhotoFrame”. I set the uri for this channel to be the actual, static, correct, URL for my application. IE: “http://photoframe/flex2gateway/”. Finally, I edited the compiler settings to point at the the copied services-config.xml file. Amazingly, on the next run the application loaded and was able to hit my remote CFC!

I have no idea why I had this problem, but I’m happy to have a solution.

I Just Love VMWare

The Alagad crew (well my team at least) is happily working with a client to help them create a next-generation product data management system. This is easily the largest and most complex system I’ve ever worked on. Yesterday I was breaking ground on the next and final major section of the application. I spent the previous days coming up with use cases, etc, and planning my approach to the architecture for this section. As a part of that I defined a set of SQL tables and I spent yesterday actually creating the tables. I tend to create tables in my local database and, once they’re finalized, I email scripts to our DBA who adds them to the “gold” copy of the database which is deployed to our client’s servers.

So, today, I’m working through some high-level code and I realize I need the latest copy of the database. So I grab the latest revision out of SVN and restore it over my local copy. (Anyone see where this is headed?) And get back to work. This is when I start getting weird errors about objects not existing. D’oh! I’d restored over my changes without first generating my scripts! The first thing I do is look for my SQL backups. (Yes, I run SQL backups of development databases.) But, for some unknown reason it seems like my SQL Agent has been shut off since August! So, needless to say, I had no backups of the database. So, after complaining to a co-worker and enabling SQL Agent, I was about to get back into recreating tables when I realized a couple things:

  1. SQL Server is running in VMWare.
  2. I’m on a Mac using Time Machine so I should be able to restore yesterday’s backup of the VM.
  3. I don’t need to restore yesterday’s backup! I have automatic snapshots enabled in VMWare!

To solve my dilemma all I had to was create a snapshop of the VM’s current state, roll back to the last snapshot, generate my scripts, roll forward and apply my scripts. Problem solved! I really love VMWare!

Yet Another 'Passed By Reference' Analogy

Last week, there was a conversation in the #coldfusion channel on Dalnet IRC where one person was pondering if the ‘passed by reference’ behavior of ColdFusion (and just about every other programming language) ‘breaks’ encapsulation when using object oriented (OO) design patterns or architecture.

For those who may not understand what ‘passed by reference’ means, it is a way that programming languages handle complex data types (such as structures, queries or CFC instances in ColdFusion) to save memory. When you create a structure in ColdFusion, it gets stored in memory. Whenever you need to reference this structure or pass it to a function or custom tag, ColdFusion uses a ‘pointer’ to show where in the memory this variable is stored, rather than another instance of the variable. Any changes made to the structure in the function or custom tag, will be reflected in the ‘original’ structure.

Here is some sample code to show how this works.

<cfset struct1 = structNew() />
<cfset struct1.name = "New York Giants" />

<cfset struct2 = struct1 />
<cfset struct2.name = "New York Yankees" />

<cfoutput>#struct1.name#</cfoutput>

This code will actually output ‘New York Yankees’ rather than ‘New York Giants’, as some might expect.

The person who asked the question was concerned about how you can pass an object into a method, modify properties of that object, NOT return the object, yet still see those property changes reflected in the original object. He assumed this ‘broke’ encapsulation. Here is the analogy he used:

“Let’s say my method is a ‘locked room’ and I pass this method arguments by slipping paper under the door. If I pass a piece of paper under the door that represents the object, should I not get back a piece of paper with the changes made to my object?”

I liked this analogy as it represents a method as a kind of ‘black box’, which they should be, where we merely pass in data and that data gets handled and we do not need to worry about it. There were some flaws in the logic, though, as ‘passing by reference’ is not an OO principal, rather a very low level process of the programming language. When we in the channel explained that ‘passed by reference’ is not an OO principal, rather the way programming languages pass around complex data types to save memory, he then asked

“So using my door analogy, I would slide a piece of paper under the door, yet keep a copy for myself and any changes that are made by my method will automatically appear on the piece of paper I keep?”

I thought about this for a little bit as it did not seem to completely explain what was going on. After a few minutes, I think I came up with an analogy that works well (and he said helped him understand a bit more):

“Instead of sliding a piece of paper under the door that represents your object, you merely slide a note under the door that tells the method that the paper (object) it needs is tacked up on the bulletin board in the hall. You do not have that paper either, rather, you also have a note saying that the paper (object) is on the bulletin board.”

I will admit this may not be a perfect analogy either, but it did help this person and I thought it might help clarify this for others as well.

Tag Cloud