While working on a project, a SOAP request kept failing. The page wouldn’t load, and I was getting the following lines in the logs:

J2CA0206W: A connection error occurred. To help determine the problem, enable the Diagnose Connection Usage option on the Connection Factory or Data Source. This is the multithreaded access detection option. Alternatively check that the Database or MessageProvider is available.

J2CA0056I: The Connection Manager received a fatal connection error from the Resource Adapter for resource eis/JCAHTTP-WS. The exception is: java.io.IOException: javax.xml.soap.SOAPException: org.xml.sax.SAXParseException: White space is required between “SYSTEM” and the system identifier. Message being parsed:

Trace Strings

To help troubleshoot, I enabled logging.

*=info:
com.ibm.ws.webservices.*=all:
com.ibm.websphere.commerce.WC_MESSAGING=all:
com.ibm.websphere.commerce.adapters.jcahttp=all

That didn’t really help. However, the White space is required between “SYSTEM” and the system identifier message usually means HTML was returned. This is a web service over HTTP, so that is very likely.

Tcpmon – Tcp/Ip Monitoring Tool

To prove that was the case, I used tcpmon to see exactly what was happening. Tcpmon is a tcp/ip monitor that works by listening on a certain port. In takes a target host and a target port, which requests will be sent to. Unlike network analyzer, such as Wireshark, tcpmon doesn’t analyze all traffic.

Overview

You must specifically set up the SOAP configuration to point to localhost with the port specified in tcpmon. Once the requests are going to it, it will monitor the request it received, and then forward that request to the target host and port. Once it gets the response, it will forward that back to WebSphere Commerce. Essentially, tcpmon is just a proxy that is setting in between WCS and the web service you are calling, even if that web service is on localhost already.

Running Tcpmon

First thing you need to do is start it up. Tcpmon is a part of WebSphere Application Server, and not WebSphere Commerce. You will need the app server root directory, which will have a runtimes directory inside.

Start a command prompt and cd to C:\IBM\WebSphere\AppServer\runtimes, or where ever your app server root\runtimes directory is located.

For WAS 8.0, run:

java -cp com.ibm.ws.webservices.thinclient_8.0.0.jar com.ibm.ws.webservices.engine.utils.tcpmon

For WAS 8.5, run:

java -cp com.ibm.ws.webservices.thinclient_8.5.0.jar com.ibm.ws.webservices.engine.utils.tcpmon

The easiest way to tell is just look at the version number in the filename for the om.ibm.ws.webservices.thinclient jar file.

Configuring Tcpmon

Configuration is pretty straightforward. Enter in a listening port. This is what will bind to localhost, so it must be a port that is currently not in use. Pick something like 9098. Target Hostname is where the request should go to along with the target port. For example, using the WCS order services at http://localhost/webapp/wcs/services/OrderServices, you would use a target hostname of localhost and a target port of 80. That will forward all localhost:9088 requests to localhost:80.

If your web service was http://WhereTheWebServiceIs.com:5000/something/somethingElse/Service, enter target hostname of WhereTheWebServiceIs.com and target port 5000.

tcpmonitor setup

After adding the new listener, a tab will open waiting for requests and responses. Tcpmon is all set up.

tcpmonitor running

Configuring WCS to Use Tcpmon

Log into your admin console (https://localhost:8002/webapp/wcs/admin/servlet/ToolsLogon?XMLFile=adminconsole.AdminConsoleLogon) and go to Configuration, Message Types. Select your message type to change the parameters. On the first screen, just click next. On the next screen, change the URL.

tcpmonitor change url to monitor

With localhost:9098 going to WhereTheWebServiceIs.com:5000, the new URL would be:
http://localhost:9098/something/somethingElse/Service

You change the host to be localhost and the port to be the listening port, but keep the rest of the path the same.

Alternatively, you can select your message type from the msgtypes table, use the msgtype_id and store_id to select the profile_id out of the profiles table, and then use the profile_id and interspecattname=’URL’ from the iseditatt table to get the URL to update directly without having to go throw the WCS admin console.

Conclusion

All that’s left is to run the web service. You should be able to see the request and response to find out exactly what is failing, and in my case, I was getting an HTML error page.