Notes on the Fusion Authority Quarterly Update FLEX/AIR articles

The last Fusion Authority Quarterly Update focussed on User Interfaces and related topics, including an article on AIR by yours truly and some other Flex/AIR articles.

As it turns out, Adobe were nice enough to release AIR beta 2 and Flex Builder 3 Beta 2 at just about the same time the Journal came out, so some of our articles are now out of date. Such is life in the fast moving world of software development.

Anyway, the basics are still the same, but AIR apps now need to be signed and there are some other minor changes that are all detailed in the docs on Adobe labs; the FAQ-U 4 articles are still well worth reading. Anyone with questions on the differences for my article is welcome to comment here or send me an email (james.holmes at gmail dot com).

Coldfusion server restarts after a few days? Here's a possible solution.

After experiencing a random cf7 restart recently, I dug around and found this in the log:

Exception java.lang.OutOfMemoryError: requested 1024000 bytes for GrET* in /export1/jdk142-update/ws/fcs/hotspot/src/share/vm/utilities/growableArray.cpp. Out of swap space?
autorestart: Restarting process

I found some bug reports on Sun's site, with the usual buck-passing and claims regarding non-reproducibility, with no solid resolution; then I found Steven Erat's blog on the subject:

http://www.talkingtree.com/blog/index.cfm/2006/4/28/Understanding-HotSpot-in-Plain-English

Now it all makes sense. After a few days, the hotspot engine is compiling to native code instead of bytecode and has an issue. It fails bad enough that restarting the JVM is necessary.

Now to a question - has anyone seen this with CF8, running Java 6? The Sun bug reports all show 1.4 and 1.5 versions with issues, but I haven't seen it on 6.

New cumulative Coldfusion hotfix includes a backported fix from CF8

People will probably be aware that CF7.02 cumulative hotfix 3 is now available:

http://kb.adobe.com/selfservice/viewContent.do?externalId=kb402465

One of the items fixed is a personal favourite and it's been broken for ages:

67753; Disabling connections for a datasource in the cfadmin or using AdminAPI has no effect

This was first fixed in CF8. Thankfully it's been reworked for CF7 too - thanks Adobe. This was causing us all sorts of issues when we needed to to DB maintenance.

PHP on JRun Update - hacked and working

For anyone still interested, with minor hacking I now have PHP apps running on JRun next to CF. Two things needed hacking so far:

1) The class that deals with the $_SERVER variable, com.caucho.quercus.env.ServerArrayValue, called a method not supported on JRun (see the related entry for details). I just got rid of that call.

2) On my server, for some reason, com.caucho.util.RandomUtil fails when seeding SecureRandom() with System.currentTimeMillis() (the value isn't long enough). I just commented out the seeding part as SecureRandom sets itself up properly without it (according to the Java 6 docs anyway).

Now I have DokuWiki working fine and as soon as I can get a DB into play I can get phpBB working as well.

New mxAjax screencast - mxData

Arjun has added a screencast dealing with the mxAjax mxData tag:

http://www.techscreencast.com/screencast/mxajax_mxdata/mxajax_mxdata.html

PHP on JRun doesn't work just yet

A number of us have been following Sean Corfield's JSR-223 experiments with interest. The PHP flavour relies on Quercus, part of the Resin J2EE app server.

For some fun, I deployed Quercus next to CF 8 on the Multiserver install. As it turns out, this won't work with Quercus in its current form as JRun implements an older Servlet Spec (version 2.3). Quercus uses ServletRequest.getRemotePort(), which is part of the 2.4 version of the spec; this is the error that occurs with apps like phpBB and DocuWiki (and anything else that uses $_SERVER):

error javax.servlet.http.HttpServletRequest.getRemotePort()I [1]java.lang.NoSuchMethodError

Of course, Quercus could be rewritten for JRun to get around this.

mxAjax - closing a DomInclude from within the popup window

The mxAjax DomInclude (http://www.indiankey.com/mxajax/examples/mxDomInclude1.cfm) automatically provides a way to close the popup content (by clicking the link used to open it). However you might wish to have a link inside the popup that closes the DomInclude.

When you create the DomInclude, keep the created object:

function init() {
myDomInclude = new mxAjax.DomInclude( {source:"testlink"});
}

addOnLoadEvent(function() {init();});

Then in your included content, refer to the object you just created:

<a href="#" onclick="parent.myDomInclude.killPopup('external');">close</a>

mxAjax installation screencast

Arjun has created a screencast dealing with mxAjax installation:

http://www.techscreencast.com/screencast/mxajaxinstallation/mxajaxinstallation.html

mxAjax is a ColdFusion AJAX tookit providing everything necessary to use AJAX on ColdFusion. It's based on Scriptaculous/Prototype and uses JSON as the data transport.

Getting BlogCFC to work on BlueDragon

If you use CAPTCHA on your BlueDragon 6.2 based install of BlogCFC, you will probably have an issue with the LylaCaptcha code. The fix is detailed here:

http://ray.camdenfamily.com/forums/messages.cfm?threadid=9021AD4F-CDBB-773C-50E1F0EB6364795F

I modified captchaService.cfc at around line 265 to read:

<!--- Compute the next character lef tposition --->
<cfset aCharacter = CreateObject("Java","java.lang.Character")>
<cfset left = left + ((RandRange(150, 200) / 100) * graphics.getFontMetrics().charWidth(JavaCast("int",aCharacter.getNumericValue(char)))) />

CF7 seems to handle the different methods for getFontMetrics().charWidth() but BlueDragon 6.2 can't without some help.

UPDATE: added BD version info; this bug should be fixed in BD 7.0.

Become the hunted...

This blog was just added to CFHunt. I recommend you add yours too, and let Joshua know about any other sites that should be added.

Here's more info on CFHunt

Changed CGI.REQUEST_URI behaviour with CF7/Apache - A Solution

Those who have upgraded their Apache 2 CF servers to CF7 may have noticed that CGI.REQUEST_URI no longer contains the original request URL and query string when Apache does a 404 redirect to a CF page. For example, we just found this the hard way. In 6.1, the var would contain the original URL and the query string - it now contains the 404's URL and no query string info.

Well, there are other CGI vars available that do the trick: CGI.REDIRECT_URL and CGI.REDIRECT_QUERY_STRING. These contain all the original info on the request so you can get back to the way things worked before the upgrade.

http://httpd.apache.org/docs/2.0/custom-error.html

MXAJAX - mxData tag basics

The MXAJAX mxData tag is for those using MXAJAX who want complete control over the data (for integration with their own JS controls etc). The tag calls a CFC method or CF function (depending on your setup) and returns JSON corresponding to the CF return type.  In a future post I'll discuss each return type, but for now I'm going to demonstrate how to get at the info as the online example doesn't make it clear.

To parse JSON I recommend using the parser (strangely enough) rather that just evaluating it. It's all packaged with MXAJAX, so you can just go ahead in include it in your page.  Once it's been parsed, you can do with it what you want; the example below (a slightly modified version of the official mxData 1 example) writes the return into a span:

<html>
    <head>
        <title>Returning Data from CF page</title>
        <script type='text/javascript' src='../core/js/prototype.js'></script>
        <script type='text/javascript' src='../core/js/mxAjax.js'></script>
        <script type='text/javascript' src='../core/js/mxData.js'></script>
        <script type='text/javascript' src='../core/js/json.js'></script>
        <script language="javascript">
            var url = "<cfoutput>#ajaxUrl#</cfoutput>";
           
            function init() {
                new mxAjax.Data({
                    executeOnLoad:true,
                    paramArgs: new mxAjax.Param(url,{param:"id=1", cffunction:"getContent"}),
                    postFunction: handleData
                });
               
                function handleData(response) {
                    var myHTMLOutput = JSON.parse(response);
                    document.getElementById("myTargetSpan").innerHTML = myHTMLOutput;
                }
            }
           
            addOnLoadEvent(function() {init();});
        </script>
    </head>
    <body>
        <h1>Returning Data from CF page</h1>
        <span id="myTargetSpan"></span>
    </body>
</html>

The next post will be a more complicated example, doing something with a CF query.

Generating Barcodes with Barbecue and Coldfusion

If you need to generate a barcode within your web app, you have a few options. To keep it completely server-side (i.e. not dependent on the client's fonts etc) one option is the open-source java package Barbecue.

This is a graphics solution, so the server needs to properly support graphics. Windows servers will be fine; *nix servers may be fine and they may not. Some help with graphics on *nix:

(Thanks Massimo for putting the links in one place)

Now that's out of the way, onto Barbecue itself. If you have a servlet container you can use the servlet supplied with Barbecue. CF Enterprise will suffice, as will anything like Tomcat or a J2EE server if you want. However, you may not want to have a servlet that any old muggins can call, generating random barcodes at will. It is for this purpose I wrote a simple java wrapper:

package net.sourceforge.barbecue;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import net.sourceforge.barbecue.env.EnvironmentFactory;
import net.sourceforge.barbecue.linear.code39.Code39Barcode;

public class BarcodeCF {

public void main() {};

public ByteArrayOutputStream getCFBarcode (String data) {
Barcode barcode = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
EnvironmentFactory.setDefaultMode();
barcode = new Code39Barcode(data, false, true);
barcode.setBarWidth(2);
barcode.setDrawingText(true);
} catch (BarcodeException e) {
// Error handling
throw new RuntimeException(e);
}
try {
// Let the barcode image handler do the hard work
BarcodeImageHandler.outputBarcodeAsJPEGImage(barcode, bos);
} catch (IOException e) {
// Error handling here
throw new RuntimeException(e);
}
return bos;
}

public void writeBarcode(String data, String filePath) {
// TODO Auto-generated method stub
ByteArrayOutputStream whatever = new BarcodeCF().getCFBarcode(data);
try {
FileOutputStream fos = new FileOutputStream(filePath);
whatever.writeTo(fos);
fos.close();
}
catch (IOException e) {
// Error handling here
throw new RuntimeException(e);
}
}
}

You may want to change the kind of barcode you create; this example uses the Code39Barcode class.

Calling it is simple. If we've used createobject or some other method of getting an instance of net.sourceforge.barbecue.BarcodeCF called BarcodeCF:

<cfset BarcodeCF.writeBarcode("Barcode Text Here","/barcode/location/here.jpg")>

The BarcodeCF class will write the image file to the desired location.

Somebody who's paying attention will be thinking, well why not just write the CF equivalent of that Java. Yes, you can if you have access to get the Barbecue jar into the classpath on the machine, but this gives you a class you can use with a dynamic classloader, like Spikes method.

 

 

ColdFusion Community Consensus page layout drafts

First drafts of the ColdFusion Community Consensus pages are now available for comment:

www.bifrost.com.au/c3/

www.bifrost.com.au/c3/topic.cfm 

The CF Best Solutions Comparison App

On CF-Talk, the idea of an application that allows people to rate solutions to CF-Related problems came up. For example, which framework is best, which forum app, which webserver etc. User comments and a star rating based on votes were put forward as features. Here's the CF-Talk thread: http://www.houseoffusion.com/cf_lists/messages.cfm/forumid:4/threadid:46751

If you have a requirement for this app, comment here or post in the forum: http://www.bifrost.com.au/forums/messages.cfm?threadid=67DC9508-DBFF-39AD-4B0EDD65F06970FD

Installing CFAJAX - Paths explained

The official CFAJAX installation steps are at http://www.indiankey.com/cfajax/installation.asp.

However, when installing CFAJAX, no CFADMIN changes are necessary if a few paths are modified to suit the chosen installation. I currently have three versions of CFAJAX on my dev machine, all of which work indepentently if the right files point to the right places. Below I use {webroot} to indicate the root web folder on your webserver.

The installation steps are as follows:

1) Download the CFAJAX version of your choice from http://www.indiankey.com/cfajax/.

2) Inside the zip file you will see a folder named after the version you downloaded (e.g. /cfajax.1.3). Open up this folder and put the various contents into the chosen destination on your server. Assuming, for example, a choice of {webroot}/cfajaxtest, with 1.3 that now gives folders {webroot}/cfajaxtest/app, {webroot}/cfajaxtest/core, {webroot}/cfajaxtest/examples and {webroot}/cfajaxtest/utility (with various files and folders below these). Note that the app, examples and utility folders should be left out of a production server install.

At this point you will note that the examples do not work. Go on, try one. No problem - this is where the path alterations come in. Let's get the first example working; {webroot}/cfajaxtest/examples/text.htm in my case.

3) Alter the following code to match your setup:

* In the file you are trying to run ({webroot}/cfajaxtest/examples/text.htm for this example), the core CFAJAX includes need altering:

<script type='text/javascript' src='/ajax/core/engine.js'></script>
<script type='text/javascript' src='/ajax/core/util.js'></script>
<script type='text/javascript' src='/ajax/core/settings.js'></script>

all become

<script type='text/javascript' src='/cfajaxtest/core/engine.js'></script>
<script type='text/javascript' src='/cfajaxtest/core/util.js'></script>
<script type='text/javascript' src='/cfajaxtest/core/settings.js'></script>

If you want to use a relative path instead, go ahead (but this means you can't just copy and paste beween pages in different directories any more).

* In {webroot}/cfajaxtest/core/settings.js

_cfscriptLocation = "http://localhost/ajax/examples/functions.cfm";

must change to the web location of your CF functions file. In this case it is {webroot}/cfajaxtest/examples/functions.cfm, so I can use

_cfscriptLocation = "/cfajaxtest/examples/functions.cfm";

You can use the fully qualified path with http://blahblah (with a port number if necessary; remember that CF developer runs on port 8500 by default) if you want, but I don't. A purely relative path will cause you problems, since a relative path that is right for one file will be wrong for another.

* In the CF file to which we just pointed, change the top line

<cfinclude template="/ajax/core/cfajax.cfm">

to point to the correct location of the core/cfajax.cfm file

<cfinclude template="../core/cfajax.cfm">

Note that I used a relative location here; absolute locations only work if you have a cf mapping to the location (which I'm assuming we don't).

That's it - the example is now working (yes, I just did a fresh install as I wrote this, as a test). To get other examples working, the example file JS script locations need to be edited too. The "app" directory examples, and some of the other examples like suggest also need some extra tweaking - just check the paths as above and all will be well (although in the case of the "suggest" example, some people have other problems, related to the fact that it uses application variables or some other hassles).

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.5.1.