Tuesday, August 16, 2005

More CFHTTP weirdness

Here's a question for you -

Why would a previously solid, stable, Win2K3 box running CFMX6.1 standard suddenly start throwing a java.lang.NoSuchMethodError on any CFHTTP calls?

(note: this is NOT the box which falls over in the middle of the night with a JRun Guard Page Exception, this is another one!)

This line of code:

<cfhttp method="get" url="http://www.google.com" >
</cfhttp>

...in fact ANY cfhttp call, to any url, with any combination of parameters...

has just started throwing this error:

HTTPClient.HTTPResponse.getHeaderAsObject(Ljava/lang/String;)Ljava/lang/Object;

here's the stack trace:


java.lang.NoSuchMethodError: HTTPClient.HTTPResponse.getHeaderAsObject(Ljava/lang/String;)Ljava/lang/Object;
at coldfusion.tagext.net.HttpTag.createResponse(HttpTag.java:1673)
at coldfusion.tagext.net.HttpTag.connHelper(HttpTag.java:856)
at coldfusion.tagext.net.HttpTag.doEndTag(HttpTag.java:990)
at cftest2ecfm1025982501.runPage(«path removed»\test.cfm:11)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:147)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:357)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:62)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:107)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:80)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:47)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:35)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:43)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.CfmServlet.service(CfmServlet.java:105)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:249)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:527)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:192)
at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:318)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:426)
at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:264)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)


The NoSuchMethodError javadoc says the following:

"Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed."


So this kind of implies that either:

- One or more of the CFMX jar files has changed
or
- The Java Runtime Environment has changed

yet a quick search shows that neither is the case.

java -version from the command prompty is showing 1.4.2_08-b03

The CF Administrator System Information page shows :

Java VM Version 1.4.2-b28

and this is what I get if I cd into the cfusionmx/runtime/jre/bin directory and run java -version from there.

The only files under CFusionMX that have changed since 1st August are log files, verity collections or in wwwroot/WEB-INF/cfclasses/


My first thought was "has someone been fiddling about with the JVM?" but it appears not. No new code has been released on this box in weeks, nothing has changed in the CF Administrator, and no-one has applied any updates to the box for weeks.... yet it's just started throwing this error on all CHTTP calls.

Maybe it's that marvellous Automatic Updates feature in W2K3?

Anyone else had this problem? Anyone JUST STARTED having this?
If so, maybe we can try to find common elements and track down the cause.

UPDATE 22/08/05

I think I've isolated the cause - we had a custom Java-based CFHTTP replacement on the same box which was built around the HTTPClient lib. In deploying this project, we added a HTTPClient.jar onto the classpath, and it looks like that was causing the issue - a conflict with the httpclient.jar (note case) in the CFusionMX/runtime/lib directory.

When I deleted that second HTTPClient.jar file and restarted the server, the CFHTTP calls started working again.

HOWEVER - the custom-made Java-based CFHTTP replacement calls don't work any more........... it's another one of those "works perfectly on dev, but won't work at all on live" issues that we all know and love so well.

6 comments:

Anonymous said...

that's not the default JRE shipping with cfmx6.1. There are issues with with 1.4.2_06 and greater with cfldap calls and IIRC from the CF lists cfhttp also. This may be the issue you are having. roll it back to 1.4.2_05 and try.

Douglas Knudsen

Alistair Davidson said...

Cheers Douglas

On further investigation, I should add the following:

The CF Administrator System Information page shows :

Java VM Version 1.4.2-b28

and this is what I get if I cd into the cfusionmx/runtime/jre/bin directory and run java -version from there.

The 1.4.2_08-b03 is what I get from a java -version on the command prompt from anywhere else.

Thinking about this, could it be a conflict between the two different versions on the same machine?

I always thought that the CF JVM existed in it's own little world, inviolate and insulated from the rest of the box, but that may not be the case...

Anonymous said...

Hello friends,

I think the problem here is that ColdFusion uses its own HTTPClient.jar for all of its "browser like" behavior. In other words, any time the server needs to act like a web browser (like when you use CFHTTP or when you use web services to convert a WSDL definition into a stub class using CFINVOKE or CFOBJECT). The version of HTTPClient.jar that CF uses is dated "0.3-3 06/05/2001 1996-2001 Ronald Tschalär" on my install (CFMX 6.0). By installing your own version and putting it in the class path, you're interfering with CF's own use of the HTTPClient code. I would suggest that you tell your developers who have decided to build their own HTTPClient code to try to stay within the bounds of whatever the default HTTPClient that was installed with CFMX. The base HTTPClient jar contains source code (it's GNU), and it's located in: C:\CFusionMX\lib\HTTPClient.jar
(at least for my install).

You're on the right track by removing the new one, but there's probably no reason your developers can't use the embedded one, as long as they don't do anything outside of what it provides.

--jr

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

We decided to create our own jar/classes to accomplish more than what was available in cfhttp. We created our own class/methods so that we can
1) require 128+ encryption on the receiving end or the files would not http post
2) allow multiple trys of our server posting data to secure servers outside our network
3) logging failed attempts to an xml file for batch processing.
4) ping servers to verify
5) this ties in to our custom methods which read/write/create excel files with data loads for older non xml apps.

Anonymous said...

Why don't you use one of many classloaders. Classloading is at the heart of every j2EE app anyway so load the jar that way