While upgrading to ColdFusion 10u18 (APSB15-29) in my development environment, I immediately started having a problem with the CF Administrator. The topnav.cfm was generate errors (I wasn't seeing the normal icons at the top right) and any attempt to go to the Server Update > Updates page was throwing one of the following errors:
java.lang.NullPointerException
at coldfusion.server.UpdateService.init(UpdateService.java:127)
at coldfusion.server.UpdateService.<init>(UpdateService.java:118)
at coldfusion.server.UpdateService.getInstance(UpdateService.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:97)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2428)
or:
Element UPDATESETTINGS.UPDATESERVICE is undefined in a Java object of type class [Ljava.lang.String; referenced as ''
The error occurred in C:/work/cf10_final_hotfix/cfusion/wwwroot/CFIDE/administrator/updates/index.cfm: line 103
Called from C:/work/cf10_final_hotfix/cfusion/wwwroot/CFIDE/administrator/updates/index.cfm: line 52
Called from C:/work/cf10_final_hotfix/cfusion/wwwroot/CFIDE/administrator/updates/index.cfm: line 51
Called from C:/work/cf10_final_hotfix/cfusion/wwwroot/CFIDE/administrator/updates/index.cfm: line 1-1 : Unable to display error's location in a CFML template.
After working with Adobe, it was determined that the {cf_install_home}/{instance_name}/lib/neo_updates.xml was corrupted and missing the <defaulturl> element. It appears this file was corrupted in the version of hotfix_018.jar that was originally available. I just re-downloaded the JAR file and the problem appears to be resolved, so I think they already fixed the problem.
The fix was to replace the neo_updates.xml with the following:
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<update autocheck="false" checkinterval="10" checkperiodically="false">
<url>
http://www.adobe.com/go/coldfusion-updates
</url>
<defaulturl>http://www.adobe.com/go/coldfusion-updates</defaulturl>
<notification>
<emaillist/>
</notification>
</update>
</settings>
And then restart the ColdFusion service.
Hopefully no one else runs into the issue, but if you do, hopefully this helps someone!
There's not a ton of information out there on using ColdFusion Components from within Java, so I wanted to document a problem I was having. I'm in the process of evaluating using Drools as a Rules Engine to use within ColdFusion. One of the problems you face in using Drools, is you need to represent your CFC in a way that Drools can work with it. This means you need to do a couple of things:
Setting all this up was pretty straight forward.
The problem that I was running into, was I could never successfully call the "setter" on a CFC object that was created dynamically using the "accessors='true'" option on my CFC.
Here was my very simple CFC:
component output="false" persistent="false" accessors="true" { property name="name" type="string" ; property name="age" type="numeric" default="-1" ; property name="valid" type="boolean" default="true" ; }
The problem is, every time I'd try to call the setter on my dynamic proxy item, I'd see an like "java.lang.ClassCastException: coldfusion.runtime.TemplateProxy".
The Java interface I was using, looked like this:
public interface ApplicantInterface { public String getName(); // automatic setters, return "this" which is a reference to the proxy object public void setName(String name); public int getAge(); // automatic setters, return "this" which is a reference to the proxy object public void setAge(int age); public boolean getValid(); // automatic setters, return "this" which is a reference to the proxy object public void setValid(boolean valid); }
Accessing the getters() worked as expected, so I knew there was something in the way the setters were working that was causing a problem.
After dumping out the metadata for my CFC, I finally discovered the issue.
When CF10 automatically creates setters, the return type on the objects is not void, but instead is a references to the CFC itself.
There are two ways to resolve the problem:
I decided to use option #2. Here's what my final interface looked like:
public interface ApplicantInterface { public String getName(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setName(String name); public int getAge(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setAge(int age); public boolean getValid(); // automatic setters, return "this" which is a reference to the proxy object public coldfusion.runtime.TemplateProxy setValid(boolean valid); }
In order to use a return type of "coldfusion.runtime.TemplateProxy", you'll need to make sure to add the cfusion.jar to the classpath when compiling your code. For example:
javac -g -cp {{ColdFusion 10 Install Folder}}\cfusion\lib\cfusion.jar -d ./bin/ ./src/*.java
Hope this helps someone else in the future!
Outside of Rob Brooks-Bilson's blog, there's not a lot of information on digging down into the ColdFusion's internal implementation of ehCache. I recently spent some time getting the built-in ehCache implementation to replicate across multiple nodes using RMI. Overall the process isn't that difficult, but due to the lack of information out there, it took me much longer to figure out the exact steps necessary to get things work.
NOTE: ColdFusion 10 added the ability to specify a specific ehcache.xml file on a Per Application basis using the this.cache.configfile value. Unfortunately, you can not use this method to configure replication. You will need to replace the default ehcache.xml that ships with ColdFusion.
<!-- In order for this rule to work, you must: * Configure the operating system to use multicast * Open up UDP on port 4446 in the firewall --> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1,multicastGroupPort=4446,timeToLive=1" propertySeparator="," />
<!-- In order for this rule to work, you must: * Open up TCP on port 40001 & 40002 in the firewall --> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="port=40001,remoteObjectPort=40002" />
<!-- Mandatory Default Cache configuration. These settings will be applied to caches created programmtically using CacheManager.add(String cacheName). The defaultCache has an implicit name "default" which is a reserved cache name. --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="86400" timeToLiveSeconds="86400" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="3600" memoryStoreEvictionPolicy="LRU" clearOnFlush="true" statistics="true" > <!-- apply the replication listener to all caches created by ColdFusion --> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </defaultCache>
In order for this all to work, your server must be configured for multicast. In Redhat, this isn't a standard config, so there's some additional steps you may need to do.
While ehCache does allow you to set up a peer-to-peer configuration, it's very unwieldy and won't work well with ColdFusion, unless you explicitly use named regions in all your code. The reason multicast is really required, is because it's the only method in which ehCache replication works without having to manually specify the name of each region to replicate.
I hope this helps someone out!
I'm working on a jQuery Mobile project at the moment and I was not happy with the way that jQM was handling errors from the server. Our application's error handling code sets the HTTP's status code to 500. We do this, because it makes it much easier to track problematic requests. The issue we were running into was that jQM wants to just display a "Error Loading Page" dialog whenever it detects a 500 status code.
In order case, our error pages are formatted for use with jQM, so we really wanted to display the error, just as if the page had successfully loaded. We could have returned a status code of 200, but we wanted to respond with the correct status code.
To work around this issue, jQM has a "pagecontainerloadfailed" event which it fires whenever a page fails to load. Unfortunately, it's not very clear on how to use this event to handle the request as a successful page load. You can use the event.preventDefault() to cancel the default behavior, but how do you handle it as a successful page load?
Well that took some digging, but I finally found a solution that appears to work really well:
// if an error occurs loading the page, the server will make sure we have a properly formatted document $(document).on("pagecontainerloadfailed", function(event, data) { // if the error response is formatted for jQM, it'll have a custom response header that flags to use the standard page handler if( data.xhr.getResponseHeader("X-jQueryMobile-HasLayout") === "true" ){ // let the framework know we're going to handle things. event.preventDefault(); // load the results as if they had succeeded $.mobile.pageContainer.data("mobilePagecontainer")._loadSuccess(data.absUrl, event, data.options, data.deferred)(data.xhr.responseText, "success", data.xhr); } });
What this code does is look for a custom response header of "X-jQueryMobile-HasLayout" and if it sees this header is true, will then stop the default behavior and load the page as if it detecting a 200 status code.
I decided to use a custom header to determine if I should run the code or not, because then any unexpected error that occurred outside our framework would still behave the way jQM acts by default. However, if our application error handler runs, we set the header to "true". This tells jQM that the resulting HTML should be in a format that jQM needs to render the page.
I ended up posting this basic solution in GitHub 6866 - Add documentation for presenting server generated error pages and Alexander Schmitz, a jQuery Foundation member, confirmed this is the basic approach they plan on implementing in the future.
While this shouldn't affect most users (and by and large is probably a good thing), I noticed that Firefox 29 started automatically aborting requests after 300 seconds if the server has responded. As a developer, I often have test scripts that can take a very long time to run to completion, so this change was causing me some issues running a script to validate some data.
The change appears to be with the network.http.response.timeout setting in the about:config menu. It appears this setting used to be undefined, but it now set to 300.
It appears setting the value to 0 will reset the behavior so that Firefox will no longer automatically abort requests. Once I made this change, my test script starting running successfully (it's final runtime was about 6 minutes.)
Anyway, I don't expect this to affect most people. I think the impact is going to be felt mostly by developers who might have unit tests that run via a browser or other test scripts which could take a very long time to run.
One common pattern I've seen in usability, is that users don't always have great control over their mouse. It's easy to accidentally overshoot a target area with you mouse, which is really frustrating with things like nested dropdown menus, where accidentally mousing away from a target area may end up collapsing/closing the open menu.
Giva's recently released the MouseIntent jQuery Plug-in which aims to give developers a way to control this behavior. It works by monitoring an invisible border around the element to see what the user appears to be doing. If a user quickly moves back into the original element, then then no mouseaway event is ever fired. The plugin has a number of settings that allow you to control the behavior—such as monitoring whether or not the user is still moving the mouse in the invisible border area.
I've used the plugin in one of our dropdown menus that has nested menus and it's really helped to improve our user's experience.
Giva has released released a new plugin (Maskerade jQuery Plug-in) which can convert a normal text field into a power date mask input field. The plugin supports a large array of date masks (even quarters) and even supports copy/paste. Here's a list of some of it's key features:
We have actually been using this plugin in production for a long time with great success.
We recently discovered an issue in ColdFusion 9+ when images that were temporarily stored in the RAM disk, but later removed would start throwing exceptions in the application.log, exception.log and coldfusion-out.log. The code itself would run just fine, so the issue is a bit masked because you won't see it unless you're monitoring your log files.
What we were seeing was a lot of errors like the following being thrown throughout our logs:
Could not read from ""ram:///797C39D0-CAE4-21F9-D573CFDC3FE7482E.jpg"" because it is a not a file.
When we tracked down why the log entries were being written, we discovered that the following workflow was causing the problem:
It was when trying to write the image to disk, we'd start to see 3 exceptions being logged, but the code would generate the expected output. What appears to be happening, is that internally ColdFusion is trying to access the original "source" of the file for some reason.
What we did to fix the issue, was to return a new copy of the image using imageNew(imageGetBufferedImage(source)). What this does is create a copy of the image that no longer references any file on disk, but creates an image purely in RAM.
I'm sure this isn't a very common problem, but if you found that you're using Dave Ferguson's ColdFusion 9 PNG image processing fix you may find yourself running into this issue.
I've filed a Bug #3690487 with Adobe. This problem does affect ColdFusion 9 and 10, so if you think Adobe should fix it, make sure to vote it up!
Yesterday I ran into a very strange bug with ColdFusion 9 and I thought it worth blogging about. I think this probably affects earlier versions of the product, but I haven't tested to confirm.
What was happening is whenever I tried executing a specific query, I was seeing the following error:
Invalid data coldfusion.sql.QueryColumn@540350 for CFSQLTYPE CF_SQL_INTEGER
The error had me very perplexed, because the variable that it was complaining about I knew was an integer. When displayed on screen, it showed as an integer. It would even return true when passed to the isNumeric() function. After spending way to much time on the issue, I finally track down the root problem.
What was happening is the variable's value was coming from a ColdFusion query, that I was converting to a structure. Since the query was designed to return at most a single row, I was using the shortcut notation of queryName.columnName to update the variable. I've used this shorthand plenty in the past, because it will either display the value in the first row (when not inside a <cfoutput query=""> or <cfloop query="">) or it will display an empty string if the query returned no rows. This has generally worked fine for me, but apparently this ends up storing a reference to the query object, instead of copying the value directly—which <cfqueryparam /> did not like.
The fix was pretty straightforward, all I need to do was to change my code to reflect grabbing the value from the first row of the dataset: queryName.columnName[1].
My original code looked like this:
<cfquery name="data" attributeCollection="#Application.dsn.getAttributes()#"> select Name, Email, Phone from Employee where EmployeeId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.EmployeeId#" /> </cfquery> <!---// get the column names from the query //---> <cfset columns = getMetaData(data) /> <!---// return the preferences as a struct //---> <cfloop index="column" array="#columns#"> <cfset results[column.Name] = data[column.Name] /> </cfloop>
All I did was change the code to:
<cfquery name="data" attributeCollection="#Application.dsn.getAttributes()#"> select Name, Email, Phone from Employee where EmployeeId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.EmployeeId#" /> </cfquery> <!---// get the column names from the query //---> <cfset columns = getMetaData(data) /> <!---// return the preferences as a struct //---> <cfloop index="column" array="#columns#"> <cfset results[column.Name] = data[column.Name][1] /> </cfloop>
NOTE:You'll notice the only change is the [1] after data[column.Name].
What I learned from this is that I shouldn't trust using the queryName.columnName shorthand—at least not outside a cfoutput/cfloop query block. Instead I need to make sure to reference an actual row from the query.
A common practice when building applications in ColdFusion is to utilize the onError event in the Application.cfc in order to track and log errors that occur in your application, so that you can track down the problems and resolve them. However, there's one type of error that can often escape your onError event handler—and that's requests that are timing out.
First, just some background information on how ColdFusion handles "request timeouts". If the server (or current page) is designed to timeout after 30 seconds, ColdFusion will not simply stop executing when the length of the running request gets to 30 seconds. Instead there are specific operations in ColdFusion1 that check the current running time to see if the request should be halted. That's why if you have a SQL query that takes 45 seconds to run, the page doesn't simple stop after 30 seconds. Instead the query will finish executing and your code won't halt execution until it tries to execute logic that would check the current execution runtime.
NOTE:This also why when ColdFusion reports the line that took to long to run, it often isn't pointing to the actual line of code that was the real culprit, but a tag like <cfoutput>—which is just displaying the information.
Now that you hopefully have a better understanding of when request timeouts are thrown, let's examine why the Application.onError might not run.
The problem isn't that the Application.onError event doesn't get fired—it does. The problem is that because your page has already been running longer than the allotted time, as soon as ColdFusion encounters one of the operations that checks to see if the page should timeout, it will throw a second error—which effectively breaks your onError event.
The way you can get around this problem is by tracking the current execution timing in your Application and then having your Application.onError immediately adjust the page's request timeout setting as it's first line of logic. Since the <cfsetting /> tag does not check against the current execution time, this allow you to add a buffer to your onError request so that the event can run to completion.
Here's a sample snippet of an Application.cfc which will allow the Application.onError event to run for another 10 seconds—regardless of how long the current template has been running:
<cfcomponent output="false"> <!---// track the starting execution time //---> <cfset executionStartTime = getTickCount() /> <!---// onError //---> <cffunction name="onError" returnType="void" output="true"> <cfargument name="exception" type="any" required="true" /> <cfargument name="eventName" type="string" required="true" /> <!---// declare local variables //---> <!---// take the current time the request has been running and add 10 seconds, to attempt to run the onError handler succesfully //---> <cfsetting requesttimeout="#(((getTickCount()-executionStartTime)/1000)+10)#" /> <!---// insert error code handling here //---> </cffunction> </cfcomponent>
I've been using this trick to help make sure any requests that are timing out are fully logged, so I can evaluate the issue and look for ways to fix the root problem.
1 Unfortunately I do not have a list of which operations in ColdFusion do an integrity check on the request lifecycle. I do know that <cfloop>, <cfoutput>, <cfquery> and most complex cf-based tags do check the current running time against the page's request timeout setting.
Today a new version of the jQuery Linkselect Plug-in was released. The new version under went a ton of changes from the previous version and includes a much better CSS skinning mechanism (see the Linkselect Example.)
The coolest new feature is probably the "placeholder" support, which allows you to specify an <option /> element in your <select /> box to use as a label/placeholder. The "placeholder" <option /> tag uses the <option /> tag as the title of the dropdown menu that's always visible, but still selectable. Here's an example:
Here's a list of all the changes:
We recently upgraded our version of Subversion from a very old version of Subversion to v1.7.1. We really wanted the newer merging capabilities that arrived in Subversion 1.5 and figured it was worth the energy to upgrade Subversion to the latest version. Fortunately upgrading our Subversion repositories went very smoothly. I even decided to just do a full dump/load to make sure the repositories were fresh 1.7.x repositories. While this process took a little extra time, the upgrade itself went very smoothly.
However, where things really fell apart for us was with our Trac/SVN integration. The problem is we were still running Python 2.4, which include old SVN bindings, so any attempt to do anything with our SVN ended up with an error that looked like:
TracError: Couldn't open Subversion repository c:/path/to/repository: SubversionException: ("Expected FS format '2'; found format '4'", 160043)
In order to get the SVN commit hooks working with Trac, I was going to need SVN bindings that worked with SVN v1.7.1, but also were compiled for my version of Python. While one might think this wouldn't be difficult, I couldn't find any SVN bindings for Python 2.4. This left my options at either trying to compile my own versions or upgrade Python. Since I don't have easy access to tools for compiling my own version of the Windows binaries, I thought the best option was just to upgrade Python—especially since Trac is soon dropping support for Python 2.4.
The problem is there's no easy way to just migrate a Trac install to a new version of Python, because you're going to need to recompile all your Python *.egg files for the version of Python you're using. After spending way too much time getting all this working, I thought it was wise that I compile a list of all the steps you may need to take in order to get Trac migrated to a new version of Python.
Here is the general install instructions. I don't break this down as a true step-by-step instructions, because so much varies based on your environment. However I do break down all the major steps you'll need to take and try to point you to step-by-step instructions for each bullet when possible.
If all goes well, your environment should now be running under your new Python installation.
This process ended up costing me way more time than expected, so hopefully this guide will prevent you from struggling the way I did.
There was some disturbing news yesterday—and I'm not talking about the death of Steve Jobs. The "Olson" time zone database was taken offline. While the immediate impact may not be felt, this is a very important open project and shutting it down is potentially going to cause a lot of problems.
For those that don't know, the time zone database has been maintained by a group of volunteers over the years and hosted at National Institutes for Health and contains historical, present day and known future information on day light savings changes around the world. This database is used by a huge of array of platforms to keep accurate time—Java, Unix, *nix, smart phones, etc. If you have an app that can tell you the current time in another location, there's a good bet it's based on this time zone database (either directly or via the underlying language's platform.)
Here are some good articles with more insight:
As many have already commented on, I'm not sure how this law suit can hold up since historical information can not be copyrighted. However, the law suit will have an impact—especially for applications in use by locations where the day light savings is in frequent flux.
One of the features introduced in Microsoft SQL 2005 that I think really goes largely unused in the "OUTPUT" clause. It certainly was a feature that went unnoticed by me for a long time and even once I became aware of the feature, didn't really put it to much use. However, lately I've been refactored a ton of old SQL into objects and with this refactoring I've been making high use of the OUTPUT clause in order to help create audit trails. It's been a great way to know which rows were affected in your CRUD operations.
There's really a ton of useful things you can do with the OUTPUT clause, but one thing it allows you to do is to migrate data from one table to another in a single atomic operation.
Let's look at the syntax:
-- the table to move data from delete dbo.SourceTable -- get the data removed from the "source" table output deleted.column1, deleted.column2, deleted.column3 -- insert the deleted row into the "destination" table into dbo.DestinationTable -- your where clause for the "delete" operation where Column1 > 2000 and Column2 = 1234
Here's a fully working example that you can run in SSMS:
-- declare temp tables declare @original table (id int identity(1,1), name varchar(20), company varchar(20), dob datetime) declare @new table (id int, name varchar(20), company varchar(20), dob datetime) -- insert some fake data into our "original" table insert into @original (name, company, dob) values ('Bill Gates', 'Microsoft', '1955-10-28') insert into @original (name, company, dob) values ('Paul Allen', 'Microsoft', '1953-01-21') insert into @original (name, company, dob) values ('Steve Jobs', 'Apple', '1955-02-24') insert into @original (name, company, dob) values ('Steve Wozniak', 'Apple', '1950-08-11') -- show the results select 'original' as tableName, * from @original select 'new' as tableName, * from @new /* here is the core SQL used to do the move */ delete @original -- get the data removed from the @original table output deleted.id, deleted.name, deleted.company, deleted.dob -- insert the deleted row into the @new table into @new -- your where clause for the "delete" operation where company = 'Microsoft' -- show the new results select 'original' as tableName, * from @original select 'new' as tableName, * from @new
If you run this example in SSMS, you'll see the two "Microsoft" records move from the @original table into the @new table.
NOTE:The @original and @new tables are simple table variables (which are like temp tables.)
There really is a ton of useful things you can do with the OUTPUT clause, so I highly recommend playing around with the OUTPUT clause if you're using SQL Server 2005 or later!
This morning I was working on some code where I wanted to capture an error in side a cftry/cfcatch block and rethrow the message, but I wanted to modify the cfcatch.message key to include more detail without losing the stack trace. I could have just used the <cfthrow /> tag and used the type, message and detail attributes but this would have caused me to lose the stack trace—which I needed.
Idealistically, I could have just modified the "message" key in the cfcatch variable, but the problem is the ColdFusion cfcatch variable is not really a struct—it looks like one—but it's actually an Java exception. Because it's not really a struct, it's not possible to just edit key values—making the cfcatch variable essentially read-only.
This got me looking into a method were I could rethrow the original stack trace, but customize the "message" key. After a few minutes playing around the java.lang.Exception object, I came up with the following:
<cffunction name="rethrowMessage" access="public" returntype="void" output="false" hint="Rethrow a CFCATCH error, but allows customizing the message key"> <cfargument name="cfcatch" type="any" required="true" /> <cfargument name="message" type="string" required="false" /> <cfset var exception = "" /> <cfif not structKeyExists(arguments, "message")> <cfset arguments.message = arguments.cfcatch.message /> </cfif> <cfset exception = createObject("java", "java.lang.Exception").init(arguments.message) /> <cfset exception.initCause(arguments.cfcatch.getCause()) /> <cfset exception.setStackTrace(arguments.cfcatch.getStackTrace()) /> <cfthrow object="#exception#" /> </cffunction>
Using this UDF, I can now do something like:
<cfscript> // connect and authenticate try { store.connect(variables.instance.server, variables.instance.username, variables.instance.password); } catch(Any e) { // throw original message, but append the username to the message rethrowMessage(cfcatch=e, message=e.Message & " [#variables.instance.username#]"); } </cfscript>
This allows me to throw the original Java error that occurs when connecting to a JavaMail Store occurs, but modify the message to include the mailbox I'm trying to connect to which is helpful in debugging the root cause.