Handy Hint for running TestBox Tests

Last year I migrated my ColdFusion unit tests from MXUnit test to TestBox, and it’s been a great decision.

While I’m developing I generally run the test I’m working on in my web browser, calling the runRemote method, as shown below:

http://localhost/tests/MyTest.cfc?method=runRemote

However it’s generally very inconvenient to have to type in the URL for each test, and I’ve been looking for a better way to run them.

Today I realised that with directory browsing enabled in Apache, and rewrite rule I can easily navigation to the file in my browser and run it with only a few mouse clicks.

Here’s the rewrite rule I use:


RewriteCond %{REQUEST_URI} ^/tests/(.*).cfc$
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/(.*)$ $1?method=runRemote [R=301,L]

Now I simply call up http://localhost/tests in my browser, then navigate to the file I’m working on, click on it, and the tests run.

I thought I’d share this tip in case it’s of use to others. Please let me know if you find it useful, or have any questions.

Slow Oracle Datasource Creation in Adobe ColdFusion 11

While preparing to upgrade our production server from ColdFusion 9 to ColdFusion 11, I noticed some terribly poor performance under load testing. I’ve spent a considerable amount of time investigating the cause, and have tracked it down to the amount of time it was taking ColdFusion to open a connection to Oracle.

To be clear, this may not be a problem with ColdFusion itself. However the issue only became apparent when we started using CF11.

Our environment is ACF11 with Hotfix 3, deployed as a war file on Apache Tomcat 7.0.57. The Java version is 1.8.0_25 and the Operating System is RHEL 5.x (64 bit). Our database is Oracle 11g.

Here’s the basic test case to reproduce the issue. Thanks to @TransientAaron on Twitter for the assistance with this.

Assuming you have an Oracle datasource called “test”, create a new directory under your web root and add the following files:

Then use Apache JMeter to hit the page with multiple concurrent request (I gave it 2 iterations of 200 threads with a ramp up period of 25 seconds).

Here’s the initial results:

Graph Results - Test Server - No JVM Parms

Only a handful of the requests actually completed before timing out after 60 seconds.

At this point I opened the CF monitor, and saw there were actually 25 Oracle connections open. So I took a look at what would happen if I ran it again:

Graph Results - Test Server - No JVM Parms - 2nd run

Note that this second graph is cumulative. The bit to look at here is the almost solid black line near the bottom, showing the responses to the majority of requests now taking only a few hundred milliseconds.

So I think it’s fair to say that I’ve proved that establishing connections is bad (or much worse than bad). But once they’re established, things are fine.

So what is happening here? After a lot of fruitless searching for results related to ColdFusion and slow Oracle connections, I found a question on Stack Overflow relating to slow connections in Java, which provides us with the solution: http://stackoverflow.com/questions/5503063/oracle-getconnection-slow.

Apparently, creating Oracle connections depends on generating random numbers, and that is sloooooow. BUT, we can trade off (a bit) of randomness for (a lot) of speed by using an alternative generator. This is done by adding in the JVM parameter:

-Djava.security.egd=file:/dev/./urandom

(credit: http://stackoverflow.com/questions/137212/how-to-solve-performance-problem-with-java-securerandom).

@elishdvorak also pointed out on twitter that the performance of cfhttp can similarly be affected:

So let’s repeat our tests with this new JVM parameter.

First run:

Graph Results - Test Server - with JVM Parms

(note that the graph scale has changed considerably, because it is magnitudes faster)

Second run:

Graph Results - Test Server - with JVM Parms - 2nd run

I think we’re now ready to put CF11 into production.

CFScript Hightlighting on Adobe Brackets

Here’s a patch I made recently to enable CFScript highlighting to work on Adobe Brackets

Install the CFBrackets extension from the Brackets Extension Manager (File -> Extension Manager on windows).

Select Help -> Show Extensions Folder. Navigate to user/cf9.cfbrackets.org (‘cf9’ may be different depending on what flavour you have installed).

Download and unzip my patch from https://dl.dropboxusercontent.com/u/26388856/cfbrackets.zip into this folder.

Restart brackets (Debug -> Reload with extensions)

This will now use a modified version of Haxe mode to highlight blocks inside .cfm files, and it will also open .cfc files in this mode. For tag based CFC’s you’ll need to change to “CFML” in the status bar.

The CFBrackets should give some code completion for tags, but so far there’s no code completion for cfscript. It may be something I look at next, depending on whether I end up using Brackets for CFML and/or there’s much interest from others in it. Similar Haxe mode is “near enough” for basic syntax highlighting, but there’s plenty that can be improved.

My intention is to submit this is a pull request to CFBrackets, but I want to play with it a bit first to see what issues arise.

Give it a try and let me know what you think.

Bound Functions – cfml

Following on from the last blog post – we can observe the same behaviour in CFML:

Outputs (on Railo 4.2.1.000 final and ACF 11):


Function says: 5
Function says: 5
Function says: 5
Function says: 5
Function says: 5

Now it looks like there’s been some discussion about this (https://issues.jboss.org/browse/RAILO-3099), but I can’t follow what was decided upon…

EDIT:

I found on the Railo Google Group how to do this.

The solution isn’t particularly pretty, but it works:

Output:

Function says: 0
Function says: 1
Function says: 2
Function says: 3
Function says: 4

JavaScript – bound functions

A quick post to share something I came across last night while tinkering with some JavaScript for a utility I created.

I was creating a number of functions that would later been called on certain events. Each of these functions was essentially the same, but was dependent upon the value of certain variables at the time they were initialised.

My first attempt looked something like this:

View on JSFiddle

When I ran it I expected to see the numbers 0,1,2,3,4 printed, however I got this output:

Function says: 5
Function says: 5
Function says: 5
Function says: 5
Function says: 5

Which makes sense when you think about it (the global variable j has value of 5 after the array is initialised), but this was definitely not what I wanted.

In order to get the result I wanted, I needed to create a bound function, which is associated with the state of j at the time it is added to the array. My next attempt, inspired by the documentation at MDN was as follows:

View on JSFiddle

The output is now:

Function says: 0
Function says: 1
Function says: 2
Function says: 3
Function says: 4

I also realised this could be achieved using a closure, as follows:

View on JSFiddle

This also gives the output:

Function says: 0
Function says: 1
Function says: 2
Function says: 3
Function says: 4

I think this code is a bit neater.

Nothing groundbreaking here, but it gave me an interesting insight into what happens when you start passing functions around. In particular functions that refer to mutable state.

Adobe Brackets on Fedora

UPDATE: (July 2016)
An RPM package now exists for Adobe Brackets on Fedora and CentOS at

https://copr.fedorainfracloud.org/coprs/mosquito/brackets/

This is now the recommended way to install Brackets on Fedora or CentOS. The post below is kept for reference only.

I noticed some time ago that Adobe Brackets was available for Ubuntu. Today I found out that it’s also very simple to get it working on Fedora.

I found out how to do this from this blog post but also found a few extra steps I needed to take, which I’m outlining here.

Here’s how I did it:

Download the appropriate Debian/Ubuntu .deb file from https://github.com/adobe/brackets/releases (in my case this was Brackets.Release.0.41.64-bit.deb). I’ll assume you have downloaded this to ~/Downloads/Brackets.Release.0.41.64-bit.deb.

The following steps will allow you to install the .deb file on Fedora (and potentially other distros like CentOS):


$ cd ~
$ mkdir brackets-tmp
$ cd brackets-tmp
$ ar vx ~/Downloads/Brackets.Release.0.41.64-bit.deb
$ tar xf data.tar.xz

You should now have the following in your brackets-tmp directory:


$ ls
control.tar.gz data.tar.xz debian-binary opt usr

Copy these to the correct location using the following commands:


$ sudo cp -R opt/* /opt/
$ sudo cp -R usr/* /usr/

At this point brackets is installed, but it will not run due to it not being able to find libudev.so.0.

I found some solutions to this at on the following page https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0, and opted for the first suggestion.


$ cd /opt/brackets/lib
$ sudo ln -s /lib64/libudev.so.1 ./libudev.so.0
$ cd ~
$ mkdir bin (only necessary if you don't already have a ~/bin dir)
$ touch brackets
$ chmod a+x brackets

Then in a text editor, open ~/bin/brackets and paste in the following:


#!/bin/sh
LD_LIBRARY_PATH=/opt/brackets/brackets/lib:$LD_LIBRARY_PATH /usr/bin/brackets $

That’s it. You can now launch brackets from a terminal using the command:

$ ~/bin/brackets &

Here’s how it looks:

Bracketson Fedora  Screenshot

ColdFusion Builder – “Thunder” – First Impressions

Late last week, Adobe announced the availability of Beta versions of ColdFusion 11 (code name “Splendor”) and ColdFusion Builder 3 (code name “Thunder”).

Although I mostly use Emacs now for my CFML coding, I decided to check out Thunder to see if it was any improvement on previous versions of CF Builder (which to my mind have been only adequate, at best).

After running the installer the first thing that I noticed was the new option to install a “Bundled ColdFusion server”:

Thunder1

This feature is a nice surprise, and I think it’s a good addition from Adobe. One of the criticisms levelled at CF in the past has been the difficulty of installing it and this is a positive step, especially for people new to CF. I can even see some more experienced users finding it useful as well. I’m definitely more tempted to play with this bundled version of CF11 than to install the full beta at this stage.

Once the install finished (and it was quite a wait…), it was pleasing to see that Builder now runs on the current version of Eclipse (Kepler – 4.3.1). The “Getting Started” page is well out of date though, and I hope that will be addressed before the final release:

Thunder2

After dismissing the Getting Started page, you’ll notice that the bundled server is preconfigured in the “CF Servers” view. Getting it running is as simple as clicking the “Start Server” play button. By right clicking on the server, you can launch the admin console. It’s both easy for a newcomer, and painless without feeling “dumbed down” for a more experienced user.

Thunder3

You’ll also notice a new “PhoneGap Status” tab – I have no idea what this is for yet.

The toolbar features a new button – “New ColdFusion Mobile Project”, with a picture of a phone on it:

Thunder4

I decided to click on this and give it a quick try. This brought up a wizard that offered a “MASTER-DETAIL” project, using JQuery Mobile. After following it through, I was presented with a project containing a single file (index.cfm), which was nicely hooked up to to the bundled server:

Thunder5

The generated index.cfm contains only a single CF tag. Here is expected to see the cfclient madness we have all been dreading, but it in fact contains only a single cf tag:

<cfclientsettings detectdevice="true" enabledeviceapi="true"/>

The rest of the file is standard HTML and JavaScript.

Running the project (by selecting index.cfm and pressing the play button in the toolbar) launches your browser and the skeleton it’s created:

master-detail

Not bad.

The only other thing I have really done so far is to check whether this bug relating to typing over auto-inserted characters has been fixed, and I’m very pleased to see that it no longer exists.

So overall my first impressions of “Thunder” – admittedly after only a very brief look – are that this is actually looking fairly decent. I’ll continue to tinker with it and see how I feel about it after spending some more time with it.

Windows Terminal Replacements

Recently on twitter I saw a link to a blog post by Jim Priest about Windows Terminal replacements.

As much as I like Linux, the reality is that I spend a good deal of my work day in Windows, and I don’t see that changing in a hurry. Until reading Jim’s post, I had been using Console2 as a replacement for Windows’ cmd.exe. It’s been handy, but I wasn’t completely sold on it.

So I decided to give ConEmu and Clink a try. My first reaction was that ConEmu is pretty damn ugly, but I’ve managed to make it look reasonable by changing the font to Consolas (size 18) and changing the Anti-aliasing setting to Clear Type. I also hid the status bar.

Clink gives some super nice stuff – in particular the ctrl-r history searching I love in bash. But I also want to be able to use GNU tools like find and grep. To me, these are the things that make the Linux command line so much superior.

That’s where gnuwin32 comes in. I realise cygwin also gives you this stuff, but I gave it away a while ago for reasons I can’t completely remember (various scripts borking at Windows paths I think – I’m sure there’s a way around it, but basically I just came to realise I didn’t actually need a full on bash shell – it was just the GNU tools I was after).

I like to load gnuwin32 to my path for interactive sessions only. To achieve this in ConEmu I had to make a few customisations. (Most of this is taken from a StackOverflow question about integrating Git Bash with ConEmu. I followed this blindly so it might not be the best way, but it works. ;-))

Firstly I created a new entry under ConEmu’s Features -> Integration settings, shown below:

Next, I created a new task in Startup -> Tasks:

This task calls a script (init-gnuwin32.cmd) which adds gnuwin32 to the path then loads cmd.exe (which is actually now an alias for Clink…). The file looks like this:


@ECHO OFF
set PATH=C:\gnuwin32\bin;C:\gnuwin32\include\glibc;%PATH%
cmd

Now after launching ConEmu you have a terminal with extra goodness, such as the ctrl r history searching, courtesy of Clink:

And you GNU goodies like find, grep, ls, etc, courtesy of gnuwin32.

It’s no *nix, but it’s pretty decent, yes?

ColdFusion / JBoss Issue – “class file has wrong version 49.0, should be 48.0”

While playing with a Remote Proxy example in ColdSpring 2 tonight in my previously mentioned CF9/JBoss setup I ran into the error below:

"Error","http-127.0.0.1-8080-2","01/05/12","22:39:39","coldspring-remote-example","coldfusion.jsp.CompilationFailedException: Errors reported by Java compiler: /home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/WEB-INF/cfusion/stubs/WS-316894903/coldfusion/xml/rpc/CFCInvocationException.java:10: cannot access java.rmi.RemoteException bad class file: /usr/java/jdk1.6.0_26/jre/lib/rt.jar(java/rmi/RemoteException.class) class file has wrong version 49.0, should be 48.0 Please remove or make sure it appears in the correct subdirectory of the classpath. public class CFCInvocationException extends org.apache.axis.AxisFault implements java.io.Serializable { ^ 1 error . The specific sequence of files included or processed is: /home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/examples/quickstart/remote/index.cfm, line: 20 "
coldfusion.server.ServiceRuntimeException: coldfusion.jsp.CompilationFailedException: Errors reported by Java compiler: /home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/WEB-INF/cfusion/stubs/WS-316894903/coldfusion/xml/rpc/CFCInvocationException.java:10: cannot access java.rmi.RemoteException
bad class file: /usr/java/jdk1.6.0_26/jre/lib/rt.jar(java/rmi/RemoteException.class)
class file has wrong version 49.0, should be 48.0
Please remove or make sure it appears in the correct subdirectory of the classpath.
public class CFCInvocationException extends org.apache.axis.AxisFault implements java.io.Serializable {
^
1 error
.
at coldfusion.xml.rpc.XmlRpcServiceImpl.registerWebService(XmlRpcServiceImpl.java:319)
at coldfusion.xml.rpc.XmlRpcServiceImpl.getWebService(XmlRpcServiceImpl.java:496)
at coldfusion.xml.rpc.XmlRpcServiceImpl.getWebServiceProxy(XmlRpcServiceImpl.java:450)
at coldfusion.tagext.lang.InvokeTag.doEndTag(InvokeTag.java:449)
at cfindex2ecfm1931456168.runPage(/home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/examples/quickstart/remote/index.cfm:20)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2722)
at cfApplication2ecfc135565788$funcONREQUEST.runFunction(/home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/examples/quickstart/remote/Application.cfc:22)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:491)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:337)
at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:88)
at coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:280)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:356)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:94)
at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.CfmServlet.service(CfmServlet.java:200)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:662)
Caused by: coldfusion.jsp.CompilationFailedException: Errors reported by Java compiler: /home/andrew/cfdev/jboss-5.0.1.GA/server/devserver/deploy/cfusion.ear/cfusion.war/WEB-INF/cfusion/stubs/WS-316894903/coldfusion/xml/rpc/CFCInvocationException.java:10: cannot access java.rmi.RemoteException
bad class file: /usr/java/jdk1.6.0_26/jre/lib/rt.jar(java/rmi/RemoteException.class)
class file has wrong version 49.0, should be 48.0
Please remove or make sure it appears in the correct subdirectory of the classpath.
public class CFCInvocationException extends org.apache.axis.AxisFault implements java.io.Serializable {
^
1 error
.
at coldfusion.jsp.JavaCompiler.compileClass(JavaCompiler.java:152)
at coldfusion.xml.rpc.XmlRpcServiceImpl$2.run(XmlRpcServiceImpl.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at coldfusion.xml.rpc.XmlRpcServiceImpl.registerWebService(XmlRpcServiceImpl.java:270)
... 55 more

I had this example running fine in CF9 on JRun / Windows 7 previously so at first I thought this must be something specific to my JBoss install.

After a bit of searching, I found a post on the Adobe Forms that helped me understand what was going on.

It seems there is a file “tools.jar” in ColdFusion’s WEB-INF/cfusion/lib dir which is incompatible with the JDK I was running (Oracle JDK 1.6.0_26). I replaced this file with the tools.jar from <JAVA_HOME>/lib and restarted my server and the problem went away.

I’m not exactly sure why this file was incorrect in my JBoss install – (the file was 4.9M in size as opposed to 13M in the new version), but I thought I’d share this workaround in case it helps anyone else, or I need to refer to it later.

Adobe ColdFusion 9 on JBoss

A long time between blog posts but I thought this was worthy of a quick one.

I’m using Fedora 16 as my workstation at the moment, and because of some difficulties I encountered when running Adobe ColdFusion 9 on JRun, I decided to give JBoss a try.

I downloaded JBoss and CF9 and followed the instructions for Deploying ColdFusion 9 on JBoss Application Server and fairly quickly had a working system.

Then I wanted to patch it with the awesome Unofficial Updater 2 but realised first I needed to install ColdFusion 9 Updater 1 to get to 9.0.1.

After downloading the updater, I attempted to run it against my exploded war, deployed at <JBOSS_HOME>/server/cfusion/deploy/cfusion.ear/cfusion.war however the updater failed to complete, giving the message “Selected EAR/WAR archive is invalid”.

The work around this, I logged into the ColdFusion Administrator, and under the Packaging & Deployment -> J2EE Archives was able to export my current project as a war file, which I could then patch with Updater 1, and redeploy. After that, the Unofficial Updater ran fine, brining me up to the current Hotfix.

I thought I’d share this in case it helps someone down the track, or I need to refer back to it.