Enterprise Software

Avoid CFMX/BEA WebLogic pitfalls in your Web service

Any Web service implementation is going to see its share of gotchas, and Web services developed with ColdFusion MX and BEA WebLogic are not immune. Minimize your efforts by learning from the problems one developer encountered in his implementation.

Web services are supposed to make our lives easier. With a simple click of a button, data is supposed to leave one system and magically appear on another in a format the receiver understands. The focus here will be interacting with Web services running on BEA WebLogic 7.1 via the <CFINVOKE> tags in CFMX 6.0 (Updater 3 installed). More specifically, I'll be talking about certain pitfalls and setbacks my team encountered during a recent Web service implementation. Some of the hurdles we had to overcome were user-created, while others were system-created.

I encountered three types of pitfalls:
  • User errors
  • System errors
  • Logic errors

User errors were those that we, the programmers, caused by coding incorrectly. System errors were those that didn't work in the CF Application Server inner workings. Logic errors were those that weren't errors on the surface but which, upon closer inspection, were proven to be errors of logic.

User error: Date format
The first area where we ran into serious problems was when we had to pass a date to the Web service. The Web service we called was expecting the date in the W3C XML schema definition of dateTime. Suffice it to say, the W3C is a bit pickier about its date formats than ColdFusion, which accepts many formats.

The schema definition can be found on the W3C site at for those interested in reading up on it. I was more interested in getting the Web service working ASAP; therefore, like a typical programmer, I skimmed over the explanation and starting trying all these formats. Eventually, I came to the realization that the only acceptable format was the format outputted by the createodbcdatetime() function:
{ts '2003-08-01 00:00:00'}

A little something to think about regarding the DateTime definition: When you program a Web service on a BEA WebLogic server, it automatically creates a simple HTML form to run the service. (See Figure A.) We had trouble getting results back in our ColdFusion MX (CFMX) code, so we tried using the WebLogic form. It too returned no results. When we pointed out to the WebLogic programmer that the form returned no results, he said that the WebLogic form wasn't capable of sending the date in the proper W3 dateTime format. You should keep that in mind if you use that form to test WebLogic services against your CFMX results.

Figure A
W3 DateTime definition example

System error: Can't mix and match WSDL servers
The second thing we encountered was a system quirk. When developing in an enterprise, there are at least three environments for applications: development (dev), staging, and production. We started off using dev environments for both the CFMX and WebLogic systems. The WebLogic Web services went into the production environment, and we needed to test them from the CFMX dev environment. This is when our Web service calls started to throw errors.

At first, we thought it was our code, considering that it was a dev environment. After days of testing and experimenting, we found out the culprit. It was the URL of the WSDL files in our code. When you run a Web service for the first time, it's a bit slow because CFMX creates and compiles Java code in the stubs directory of your CFMX installation. (CFMX's underlying Java engine uses these stubs to actually make the Web service call.) We began getting errors saying that the Java engine couldn't compile the stubs correctly and thus couldn't run the Web service. This made no sense, since it would run the first time after a reboot and then every call afterward would generate the error message.

Our code was calling various methods from the same WSDL code; however, we were calling the WSDL from both the WebLogic dev and production environments. Every time we switched servers in our <CFINVOKE> tags, CFMX would try to regenerate the stub because it assumed we were calling a new service. The switching back and forth between the two WebLogic environments within our code was causing the CFMX server to corrupt our stubs, leading to all manner of mayhem.

The solution was to stick to calling the WSDL from either the WebLogic dev or production environment. If we had to call the other WebLogic environment, we had to delete the compiled code in the cfmx\stubs directory. (See Figure B.)

Figure B
Delete the compiled code.

Delete the reference to the service in the CF Administrator (Figure C) and bounce the CFMX service to fully clear the references to the old Web service (Figure D).

Figure C
Delete the entry in CF Admin.

Figure D
Bounce the CFMX.

Logic error: Assuming that an object will provide null value placeholders when values are not found
We had the date issue figured out and weren't getting compilation errors when we hit our third type of bump. This time there was no error per se. The code behaved exactly as it should and the results were being returned from the Web service exactly as they should have been. The problem arose from an assumption that the Web service would return null placeholders for methods that did not possess data in the resultset.

When coding output for a recordset, we know that CFMX will provide a null value for columns that do not have any data. In addition, when we <CFPARAM> our variables, we usually give them a blank value as a default. This is not the case for Web services—which makes sense because the Web service assumes that its results will be transferred across a network. If that's the case, why waste the CPU cycles and the bandwidth to transport an object that contains no data? However, trying to output an undefined method throws a pretty ugly error. Therefore, we had to trap for this possibility, which required a major rewrite of our code. That is definitely something to keep in mind.

Three lessons
Although utilizing Web services to connect disparate systems may be the wave of the future, it's not quite as simple as it sounds in the marketing messages. Don't get me wrong—the services do help. If not for the Web service discussed above, we would have had to figure out how to get our Web servers on the outside network to talk to our Oracle databases on the other side of the firewall on our internal network and find a way to keep our code on the Web servers up to date on any and all schema changes taking place in those databases.

Using the <CFINVOKE> tag within a few CFCs makes this job a lot easier. The thing to remember is that even though you are accessing the results within your CFMX Web application, it doesn't mean that the function and the results behave exactly like CFMX code. Instead, you have to keep the following three things in mind:
  • Make sure to properly research the type of Web service you are planning to consume. That way, you will know exactly what sort of syntax and formatting will be needed to properly pass variables to the Web service call.
  • Remember that by using the <CFINVOKE> tag to consume Web services within the ColdFusion Application Framework, you're working with a relatively new technology. Yes, CFMX was completely rewritten to take advantage of Web services, but there are still some kinks to work out.
  • Make sure that your logic is complete. Take the time to view and understand what the Web service is returning to you before you code for the results. If you don't, you could be caught off guard by the results acting differently than you expected, and you'll find yourself doing twice as much work as you'd like to.

Picking up the pace
After all our efforts, we still had more work to do. For one thing, our Web service was complete and working as requested in the project spec, but it was way too slow in production. The CF developers and WebLogic developers had to get together and work out ways to make our various bits of code more efficient. This is a topic I will cover in the next article.

Editor's Picks