Archive for September, 2008

By default ColdFusion will use the computer name without the domain name appended when sending email. However, some mail servers require that senders use a Fully Qualified Domain Name (FQDN) in their EHLO. If that is the case, you may get errors in your mail.log that look something like this:

Sep 18 17:22:11 mail postfix/smtpd[55543]: NOQUEUE: reject: RCPT from
prlt004[145.94.255.255]: 504 5.5.2 mail3.prisma-it.com: Helo command
rejected: need fully-qualified hostname; from=<email-address>
to=<email-address> proto=ESMTP helo=mail3.prisma-it.com

A similar problem exists with Message-IDs and spam filters and Adobe has TechNote kb400753 ColdFusion MX: Configuring cfmail to use a Fully Qualified Domain Name which describes a solution to fix the Message-ID. Luckily a similar solution works for changing the FQDN used in the EHLO. Just add a mail.smtp.localhost to your jvm.config with the right FQDN as value, restart your ColdFusion instance and you can send email again. My jvm.config uses:

-Dmail.host=jochem.vandieten.net -Dmail.smtp.localhost=jochem.vandieten.net

So yesterday I wrote about installing 2 versions of LiveCycle ES, but with the limitation that you can’t run them simultaneously. I didn’t really intend to try to run them simultaneously because I thought it would be a lot of work, but it did feel unfinished and that kept nagging. So a little over an hour ago I decided to give it a shot anyway. Not the way you are supposed to do it, but using a brute force approach. The first step was using “netstat -ano” to register all the ports in use by the JBoss and MySQL processes. After filtering that produced the following list:

?View Code WINBATCH
Active Connections
 
  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:1098           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:1099           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:1100           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:1101           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:3306           0.0.0.0:0              LISTENING       2392
  TCP    0.0.0.0:3528           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:4444           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:4445           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:4446           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:4447           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:8083           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:8093           0.0.0.0:0              LISTENING       1032
  TCP    0.0.0.0:49152          0.0.0.0:0              LISTENING       1032
  UDP    0.0.0.0:1161           *:*                                    1032
  UDP    0.0.0.0:1162           *:*                                    1032
  UDP    192.168.0.121:1496     *:*                                    1032
  UDP    192.168.0.121:1498     *:*                                    1032
  UDP    192.168.0.121:1501     *:*                                    1032

The next step was a search of all the configuration files to find all occurences of these port numbers. All the configuration files means everything with the extensions .properties, .xml and .ini in all the subfolders of “c:\Adobe\LiveCycle8.3\jboss\” and “c:\Adobe\LiveCycle8.3\mysql\”. I did some fuzzy selection on which of these files were really relevant and changed the port numbers to a number exactly 1000 higher in the following files:

?View Code WINBATCH
C:\Adobe\LiveCycle8.2\jboss\server\all\conf\jacorb.properties
C:\Adobe\LiveCycle8.2\jboss\server\all\conf\jboss-minimal.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\conf\jboss-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\cluster-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\httpha-invoker.sar\META-INF\jboss-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\jboss-ws4ee.sar\META-INF\jboss-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\jbossweb-tomcat55.sar\server.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\jms\hajndi-jms-ds.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\juddi-service.sar\juddiws.war\WEB-INF\juddi.properties
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\snmp-adaptor.sar\META-INF\jboss-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy-hasingleton\jms\uil2-service.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\adobe-ds.xml
C:\Adobe\LiveCycle8.2\jboss\server\all\deploy\mysql-ds.xml
C:\Adobe\LiveCycle8.2\mysql\my.ini

This appears to work (for some value of work). Anytime now I will get an alarm because the system overheated and imploded (it has only 2 GB of RAM), but the server started, the server.log is clean and I am logged on to both the LiveCycle 8 Admin on port 8080 and the LiveCycle 8.2 Admin on port 9080.So as long as you’re willing to bypass all the rules on how it should be done and just go for the brute force approach it appears to be pretty easy to run 2 versions of LiveCycle ES simultaneously.

Sometimes I need multiple versions of LiveCycle ES for JBoss installed, for instance a version 8.2 for delivering a training and a version 8.0 for a consultancy project. That is not easily supported out of the box. The official installation instructions for a customized install aren’t really difficult, but at over 200 pages the combined installation manuals are a bit tedious. So what we really want is to use the turnkey installation, but the standard turnkey installer will detect an installation is already present and will only allow to update and not to install alongside. Luckily that is pretty easy to circumvent if you know a little bit about the default installation paths on Windows. So here is how you do it.

  1. Do a completely standard TurnKey install of LiveCycle ES 8.0.
  2. Change the LiveCycle 8 services (JBoss and MySQL) not to start automatically.
  3. Backup the registry keys “HKLM\SYSTEM\CurrentControlSet\Services\JBoss for Adobe LiveCycle ES v8″ and “HKLM\SYSTEM\CurrentControlSet\Services\MySQL for Adobe LiveCycle ES v8″ and then delete them.
  4. Search the registry for “Adobe LiveCycle ES” and when you find a key under “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\” back it up and delete it.
  5. Move your C:\Adobe\LiveCycle8\ folder elsewhere.
  6. Restart.
  7. Do a completely standard TurnKey installation of LiveCycle ES 8.2.
  8. Change the LiveCycle 8 services (JBoss and MySQL) not to start automatically.
  9. Restore your C:\Adobe\LiveCycle8\ folder.
  10. Restore the “HKLM\SYSTEM\CurrentControlSet\Services\JBoss for Adobe LiveCycle ES v8″ and “HKLM\SYSTEM\CurrentControlSet\Services\MySQL for Adobe LiveCycle ES v8″ registry keys.

You can now start whichever version of LiveCycle you want from the services control panel. You can not run them at the same time due to port conflicts in both MySQL and JBoss, but fixing that is quite a bit more work. And I’m pretty sure this breaks the uninstall too.

One my coworkers had and issue where she couldn’t run cfreport from her site. The error from the site was rather unhelpfull:

ROOT CAUSE:
java.lang.NoClassDefFoundError: Could not initialize class coldfusion.runtime.report.Report
	at coldfusion.tagext.lang.ReportTag.doEndTag(ReportTag.java:581)
	at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2662)
	at cfprintLabels2ecfm1064228503.runPage(D:\sites\********\www\common\widgets\printLabels.cfm:49)

Initially Google only came with one hit when searching for this, and it didn’t provide any solution. Since it was a simple report to generate Avery labels in pdf I recommeded a workaround: use a pdf form template and fill out the addresses  through cfpdfform. But today when I saw a WEB-INF/cfusion/tmpCache/CFFileServlet/_cf_report/ folder on my development system I suddenly realized the problem might be caused by a sandbox issue.  The site is on a shared server and sandboxes default to the site folder and all subfolders, but nothing outside that. And as it turns out ColdFusion tries to do something with WEB-INF/cfusion/tmpCache/CFFileServlet/_cf_report/ so the sandbox will need access to that folder for cfreport to work. Once we allowed access to the Sandbox to this folder, cfreport started working again.

In case you are interested, the script to add a directory to all sandboxes is here:

<!--- For Sandbox stuff use the platform specific directory delimiter --->
<cfset cftempdir = server.ColdFusion.rootDir & "\tmpCache\-" />
<cfset adminPassword = "" />
 
<cfset administrator = CreateObject('component', 'cfide.adminapi.administrator')>
<cfset security = CreateObject('component', 'cfide.adminapi.security') />
 
<!--- Login --->
<cfif NOT administrator.login(adminPassword)>
	<cfthrow message="Login failed" detail="Unable to login to the CF adminAPI.">
</cfif>
 
<!--- Collect the defined sandboxes--->
<cfset sandBoxes = security.getSecuritySandboxes() />
<cfloop collection="#sandBoxes#" item="box">
 
	<!--- Test if it is a user-sanbox and not a system-sandbox and add the tmpCache folder --->
	<cfif Left(box, 12) IS "z:\websites\">
		<cfset security.setSecuredFolder(
				directory=box
				, folder=cftempdir
				) />
	</cfif>
 
</cfloop>

Other tags that won’t work in a sandbox

This issue appears to be new in CF 8 because aparently it had worked before in a similar sandbox on CF 7. Several more tags have problems if you typically limit sandbox access to the folder the code is in and to subfolders. My current list is

tag folder
cfdocument font directory (c:\windows\fonts\)
cffile upload J2EE server temp dir (c:\JRUN4\servers\cfusion\SERVER-INF\temp\cfusion.war-tmp\)
cfreport WEB-INF/cfusion/tmpCache/CFFileServlet/_cf_report/
cfimage WEB-INF/cfusion/tmpCache/CFFileServlet/_cf_image/

So who has discovered any other tags that need access to special directories to work properly?

Over the past months we have nearly completed a consolidation from two datacenter locations to one datacenter location. We had moved our dedicated servers to one location a while ago and two weeks ago we finally moved the last shared hosting to new hardware. And part of that last batch was our own stuff: experiments, mockups, test-sites etc. And while I was cleaning up on one of the old servers I noticed something peculiar about the webserver configuration for one of the sites. Because I would have sworn that site ran CF 7, but the IIS configuration looked like this:

IIS configuration screenshot

If you look carefully you see that the .dbm extension is actually mapped to CF 5 and the .cfm, .cfml etc. extensions are mapped to CF MX. And if you look really carefully you will notice that the wildcard filter is mapped to wsconfig instance 2. And instance 2 had the port number in jrun.ini changed causing it to connect to CF 7 even though the connector was located in the CF MX installation directory. And since the wildcard filter runs first the site did run under CF 7.

If you use a server like this one where we hosted internal stuff and didn’t have strict change control for a long time I think it is pretty much inevitable that you end up with this sort of configuration quirks. (But that still doesn’t make it right.) But this sort of thing I have noticed before even on serious production servers from third parties (although usually with only 2 versions of CF instead of 3). And this sort of thing is why I always prefer to do upgrades through a full uninstall of the old version and then a fresh installation of the new version. It just helps keeping things clean and it really isn’t that much work. Nowadays I pretty much always work with CF multiserver and then it is just a matter of generating a new EAR file from the CF installer and deleting the old EAR file, but even when I am working with the single server edition it is just a matter of scripting the install through the silent installer and the admin API.

In the ColdFusion Administrator you can configure the logging behaviour to some extend. Where the ColdFusion logfiles are written, whether to log all email messages, long running pages etc. But you can not change the columns or masks for date formatting there, which is unfortunate because the native date mask for the logging is rather ambiguous. On my Dutch locale server the date “04/07/08″ should mean July 4th, but the log entry was written April 7th.

Fortunately, though not exposed in the ColdFusion Administrator, we can change the columns and patterns of the logfile directly in neo-logging.xml. By default, it defines the following pattern for the logging:

<var name="pattern">
    <string>"%p","%t",%d{"MM/dd/yy","HH:mm:ss"},%a,"%m%x"%n</string>
</var>

If we change the date mask in this pattern to something unambiguous, like the format defined in ISO 8601, we can now process our logfiles using tools written for our own locale:

<var name="pattern">
    <string>"%p","%t",%d{"yyyy-MM-dd","HH:mm:ss"},%a,"%m%x"%n</string>
</var>

Obviously you can change even more in the logging if you want, but if you start swapping / removing columns you may discover that the Logfile Reader that is part of the Adobe Extensions for Eclipse won’t work anymore. And like any change to a configuration file, make sure you have a backup before you start and make sure you restart the server once you have made the changes to detect any errors immediately instead of when the server won’t start at 3 AM.

Those who deploy ColdFusion on top of JRun may have noticed that the date mask in the JRun logfiles is even worse. Luckily here too we can configure the mask in a configuration file, jrun.xml:

<attribute name="format">{date yyyy-MM-dd HH:mm:ss} {log.message}{log.exception}</attribute>

The same warnings apply as with the ColdFusion log files.

Today Google released a first Beta of Google Chrome, a new web browser.  Just installing it already showed how Google Chrome is different from other browsers. Since I am always logged on on my laptop as a normal user I right-clicked the installer and choose the “Run as” option and installed it under the Administrator accout. The result was surprising: it didn’t work. No error messages during installation, but I couldn’t get any website to open. After some searching I figured out that Google Chrome installed itself in “%USERPROFILE%\Local Settings\Google\” so you have to install it as the user that is going to use it. So after installing it as myself I could see pages and the fun starts.

One of the touted differences between Chrome and current browsers is that Chrome runs each tab in a separate process and processes are independent and one process will not affect another, even when it crashes. (Reputably the current IE 8 beta has the same feature, but I haven’t tried that yet.) So when you look in the Windows Task Manager you see separate processes for all tabs. With Chrome’s own Task Manager you can see a little bit deeper since you can see which process is which tab, but the real good stuff is in the “Stats for Nerds” which shows detailed information. I have included screenshots of all three below here.

Windows Task Manager view Google Chrome Task Manager Stats for Nerds

The most remarkable thing other then that is how unremarkable Chrome is. It is very unobtrusive with very little chrome and lots of room for content, it feels extremely responsive and it just works. It didn’t ask if I wanted to install the Flash Player, it just worked. I don’t even know if it is embedded or if Chrome borrows the Firefox plugin or something. But since it runs in its own process the memory consumption becomes visible. So I guess pretty soon people will start to look a whole lot closer at the memory consumption of Flex applications.

All in all the first impression is very good. After the installation hurdle it just works and I really like the security / process / memory model (it feels like Unix and specifically like the model of PostgreSQL). And I mean really like it. Now I know I am a bit peculiar in my security habbits / preferences (how many others will have run into the installation issues I did?), but I really take such issues into consideration when I choose tools. And so far Google Chrome is scoring big points.