Entries from October 2008 ↓

Generated JVM byte code gives “stack shape inconsistent” error

I’ve been teaching myself how to generate JVM byte code directly for a side project recently, and got stuck on the following exception a few times:

Exception in thread "main" java.lang.VerifyError: stack shape inconsistent (class: CompiledTest method: evaluate(Lcom/ibm/test/Param;)S) at pc: 2
	at java.lang.J9VMInternals.verifyImpl(Native Method)
	at java.lang.J9VMInternals.verify(J9VMInternals.java:66)
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:127)
	at java.lang.Class.newInstanceImpl(Native Method)
	at java.lang.Class.newInstance(Class.java:1300)
	at TestHarness.execute(TestHarness.java:158)
	at TestHarness.main(TestHarness.java:100)

After a long time Googling unsuccessfully, I hacked around until stumbled across the answer. Turns out this exception is caused when your byte code is attempting to perform an instruction but the stack contains an invalid type for that instruction.

One example is if the top of the stack contains a string but you’re using a operand that expects an integer. Using BCEL:

//Push a string onto the stack
il.append( new PUSH( cg.getConstantPool(), "123" ));

//Attempt to save the top of the stack using "ISTORE"
LocalVariableGen var = mg.addLocalVariable( "var", Type.STRING, il.getEnd(), null );
il.append( new ISTORE( var.getIndex() ));

Note that I’m using the integer-specific ISTORE instruction to save the variable even though I’ve pushed the string “123″ onto the stack!  Try to execute the class generated from this code, and you’ll get the VerifyError from above.

The simple, and obvious in hindsight, fix is to change the ISTORE instruction to ASTORE.

Examining message contents when using WCF’s ServiceAuthorizationManager

Microsoft’s Windows Communication Foundation (WCF) provides a hook for inserting custom authorization modules to protect your web services.  By implementing a custom ServiceAuthorizationManager as per this tutorial, you can make the decision to allow access based on whatever custom logic you may desire.

Things can get a little tricky if you want to inpsect the incoming message itself, though.  Each message can be read only once in WCF, meaning that if you consume the message during authorization the actual service itself can no longer consume it.

Luckily WCF provides a manner in which you can buffer the message, copy it, and send an unconsumed copy to the underlying service.  Here’s the code I used to get this to work:

public override bool CheckAccess(OperationContext operationContext, ref Message message)
{
    MessageBuffer buffer =
        operationContext.RequestContext.RequestMessage.CreateBufferedCopy(8192);
    message = buffer.CreateMessage();
    Message internalCopy = buffer.CreateMessage();
    buffer.Close();

    //Examine 'internalCopy' during your authorization processing
    return authzResult;
}

The basic technique is outlined in these two posts on Nicholas Allen’s Indigo Blog:

Auto-formatting XML files

When you work with XML as much as I do, quite often you get sent a list of files that are not pretty-printed.  By “pretty-printed”, I mean nicely formatted with each new element on a new line and each nested element indented appropriately.

The files not being nicely formatted makes using command-line tools like grep nigh-on impossible, so quite often you have to format the files before you can get any real work done.

I’ve been using the following script to automatically format whatever XML files I pass it:


#!/bin/bash
for a
do
xmllint --format $a -o $a
done
exit 0

As you can see it just passes whatever arguments I pass to xmllint and over-writes the original in-place.

I’ve called my version of this file prettify.sh, and when it’s in the path you can invoke it like this:

[craigf@eleanor ~]prettify.sh *.xml

Update: I should’ve mentioned that xmllint is part of the libxml2 package. It should be available on most Linux distributions.