Monitoring SOAP messages with TCPMon and a JAX-WS client

When you create a JAX-WS client for a Web Service, you may encounter troubles to monitor the SOAP messages that transit between the client and the service.
Indeed, this is how JAX-WS proceeds:

  • The client knows the URL of the WSDL (in the class which is annotated with @WebServiceClient).
  • So, first, the client retrieves the WSDL document and finds the service’s end-point in it.
  • The service is directly invoked.

In terms of exchanges, it means:

  1. Client to WSDL URL: a HTTP GET is sent and the WSDL content is returned
  2. Client to the service URL: a HTTP POST is sent, containing the SOAP message, and the SOAP response is returned.

There are two ways of placing TCPMon between the client and the Web service.
Each approach leads to a different result.

If you only update the port of the WSDL URL that is described in the client, then you will only see the HTTP GET request.
This is the one that returns the WSDL content from the URL. But you will not see the SOAP messages with this approach.

The solution to watch them, is to use a modified WSDL.
And this WSDL must force the client to go through TCPMon.

  • Save the WSDL file in another location.
  • In this second WSDL, update the port in the service’s end-point to use the TCPmon one.
  • Update the port in the WSDL URL, that is described in the client.

Then, all the requests (GET and SOAP messages) will go though TCPMon.

MTOM is not working

I know. This is an enticing title.
It’s just that I spent about 3 hours this afternoon to succeed in invoking a service with a Java client that had MTOM enabled.

It was not the first time that I did that. But this afternoon, I could not make it work. No way.
I knew my service was working because I had no trouble with SoapUI. But I also wanted to test with a Java client.
Generally, I like to test both kinds of service invocation (XML request directly or business objects).

Anyway…
I had generated a client with Apache CXF. The client had no dependency to CXF, it was a pure JAX-WS client.
I updated the binding to enable MTOM. But it did not work. The message my service was receiving did not contain a XOP element.
Instead, there was what I think to be the file’s content in a base64 encoding.

Eventually, the solution rose from both an intuition and the abyss of the Internet.
My project’s build path was using a JRE 6. And the JAX-WS support of the JRE does not handle MTOM attachments. At least, for the sending.
Switching to a JDK 6 (1.6.0.18) solved the thing.

I would have appreciated an exception in the JRE implementation, saying “Not Implemented” when using setMtomEnabled( boolean ).
May this provocative title draw the attention of people that would have the same issue.

Merge / Compare dialogs and XML syntax highlighting

I have just implemented a refactoring feature for Petals projects (at least for those that aim at defining Petals services). The Eclipse refactoring framework is convenient and provides most of the required things. Besides, you can find interesting tutorials that will help you for an advanced usage.

After having implemented the basis of the feature, I then wanted to make it little more nicer. Indeed, the compare viewer was a simple text viewer, with no syntax highlighting. As most of the Petals files are XML files, having an enhanced viewer was rather important for the user experience.

Obviously, the first reflex in such a case, is to try to reuse an existing class or mechanism. For almost any language or editor within Eclipse, that would be quite simple. A source viewer configuration would solve it.

But not for XML. In fact, the Eclipse XML editor does not provide a real source viewer configuration. It was designed to only work with classes from the same project. So, either you create your own source viewer configuration, or you try to hack the custom viewer configuration of the Eclipse XML editor.

I chose the second option.
The first thing to do is to create an extension for org.eclipse.compare.contentMergeViewers

<extension
       point="org.eclipse.compare.contentMergeViewers">
    <viewer
           class="com.ebmwebsourcing.petals.common.internal.compare.XmlViewerCreator"
           extensions="xml, xsd, wsdl, bpel, composite"
           id="com.ebmwebsourcing.petals.common.xmlViewer">
     </viewer>
</extension>

As you an see, I registered it for several kind of XML files.
The class is a factory for the viewer that will be used in the compare dialog.
Its code is:

public class XmlViewerCreator implements IViewerCreator {

	public XmlViewerCreator() {
		// nothing
	}

	public Viewer createViewer( Composite parent, CompareConfiguration config ) {
		return new XmlViewer( parent, config );
	}
}

And here is the code of the XmlViewer.
The hack consists in intercepting the elements that do not work with the XML editor classes and create an adapted delegate to use instead. More exactly, the StructuredTextViewerConfigurations can only work with StructuredTextViewers and IStructuredDocuments.

@SuppressWarnings( "restriction" )
public class XmlViewer extends TextMergeViewer {

	public XmlViewer( Composite parent, CompareConfiguration configuration ) {
		super( parent, configuration );
	}

	@Override
	protected void configureTextViewer( TextViewer textViewer ) {

		if( textViewer instanceof StructuredTextViewer ) {
			((SourceViewer) textViewer).configure( new StructuredTextViewerConfigurationXML());
		}
	}

	@Override
	protected SourceViewer createSourceViewer( Composite parent, int textOrientation ) {

		int style = SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL;
		return new StructuredTextViewer( parent, null, null, false, style ) {
			@Override
			public void setDocument( IDocument document ) {

				if( document instanceof IStructuredDocument ) {
					super.setDocument( document );

				} else if( document != null ) {
					String contentTypeID = ContentTypeIdForXML.ContentTypeID_XML;
					IStructuredModel scratchModel = 
					    StructuredModelManager.getModelManager()
					    .createUnManagedStructuredModelFor( contentTypeID );

					IDocument newDocument = scratchModel.getStructuredDocument();
					String s = document.get();
					newDocument.set( s );
					super.setDocument( newDocument );

				} else {
					super.setDocument( null );
				}
			}
		};
	}
}

And… voilà!

The question dialog to ask if dirty editors should be saved

Asking to save the active editors in Eclipse

Hi,

After some very busy months, I am going to try to resume on my blogging activity. Here is a very small tip. It is not very difficult by itself, but it took me a little time to find it.

While starting a new wizard, I wanted to be sure that the open editors were saved. I supposed there was a common way to do this in Eclipse, rather than implementing it from zero. I eventually found it, but that was not so easy to find.

In fact, just use:

PlatformUI.getWorkbench().saveAllEditors( true );

It results in this usual question dialog in Eclipse:

The question dialog to ask if dirty editors should be saved