ColdFusion Muse

Accessing Both 64bit and 32bit Assemblies

Many readers will doubtless recall the war waged by the Muse against .NET on 64bit ColdFusion 8. If not, you can read all about it in this series of posts on Muse Vs. .NET Integration. It was clear from the outset that using 64bit CF against a 32bit assembly was not working for us. Naturally we went down the path of recompiling everything into 64bit and we had multiple obstacles to overcome. But the fact that we could not communicate with 32bit assemblies always puzzled me. The communication (like most things on a web server) happens through a socket to a listener provided by the integration service (just like Verity and Sequelink). I could not reasonably explain to my own satisfaction why it should be that a 32 bit assembly was inaccessible. After all, our tests using the assembly directly worked fine. I assumed in a vague sort of way that differences in how variables were stored and passed back and forth must be to blame.

A few weeks ago I got a tip from the always insightful Rick Root on CF-Talk - who figured this out with the help of the folks at Just CF (SupportObjective). His problem was different than mine. He had a mixed environment with both 32bit assemblies and 64bit assemblies. In his experimentation he discovered something that solves both our problems. When you call and assembly (any assembly) using .NET integration ColdFusion creates some jar files under the hood. You will find them in the /cfclasses/dotnetproxy folder. Here's a sample folder where the server is using 2 .NET assemblies:



Of course, one of the Jar files that ColdFusion creates is the actual assembly interface which "mirrors" the methods and properties of the .NET interface. It's the one with the cryptic name that looks like "-23480983_3023903.jar". The other file however is special. It's the one that is always named dotNetCoreProxy.jar. It is compiled only once (unless you delete it) on the first time you instantiate a .NET assembly. It provides (presumably) the interface to the proxy listener.

The Fix

Now here's the kicker. If the first assembly you call is a 32bit assembly - in other words, if you call the 32bit framework first - then this little jar file is compiled to access the 32 bit framework and cannot access the 64bit framework. In fact, there's some good evidence that it can't reliably access 32bit DLLs either (it seems error prone). However, if you access a 64bit assembly first then the jar file is compiled in such a way as to be able to access both the 64bit and 32bit frameworks.

Conclusion

To avoid having to run this gauntlet I would suggest accessing a .NET Assembly on the 64 bit framework first and backing up the subsequent dotNetCoreProxy.jar file to avoid future confusion. I'm sure you can find a nice "Hello World" assembly to compile to 64bit. If you have legacy .NET integration code and you are moving from 32bit to 64bit then it will likely not work out of the box until you have done this (or it may work once or twice and then give you inscrutable errors). You will need to get the correct dotNetCoreProxy.jar file compiled (the 64bit version) before you can access your 32 bit assembly dlls successfully and reliably. The good news is that you don't necessarily need to recompile all your assemblies to use the 64bit CLR - although there may be a performance or compatibility reason to do so.

Related Blog Entries

Comments
JC's Gravatar Hey Mark - any chance you could send me a working 64 bit dotNetCoreProxy.jar file? I can't get one to generate, I just keep getting "Error while generating the proxy jar for .NET core jar" in the dotnet.log, and the CF page itself just throws an error comprised of whatever value I placed in the Class attribute.
# Posted By JC | 11/15/12 6:27 PM
JC's Gravatar alternately if you know any working 64 bit SFTP (ftp over SSH) com objects... I can't for the life of me get CFFTP to work (it will work once and then refuse to close the connection or open any new ones or allow you to reuse the open one... so everything else just hangs until the server is restarted) and I'm trying to use WinSCP, but the CTO says he doesn't want us using the command line version with cfexecute, he wants a com object or .net assembly... and we're running in a 64 bit environment... and it's only so far as I can see available in 32 bit. *sigh*
# Posted By JC | 11/15/12 6:30 PM
Nick's Gravatar I'm also having trouble finding a 64 bit DLL and I only have V.S. express.. Could you also send me a copy or perhaps post a dotNetCoreProxy.jar file for download?
# Posted By Nick | 2/7/13 3:56 PM
Richard Davies's Gravatar These instructions, from http://forums.adobe.com/thread/1022767 fixed this problem for me:

I have figuered this out, wierd fix, but basically you need to try and instantiaite a .net compoment, you get the above error, then you turn off the .net and main cf service go to the ../WEB-INF/cfclasses/dotNetProxy subdirectoty and delete all but the file dotNetCoreProxy.js ...restart .net and main cf services, rerun your script and viola works like a champ. Here's a "simple script" to use:


<cfset x = GetDotNetVersion()>

<cfoutput>#x#</cfoutput>

<cffunction name="GetDotNetVersion" returntype="string">

<cfset var seClass="">

<cfobject type=".NET" name="seClass" class="System.Environment">

<cfreturn seClass.Get_Version().ToString()>

</cffunction
# Posted By Richard Davies | 1/7/14 2:18 PM



Blog provided and hosted by CF Webtools. Blog Sofware by Ray Camden.