Foo Infusion

A periodic infusion of foo from the world of a junior developer

Saturday, October 17, 2009

dom4j

I started using a dom4j implementation of an interface provided by a client's framework libraries (ie something they built themselves).

Little did I know I would need the jaxen and saxpath jars as well. Hopefully this saves someone the time it spent me...

Thursday, April 30, 2009

SOAP 1.2 + MTOM + WSE3 + NetBeans WebServices

For a project I'm working on at work right now, I needed to get a web service client implemented using WSE3 and communicating with a web service returning SOAP 1.2 using MTOM.

I know that's a bit of a mouthfull. I'll try to expand those terms a bit.

SOAP 1.2 - just a new version of the SOAP standard. It seems most tools use SOAP 1.1 as the 'standard' version of the standard. The trick seems to be how to tell your tools/technology that you want to use the new SOAP 1.2 standard. I think in reality the syntax of a SOAP 1.1 vs SOAP 1.2 message are pretty similar upon first/shallow glance. While there are some big differences in the model, the REALLY big difference from an implementation point of view seems to be the namespace it uses.

WSE3 - Microsoft's Web Services Extensions, version 3. An updated (and very changed from v.2) version of Microsoft's framework for dealing with web services.

MTOM - Message Transmission Optimization Mechanism - A standard (newish) for transmitting binary data using web services. Using just plain-old web services is not really sufficient for tranmitting binary data because SOAP is an XML standard, and it's difficult to get binary data in XML properly, esp without specialized processing on either end. Essentially, MTOM transmits your SOAP message as a multipart MIME message, with a MIME part for your standard XML SOAP message response, and another separate MIME part for the binary part. The MTOM implementation can unwind that message however it pleases I guess, though it seems that the tools I'm working with seem to take the binary data and Base64 encode it and stick it back in the SOAP XML.

Although I was only implementing the client for my part of the project, I needed a web service that used SOAP 1.2 in order to test that my stuff worked correctly. And I discovered some interesting things while stringing it all together. There didn't seem to be much in the way of help on the interwebs about this, so I wanted to put it up here in case anyone else finds it helpful. (Though I think most people have moved on past WSE3 by now, and are using WCF - I cannot make that move yet, unfortunately).

The soap namespace in your WSDL does need to be changed in order to tell your clients what version of SOAP you want to use:

o SOAP 1.1 : xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
o SOAP 1.2 : xmlns:soap="
http://schemas.xmlsoap.org/wsdl/soap12/"


The correct binding annotation for the SOAP version you wish to use should also be present to tell the JAX-WS stuff how to work. The NetBeans/GlassFish stuff picks SOAP 1.1 by default.(Java 6 has constants for this in the javax.xml.ws.soap.SoapBinding interface - http://java.sun.com/javase/6/docs/api/javax/xml/ws/soap/SOAPBinding.html#SOAP11HTTP_BINDING)
o SOAP 1.1 : @BindingType(value=”http://schemas.xmlsoap.org/wsdl/soap/http”)
o SOAP 1.2 : @BindingType(value="http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
o SOAP 1.1 + MTOM : @BindingType(value=”http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true”)
o SOAP 1.2 + MTOM : @BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/?mtom=true")



MTOM can also be specified by using @MTOM(enabled = true) annotation, but the binding type annotation takes precedence, therefore, specifying the SOAP 1.2 binding type (no MTOM) will give you SOAP 1.2 but NO MTOM even if the @MTOM annotation says otherwise.

The use of MTOM must be specified in the client as well as the WS. If the SoapClient’s RequireMTOM property is set to true, it is expecting a response with a content type of “multipart/related” – if the content type of the response is not “multipart/related” the client will throw an exception while processing the response. If the WS is not using one of the MTOM binding types it will not use a content type of “multipart/related” for the response ( I think it will use “text/xml” instead). So these must match up – if you’re using MTOM (in the WS) you have to tell the client you’re using MTOM so it will expect the “multipart/related” content type in the response, and if you’re not using MTOM you have to tell the client that so it will expect the “text/xml” content type in the response.

Here’s a very basic sample of what the client needs to look like:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Web.Services3.Messaging;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Addressing;

namespace wse3_tester
{

class Program
{

public static String CONTENT_TYPE = "Content-Type";

private String url = "
http://localhost:8888/PDFWebService12/TEIGInquiryService";

private String soapAction = "GetPolicyInquiry";

private String message = @"http://www.teig.com/"">AUTOMyIDEN2003-08-08-03:00";

private bool useMTOM = true;

static void Main(string[] args)
{
Program
p = new Program();

p.test();

}

private void test()
{

SoapEnvelope requestEnv = new
SoapEnvelope(System.Web.Services.Protocols.SoapProtocolVersion.Soap12);

requestEnv.CreateBody();

requestEnv.Body.InnerXml = this.message;

EndpointReference endpoint = new EndpointReference(new Uri(this.url));

WSClient client = new WSClient(endpoint, this.soapAction);

client.RequireMtom = this.useMTOM;

SoapEnvelope responseEnv = client.Send(requestEnv);

}

public class WSClient : SoapClient
{

String methodName;

public WSClient(EndpointReference refr, String methodName) : base(refr)
{

this.methodName = methodName;

}


public SoapEnvelope Send(SoapEnvelope env)
{

return base.SendRequestResponse(this.methodName, env);

}

}

}


And here’s a sample of what the annotations required for the ws:

@BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/?mtom=true")
@WebService(serviceName = "TEIGInquiryService",
portName = "TEIGInquiryPort", endpointInterface =
"com.teig.TEIGInquiryPortType", targetNamespace = "
http://www.teig.com", wsdlLocation =
"WEB-INF/wsdl/TEIGInquiryService12/TEIGInquiry12Wrapper.wsdl")
public class
TEIGInquiryService12 {

Wednesday, February 18, 2009

Pausing in a Windows batch script

It seems like I've been creating a lot of batch scripts lately.

I recently wanted a script that would start a server process, wait for the server to finish starting, and then start a client process.

I used the START command to kick off the server and client processes, but then was unsure of how to proceed to accomplish a pause/sleep in the batch script while the server was starting. Searching the internet seemed to turn up less information than I wanted, and often the suggested solutions didn't work anyway.

I settled on using the CHOICE command which has the following help screen:

C:\Users\admin>choice /?

CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]

Description:
This tool allows users to select one item from a list of choices and returns the index of the selected choice.

Parameter List:
/C choices Specifies the list of choices to be created. Default list is "YN".

/N Hides the list of choices in the prompt. The message before the prompt is displayed and the choices are still enabled.

/CS Enables case-sensitive choices to be selected. By default, the utility is case-insensitive.

/T timeout The number of seconds to pause before a default choice is made. Acceptable values are from 0 to 9999. If 0 is specified, there will be no pause and the default choice is selected.

/D choice Specifies the default choice after nnnn seconds. Character must be in the set of choices specified by /C option and must also specify nnnn with /T.

/M text Specifies the message to be displayed before the prompt. If not specified, the utility displays only a prompt.

/? Displays this help message.

NOTE:
The ERRORLEVEL environment variable is set to the index of the key that was selected from the set of choices. The first choice listed returns a value of 1, the second a value of 2, and so on.
If the user presses a key that is not a valid choice, the tool sounds a warning beep. If tool detects an error condition, it returns an ERRORLEVEL value of 255. If the user presses CTRL+BREAK or CTRL+C, the tool returns an ERRORLEVEL value of 0. When you use ERRORLEVEL parameters in a batch program, list them in decreasing order.

Examples:
CHOICE /?
CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "Select a for option 1 and b for option 2."
CHOICE /C ab /N /M "Select a for option 1 and b for option 2."


So to accomplish a pause in the batch script execution, I used a line that looks like this:
CHOICE /N /D Y /T

No message is needed.
/N - don't bother printing the choices
/D Y - the default response to choose, should time run out (it will) is Y
/T - specifies the timeout (time to wait for a response before picking the default) 
 Not complicated, but it's something that seemed to be lacking from the knowledge of the internet.

Tuesday, August 14, 2007

Dofuscator, Reflection, .NET Properties, and Attributes....

Recently the team I work on encountered some buggy behaviour that only exhibited itself in the obfuscated build, leading us to believe the bugs were a result of the obfuscation.

It was discovered that Dotfuscator's 'Library Mode' setting was to blame for the bugs.

From Dotfuscator's user guide:

Library Mode By Assembly

This setting tells Dotfuscator that a particular input assembly constitutes a library. (For Dotfuscation purposes, a library is defined as an assembly that is going to be referenced from other components not specified as one of the inputs in this run) This has implications for renaming and pruning, regardless of any custom excludes you may have set.

Here are the rules when using the library option:

1. Names of public classes and nested public classes are not renamed.
Members (fields and methods) of these classes are also not renamed if they have public, family, or famorassem access.

2. In addition, no virtual methods are renamed, regardless of access specifier.
This allows clients of your library to override private virtual methods if need be (this is allowed behavior in the .NET architecture).

3. Any user-specified custom renaming exclusions are applied in addition to the exclusions implied by the above rules.

4. Property and Event metadata are always preserved.

5. Pruning Rules. Public classes are not removed, even if static analysis determines they are not required. Fields of these classes are not removed if they have public, family, or famorassem access. Methods of these classes are not removed if they have public, family, or famorassem access. In addition, such methods are treated as entry points, so their call trees are followed and all subsequently called methods are also protected from removal.



If you do not have the library option set for an assembly, then you are telling Dotfuscator that your input assembly is a standalone application, or that it will only be referenced by other input assemblies. In this case obfuscation is much more aggressive:

1. Everything is renamed except methods that override classes external to the application (i.e. classes in assemblies that are not included in the run.)

2. Property and Event metadata is removed, since this metadata is not required to run the application (it is meant for “consumers” of library code).

3. As usual, user specified custom renaming exclusions are also applied.

4. Pruning Rules Specifically included classes, methods, or fields are not pruned. All trigger methods and fields are not pruned.



All classes, members, and fields that are excluded from renaming also become excluded from pruning. All other classes, fields and methods that are unreachable from some included class, method, or field are pruned.



We have some stuff built to make serializing a class to XML easier and more automatic. It uses three VB.NET concepts to accomplish this : .NET Properties, property attributes, and Reflection.

The XML serializer inspects an object using reflection, asking for a list of all 'properties', and then cycles through the list looking for properties which have the special XML serialization attributes (these are called annotations in Java).

When Dotfuscator was using 'Library Mode' on the assembly, there were no problems, as the 'property metadata' was preserved.

When Dotfuscator was not using 'Library Mode' on the assembly, the obfuscated assembly no longer contained the 'property', but rather had the property split up into the corresponding 'get' and 'set' methods. In this case, the XML serializer's call to the object for a list of properties returned an empty list as they were no longer considered properties but methods. Thus, the XML serializer didn't work very well.

I think I've determined that in our case there aren't any real negative consequences to using 'library mode' other than the obvious (but likely, slight) reduction in actual obfuscation.

If you're doing anything that combines using .NET properties for storage and you're relying on that special 'property' structure to be maintained through to the other side of the obfuscation, you need to obfuscate your assembly using Dotfuscator's 'library mode'.

In the Professional edition like we use, this property must be set (or not) on each assembly individually (as opposed to the Community edition, in which you set it for all assemblies or none).

Tuesday, May 15, 2007

A Little Java Humour

Nothing like some geeky humour to break the week up.
Check out this sweet batch of ads from RailsEnvy.

I totally dig all the crazy jars 'Java' has.

Friday, May 04, 2007

Design for Developers

CodingHorror had a couple of good pieces up recently about how important it is for software developers to get some basic design skills (including a tool like photoshop) under their belt.

I plan on using these as ammo when getting the dev manager at work to order these books for me and let me schedule their study into my time.

  1. Learn a Graphics Editor
  2. Get Some Design Know-How

Wednesday, March 21, 2007

Advice for juniors

I had hoped to do an article just like this someday. Maybe I still will. Either way, here's a great bit about what [needs to] go on for your first few years as a junior developer.