Monday, November 19, 2012

JSON-Schema generation in Jersey

So in my previous post I talked about a proposal to allow the use of JSON-Schema in a WADL, this post looks at how to get this working with a recently build of Jersey. You are going to have to download / reference 1.16SNAPSHOT until 1.16 is released.

If you are using Maven this should be quite straight forward to update your dependencies assuming you already have jersey and jersey-json. You are just going to need to add a dependency on the "jersey-wadl-json-schema" artefact from the "com.sun.jersey.contribs" group to get the new feature.

If you are outside of Maven the easiest thing to do would be to download the latest jersey-archive and then the jersey-wadl-json-schema jar. How you deploy these is tool specific, but if you are using WLS then here are some specific notes on how to upgrade the version of Jersey.

Once you have this working, you need to create a WadlGeneratorConfig class in order to enable this new grammar generation:

package jersey;

import com.sun.jersey.api.wadl.config.WadlGeneratorConfig;
import com.sun.jersey.api.wadl.config.WadlGeneratorDescription;
import com.sun.jersey.wadl.generators.json.WadlGeneratorJSONGrammarGenerator;

import java.util.List;

public class JsonGeneratorConfig extends WadlGeneratorConfig {
 
    @Override
    public List configure() {
        return generator(WadlGeneratorJSONGrammarGenerator.class).descriptions();
    }
}

This can then be registered in a variety of ways, here is an example using a servlet init param. Note also that to make this example simple that we are using the Jersey POJO mapping; but whilst writing this blog I noticed that this setting affected the format of the JSON version of the WADL in case you try this.

<?xml version = '1.0' encoding = 'ISO-8859-1'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.WadlGeneratorConfig</param-name>
      <param-value>jersey.JsonGeneratorConfig</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>/resources/*</url-pattern>
  </servlet-mapping>
</web-app>

So I put together a really simple echo service, just to check this is all working:

package jersey;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/echo")
public class EchoResource {
     

    @GET
    @Produces("application/json")
    public EchoBean echo() {
        EchoBean bean = new EchoBean();
        bean.setMessage("Hello");
        return bean;
    }

    @POST
    @Consumes("application/json")
    @Produces("application/json")
    public EchoBean echo(EchoBean echo) {
        return echo;
    }
    
}

and

package jersey;

public class EchoBean {
    public EchoBean() {
        super();
    }
    
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }


}

This very simple example results in the following WADL with the JSON-Schema elements referenced:

<?xml version = '1.0' encoding = 'UTF-8'?>
<ns0:application xmlns:ns0="http://wadl.dev.java.net/2009/02">
   <ns0:doc xmlns:ns1="http://jersey.java.net/" ns1:generatedBy="Jersey: 1.16-SNAPSHOT 11/19/2012 12:59 AM"/>
   <ns0:grammars/>
   <ns0:resources base="http://localhost:7103/Jersey/resources/">
      <ns0:resource path="/echo">
         <ns0:method id="echo" name="GET">
            <ns0:response>
               <ns0:representation mediaType="application/json" xmlns:ns2="http://wadl.dev.java.net/2009/02/json-schema" ns2:describedby="application.wadl/echoBean"/>
            </ns0:response>
         </ns0:method>
         <ns0:method id="echo" name="POST">
            <ns0:request>
               <ns0:representation mediaType="application/json" xmlns:ns3="http://wadl.dev.java.net/2009/02/json-schema" ns3:describedby="application.wadl/echoBean"/>
            </ns0:request>
            <ns0:response>
               <ns0:representation mediaType="application/json" xmlns:ns4="http://wadl.dev.java.net/2009/02/json-schema" ns4:describedby="application.wadl/echoBean"/>
            </ns0:response>
         </ns0:method>
      </ns0:resource>
   </ns0:resources>
</ns0:application>

The URI application.wadl/echoBean contains this simple JSON-Schema definition:

{
    "type" : "object",
    "properties" : {
        "message" : {
            "type" : "string"
        }
    },
    "name" : "echoBean"
}

Now there are a number of limitations in the current design, not least that the generated schema doesn't take into account any notation settings. But I thought this would be enough to provoke feedback on whether this feature would be useful generally. There appears to be a growing interest in JSON-Schema both around the net and internally to Oracle, so it would be interesting to see whether this description becomes more common.

Friday, November 16, 2012

JSON-Schema in WADL

In between other jobs I have been recently been reviewing the WADL specification with a view to fixing some documentation problems with a view to producing an updated version. One of the things that because apparent was the lack of any grammar support for languages other than XML - yes you can use a mapping from JSON<->XML Schema but this would be less than pleasant for a JSON purist.

So I began to look at how one would go about attaching a JSON-Schema grammar of a JSON document in a WADL description of a service. This isn't a specification yet; but a proposal of how it might work consistently.

Now I work with Jersey mostly, so lets consider what Jersey will current generate for a service that returns both XML and JSON. So the service here is implemented using the JAX-B binding so they both use a similar structure as defined by the XML-Schema reference by the include.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.16-SNAPSHOT 10/26/2012 09:28 AM"/>
    <grammars>
        <include href="xsd0.xsd">
            <doc title="Generated" xml:lang="en"/>
        </include>
    </grammars>
    <resources base="http://localhost/">
        <resource path="/root">
            <method id="hello" name="PUT">
                <request>
                    <representation xmlns:m="urn:message" element="m:requestMessage"  mediaType="application/json" />
                    <representation xmlns:m="urn:message" element="m:requestMessage" mediaType="application/xml" />
                </request>
                <response>
                    <representation xmlns:m="urn:message" element="m:responseMessage" mediaType="application/json"/>
                    <representation xmlns:m="urn:message" element="m:responseMessage" mediaType="application/xml" />
                </response>
            </method>
        </resource>
    </resources>
</application> 

So the first thing we considered was re-using the existing element property, which is defined as a QName, on the representation element to reference an imported JSON-Schema. It is shown here both with and another an arbitrary namespace to it can be told apart from XML elements without a namespace.

<grammars>
        <include href="xsd0.xsd" />
        <include href="application.wadl/responseMessage" />
    </grammars>


    <representation element="responseMessage" mediaType="application/json"/>

Or
    xmlns:json="http://wadl.dev.java.net/2009/02/json" 

    <representation 
        element="json:responseMessage" mediaType="application/json" />


The problem is that the JSON-Schema specification as it stands doesn't have a concept of a "name" property, so each JSON-Schema is uniquely identified by it's URI. Also from my read of the specification each JSON-Schema contains the definition for at most one document - not the multiple types / documents that can be contained in XML-Schema.

So the next best suggestion would be to just use the "filename" part of the URI as a proxy for the URI; but of course that won't necessarily be unique. I could see for example the US government and Yahoo both publishing there own "address" micro format.

The better solution to this problem is to introduce a new attribute, luckily the WADL spec was designed with this in mind, that is of type URI that can be used to directly reference the JSON-Schema definitions. So rather than the direct import in the previous example we have a URI property on the element itself. The "describedby" attribute name comes from the JSON-Schema proposal and is consistent with the rel used on atom links in the spec.

xmlns:json="http://wadl.dev.java.net/2009/02/json-schema" 
    xmlns:m="urn:message" 


    <grammars>
        <include href="xsd0.xsd" />
    </grammars>

    <representation 
        mediaType="application/json"
        element="m:responseMessage" 
        json:describedby="application.wadl/responseMessage" />


The has the secondary advantage in that this format is backwardly compatible with tooling that was relying on the XML-Schema grammar. Although this is probably only of interesting to people who work in tooling / testing tools like myself.

Once you have the JSON-Schema definition then some users are going to want to do away with the XML all together, so finally here is a simple mapping of the WADL to a JSON document that contains just the JSON-Schema information. It has been suggested by Sergey Breyozkin the JSON mapping would only show the json grammars and I am coming around to that way of thinking. I would be interested to hear of a usecase for the JSON mapping that would want access to the XML Schema.

{
   "doc":{
      "@generatedBy":"Jersey: 1.16-SNAPSHOT 10/26/2012 09:28 AM"
   },
   "resources":{
      "@base":"http://localhost/",
      "resource":{
         "@path":"/root",
         "method":{
            "@id":"hello",
            "@name":"PUT",
            "request":{
               "representation":[
                  {
                     "@mediaType":"application/json",
                     "@describedby":"application.wadl/requestMessage"
                  }
               ]
            },
            "response":{
               "representation":[
                  {
                     "@mediaType":"application/json",
                     "@describedby":"application.wadl/responseMessage"
                  }
               ]
            }
         }
      }
   }
}

I am currently using the mime type of "application/vnd.sun.wadl+json" for this mapping to be consistent with the default WADL mime type. I suspect we would want to change this in the future; but it will do for starters.

So this is all very interesting but you can't play with it unless you have an example implementation. I have something working for both the server side and for a Java client generator in Jersey and wadl2java respectively and that will be the topic of my next post. I have been working with Pavel Bucek on the Jersey team on these implementations and the WADL proposal, thanks very much to him for putting up with me.

Thursday, October 11, 2012

Using Hudson/Jenkins to diagnose that intermittent failure


I have been working on one of those intermittent bugs that just won't reproduce on my machine; but will reproduce intermittently on other machines while they are running automated testing. I filled the code with trace statements, now I suspect the problem is in code that I don't control and doesn't appear to have much in the way of diagnostics in the place I am working on.

So I did the obvious thing which is to run the tests on a loop on my machine overnight, 12 hours later and 8 test iterations later, no test failures and I am no further forward.

Since the tests are failing in the Hudson farm, it make sense to try to connect the debugger up to those jobs; but I don't want to hang around to attach the remove debugger to each. Thankfully there is a workaround that will allow me to set suitable breakpoints and manage the debugger connection for me.

First of all you need to configure you IDE to accept incoming debugger connections, here are some notes on configuring JDeveloper for a listening debugger, in Netbeans you need to use the Debug->Attach menu item and select "SocketListen" as the connector and configure as per JDeveloper. In Eclipse you need to configure the debug type as "Socket Listen".

The second step is modifying your build system so that there is a target you can call that will start the test cases in debug mode. This is an example of the parameters for one of our CI jobs that passes in the right information. Note of course the blacked out text the the name of then machine you are trying to connect back to. (The java tests are started with the parameter -agentlib:jdwp=transport=dt_socket,address=xxxx.oracle.com:5000,server=n) Make sure that you don't have any firewalls running on that machine that will block the in-coming connections.




You probably will want to run to run multiple jobs at the same time if you have the nodes available, so consider checking this concurrent build box. Always a good idea to bring cakes / cookies into the office if you are going to tie up all the preflight nodes for the day.




And then all that remains is to run a bunch of jobs and wait for your breakpoint to be hit, might take a little while; but it is going be quicker than running these jobs in series on your own machine. And if your farm is Heterogeneous so much the better for reproducing intermittent failures.



You can sit back and then wait for your code to fail..... may I suggest some sessions from JavaOne while you wait?

Thursday, October 4, 2012

wadl2java 1.1.3 released

So after a little bit of a pause we now have a new release of the wadl2java client generation tool. This is a wide range of improvements in this release; but the main feature is the new support for generating JAX-RS 2.0 client code.

This generated code is nearly identical to the Jersey 1.x interface so most simple code should compile straight after a swap without too many problems. If the client is making use of ClientResponse these references will have to be replaced with Response; but otherwise the interface will be consistent. I would welcome suggestions as to how I could improve what is generated.

So here is a list of items of changes in the release:
  • WADL-25, a patch to allow the passing in of argument to xjc, as provided by Brian Chapman thanks for that..
  • There is a problem in when there was not response content type, this type of method now returns the relevant Response object.
  • Classes that are @XmlType were being wrapped incorrectly with JAXBElement and the information was being taken from the return class.
  • The Proxy objects are now immutable, modifying any property created a new instance.
  • There is a now a programmatic interface to override the base URI at each level. (Suggested by Luigi Tagliamonte)
  • Fix for Oracle Bug 13804542, generation would fail if inner and outer class names match
  • JAX-RS 2.0 generation support available in all tool modes
  • Fix for Oracle Bug 14534583, where a fault element was being incorrectly upgraded from a '2006 WADL. This was causing problems with the examples SOAPUI were providing.
  • Fix for Oracle Bug 1462282, where the generated exception classes were not actually used in the generated code. All exceptions now extend WebAppilcationException to make migration from 1.x to 2.x easier.
  • Improved method generation, removed "application" from media types, removed duplication when method takes and returns the same type (putApplicationXmlAsApplicationXml -> putXml), moved "As" to correct location when we have a type, removed excessive method combinations where we have symmetrical media types. (eg xml,json->xml,json)
  • Initial work looking at how to support JSON-Schema type generation, non functional
  • Adding functional testing for generated clients as was previously only examining the generated classes. Now they are run for both 1.x and 2.x type clients.
 Thanks again as usual help from Pavel Bucek in getting this software out the door.


Thursday, September 20, 2012

So what credentials do you need?

One of the features that I am very proud of in the HTTP Analyzer in JDeveloper is the ability to test a SOAP service with the minimum of fuss. Rather than having to configure security headers and understand WS-Policy we make use of the WLS JAX-WS client to read and interpret the policies defined in the WSDL and then apply abstracted credentials.

It turns out that this feature is very popular; but there is some confusion about just what information you might need to provide for a particular policy. So here is a simple summary of what is required for what type of policy.

Username Token


The simplest page just ask for a username and password. You are going to need this for policies that contains the phrase usernametoken, username, UNT or even HttpBasic and HttpDigest. The policy dictates where the values end up whether they be in an HTTP header or a WS-Security SOAP header.




X509 Certificates


The X509 panel is the most powerful and the most misunderstood. On this panel you can define a set of certificates and keys for both the client and the server.



The simplest version of this panel would be one that just contains the server key store. This is sufficient in most policy to be able to send a server an encrypted message and receive a message back. (In the most common case the server certificate is used to encrypt a symmetrical key, most likely AES,  that can be used to decrypt the message being received.)

You will also need this to verify messages that are signed by the server.

If you need to server to trust that you send the message with signing then you have to provide a identity in the form of a Public/Private key that can be used to encrypt the outgoing hashes used to sign the message. 

This client identity can also be used in leu of the username token described earlier. In the most common policy I have worked with the CN of the public certificate is used as the user identity. 

Http Keystores


Some policies will make use of a Https channel to send messages, and like the x509 certificate panel the settings come in both client and server side store.

In the simplest case this panel will just be configured with a "Trusted Certificates Keystore", so this will list with certificates or certificate signing authorities are going to be trusted by the analyser. In order to make this as easy as possible by default we append the "CA" certificates that come with Java so you can by default connect to most publish websites without any further configuration.



This will normally be enough unless the policy is defined as 2-Way HTTPS, most of the OWSM https policies I have worked with are 2-Way by default. The WLS ones tend to specify this explicitly. In the 2-Way case you again need to prove the identity of the client, and the only way of doing this is going to be with a Public/Private key that the server trusts.

STS Configuration

The final panel regards working with policies that require SAML tokens; JDeveloper is unable to issue SAML tokens itself so instead it need to get hold of a token from a STS store that is trusted by the server you are in contact with.

In this case you need to specify the URL of the endpoint of the STS service along with a security policy that will match that on the sever side. This is unfortunately a static list and has to be figured out manually. Perhaps this is something that can be improved on in a later release.


On important feature to note is that when connecting to the STS store the analyser will be using values from the other three panels that we have discussed. This might be important if you are having trouble setting up a connection.

Wednesday, September 5, 2012

Changing delay, and hence the order, in a DelayQueue

So I was looking at building a simple object cache that expires the objects after a given time. The obvious mechanism for this is the use the DelayedQueue class from the concurrency package in Java; but I wanted to know if it way possible to update the delay after an object has been added to the queue. Looking at the Delayed interface there didn't seem to be a good reason not to in the docs so I thought it was time to experiment.

So first of all you need to to create an instance of Delayed, this is a very simple implementation that with the switch of a flag you can basically invert the timeout order in the list. (And add a suitable offset so things happen in the right order)

static int COUNT=100;


   class DelayedSwap implements Delayed, Comparable<Delayed> {

       int index = 0;
       volatile boolean swap = false;
       long starttime;

       public DelayedSwap(int index, long starttime) {
           super();
           this.index = index;
           this.starttime = starttime;
       }

       private long getDelay() {
           return (swap ? starttime + (2*COUNT - index) * 100 :
               starttime + index * 100) - System.currentTimeMillis();
       }


       public String toString()
       {
           return index + " swapped " + swap + " delay " + getDelay();
       }

       @Override
       public long getDelay(TimeUnit unit) {
           return unit.convert(getDelay(), TimeUnit.MILLISECONDS);
       }

       @Override
       public int compareTo(Delayed delayed) {
           if (delayed == this)
               return 0;

           return (int)(getDelay(TimeUnit.MILLISECONDS) - delayed.getDelay(TimeUnit.MILLISECONDS));
       }
   }


So to test this I created a method that would create a bunch of the DelayedSwap objects and half way through processing the list switch the flag so altering the order of expiration.

public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();
       final List delayed = new ArrayList();
       for (int i = 1; i < COUNT; i++) {
           delayed.add(new DelayedSwap(i, start));
       }

       final DelayQueue dq = new DelayQueue();
       dq.addAll(delayed);

       new Thread(new Runnable() {

           @Override
           public void run() {
               try {
                   TimeUnit.SECONDS.sleep(5);
               } catch (InterruptedException e) {
               }
               for (DelayedSwap d : delayed) {
                   d.swap = true;
               }
           }
       }).start();

       while (!dq.isEmpty()) {
           System.out.println(dq.take());
       }

   }

So what I was expecting was the elements 1-50 ish written out in the correct order but instead after the swap over the elements are coming out in an arbitrary order quite far away from the request delay time.

1 swapped false delay -19
2 swapped false delay -4
3 swapped false delay -4
4 swapped false delay -4
5 swapped false delay -4
6 swapped false delay -4
7 swapped false delay -4
8 swapped false delay -4
9 swapped false delay -4
10 swapped false delay -4
11 swapped false delay -4
12 swapped false delay -4
13 swapped false delay -4
14 swapped false delay -4
15 swapped false delay -4
16 swapped false delay -4
17 swapped false delay -4
18 swapped false delay -4
19 swapped false delay -4
20 swapped false delay -4
21 swapped false delay -4
22 swapped false delay -4
23 swapped false delay -4
24 swapped false delay -4
25 swapped false delay -4
26 swapped false delay -4
27 swapped false delay -4
28 swapped false delay -4
29 swapped false delay -4
30 swapped false delay -4
31 swapped false delay -4
32 swapped false delay -4
33 swapped false delay -4
34 swapped false delay -4
35 swapped false delay -4
36 swapped false delay -4
37 swapped false delay -4
38 swapped false delay -4
39 swapped false delay -5
40 swapped false delay -4
41 swapped false delay -4
42 swapped false delay -5
43 swapped false delay -4
44 swapped false delay -5
45 swapped false delay -5
46 swapped false delay -5
47 swapped false delay -5
48 swapped false delay -5
49 swapped false delay -5
50 swapped false delay -5
51 swapped true delay -6
94 swapped true delay -4306
96 swapped true delay -4506
87 swapped true delay -3606
91 swapped true delay -4006
97 swapped true delay -4606
95 swapped true delay -4406
98 swapped true delay -4706
92 swapped true delay -4106
82 swapped true delay -3106
80 swapped true delay -2906
90 swapped true delay -3906
93 swapped true delay -4206
74 swapped true delay -2306
99 swapped true delay -4806
70 swapped true delay -1906
69 swapped true delay -1806
66 swapped true delay -1506
83 swapped true delay -3206
62 swapped true delay -1107
61 swapped true delay -1007
58 swapped true delay -707
71 swapped true delay -2007
89 swapped true delay -3807
85 swapped true delay -3407
78 swapped true delay -2707
86 swapped true delay -3507
81 swapped true delay -3007
88 swapped true delay -3707
84 swapped true delay -3307
79 swapped true delay -2807
76 swapped true delay -2507
72 swapped true delay -2107
68 swapped true delay -1707
65 swapped true delay -1407
60 swapped true delay -907
57 swapped true delay -608
55 swapped true delay -408
75 swapped true delay -2408
77 swapped true delay -2608
73 swapped true delay -2208
63 swapped true delay -1208
67 swapped true delay -1608
64 swapped true delay -1308
59 swapped true delay -808
56 swapped true delay -508
54 swapped true delay -308
53 swapped true delay -208
52 swapped true delay -108
Process exited with exit code 0.

So the trick is when you know you are going to modify the delay is to remove and then re-add the element to the queue.

// Replacement swap loop
    for (DelayedSwap d : delayed) {
        if (dq.remove(d))
        {
            d.swap = true;
            dq.add(d);
        }
    }

This run produces a more sensible set of results:

1 swapped false delay -4
2 swapped false delay -8
3 swapped false delay -14
4 swapped false delay -8
5 swapped false delay -4
6 swapped false delay -4
7 swapped false delay -4
8 swapped false delay -4
9 swapped false delay -4
10 swapped false delay -4
11 swapped false delay -4
12 swapped false delay -4
13 swapped false delay -4
14 swapped false delay -4
15 swapped false delay -4
16 swapped false delay -4
17 swapped false delay -4
18 swapped false delay -8
19 swapped false delay -4
20 swapped false delay -4
21 swapped false delay -4
22 swapped false delay -4
23 swapped false delay -4
24 swapped false delay -4
25 swapped false delay -4
26 swapped false delay -4
27 swapped false delay -4
28 swapped false delay -4
29 swapped false delay -4
30 swapped false delay -4
31 swapped false delay -4
32 swapped false delay -4
33 swapped false delay -4
34 swapped false delay -4
35 swapped false delay -4
36 swapped false delay -4
37 swapped false delay -4
38 swapped false delay -4
39 swapped false delay -5
40 swapped false delay -5
41 swapped false delay -5
42 swapped false delay -4
43 swapped false delay -4
44 swapped false delay -5
45 swapped false delay -5
46 swapped false delay -5
47 swapped false delay -5
48 swapped false delay -5
49 swapped false delay -5
50 swapped false delay -5
99 swapped true delay -5
98 swapped true delay -5
97 swapped true delay -11
96 swapped true delay -1
95 swapped true delay -5
94 swapped true delay -9
93 swapped true delay -5
92 swapped true delay -5
91 swapped true delay -5
90 swapped true delay -5
89 swapped true delay -5
88 swapped true delay -5
87 swapped true delay -5
86 swapped true delay -5
85 swapped true delay -5
84 swapped true delay -5
83 swapped true delay -5
82 swapped true delay -5
81 swapped true delay -5
80 swapped true delay -5
79 swapped true delay -5
78 swapped true delay -5
77 swapped true delay -5
76 swapped true delay -5
75 swapped true delay -5
74 swapped true delay -5
73 swapped true delay -5
72 swapped true delay -6
71 swapped true delay -5
70 swapped true delay -5
69 swapped true delay -5
68 swapped true delay -5
67 swapped true delay -5
66 swapped true delay -5
65 swapped true delay -5
64 swapped true delay -5
63 swapped true delay -6
62 swapped true delay -5
61 swapped true delay -6
60 swapped true delay -6
59 swapped true delay -6
58 swapped true delay -6
57 swapped true delay -6
56 swapped true delay -6
55 swapped true delay -6
54 swapped true delay -6
53 swapped true delay -6
52 swapped true delay -6
51 swapped true delay -6
Process exited with exit code 0.

I don't think this is a bug in the object itself, as you wouldn't expect a HashTable to orders it's self when the key changes, but I was a little bit surprise by the behaviour.



Thursday, June 28, 2012

Catch a StackOverFlowError by its tail

One of the more annoying situations you might have to deal with when working with a Java program is a StackOverFlowError, if you have a nice producible test case then there are few options with regard to playing with the stack size, or setting a conditional breakpoint / trace of some kind.

But if you have a test case that might fail once in a 100 times, perhaps a race condition in AWTMulticaster as in my case, then you want to improve the diagnostics. The problem is that by default the VM won't any elements in a stack trace after the first 1024 entries. (At least for JDK 6) So if you run the following trivial example:

package other;

public class Overflow {


   public static final void call(double a, double b, double c, double d) {
       call(a,b,c,d);
   }


   public static void main(String[] args) {
       call(0,0,0,0);
   }

}

The output will stop before you get to the cause of the problem, making it very hard to resolve the issue.

> java other.Overflow 
Exception in thread "main" java.lang.StackOverflowError
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
        [ lots of lines removed ]
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
Process exited with exit code 1.

The good news is that this limit is one of the many official and unofficial things you can tweak when starting a VM.


> java -XX:MaxJavaStackTraceDepth=1000000 other.Overflow 
Exception in thread "main" java.lang.StackOverflowError
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
        [ lots of lines removed ]
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.call(Overflow.java:7)
 at other.Overflow.main(Overflow.java:12)
Process exited with exit code 1.

Notice that end of the stack now contains the root of the problem which will be incredibly useful when trying to diagnose the issue.

You probably don't want to leave this property set long term on a production servers because I am not entirely sure about the impact of it. Looking at the C++ code it appears that this is just a maximum value and won't affect most other stack traces as they are allocated in a linked list in segments of 32 entries.

Wednesday, May 30, 2012

try/with/resources refactoring that isn't


So I was looking at refactoring some code to use the new try/with/resources construct and found that perhaps it is not as simple as it first appears.

class Close implements AutoCloseable
   {
       @Override
       public void close() {
           System.out.println("Close");
       }
   }


   System.out.println("Normal version");


   Close close = new Close();
   try {
       throw new Error();
   }
   catch (Error e) {
       System.out.println("Catch");
   }
   finally {
       close.close();
   }

So the output for this is pretty easy to predict; but lets write it out just to be clear.

Normal version
Catch
Close

So this is pretty easy, lets throw some JDK 7 goodness on the code, this is an obvious refactoring right?

System.out.println("JDK 7 version");

   try (Close close2 = new Close()) {
       throw new Error();
   }
   catch (Error e) {
       System.out.println("Catch");
   }

So you can be pretty sure that given I am writing this up that the output is not going to be the same.


JDK 7 version
Close
Catch

So in this case the close is called before the catch, this might not be a problem but in some cases the catch block might need to make use of the resource before everything is shut down. If you want to perform a "refactoring" the code must behave the same before and after the changes. The following code is equivalent to the JDK 7 version without the try/with/resources

System.out.println("JDK 6 equivalent of JDK 7 version");

   Close close3 = new Close();
   try {
       try {
           throw new Error();
       }
       finally {
           close3.close();
       }
   }
   catch (Error e) {
       System.out.println("Catch");
   }


Just for completeness here is one possible refactoring of the original code which is functionally equivalent. Note quite as pretty I am afraid.

System.out.println("JDK 7 equivalent of original try/catch/finally");

   try (Close close4 = new Close()) {
       try {
         throw new Error();
       }
       catch (Error e) {
           System.out.println("Catch");
       }
   }

Now I ran this past my colleague Mark Warner and like me was surprised by the result. Mark pointed out that this nuance is noted in the java tutorial....

Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.

...but it does feel like this rather important distinction is part of the small print that some people might at first glance assumed is related to the SQL example above it. (Yeah okay I didn't read the SQL example down to the end)

Again not something that will be a problem all the time; but it might be an important consideration in some quite important use cases.


try/with/resource context class loaders


For various reasons I seem to end up writing a lot of code that fiddles with the context class loader in order to get non-module code running in the OSGi environment that JDeveloper runs in. This leads to a whole bunch of code that looks like this:

 public void doSomething() {

       ClassLoader context = Thread.currentThread().getContextClassLoader();

       try {
           Thread.currentThread().setContextClassLoader(Example.class.getClassLoader());

           // Class class that required the context class loader
           Endpoint.publish(null, null);            
       }
       finally {
           Thread.currentThread().setContextClassLoader(context);

       }  
  }


Now it occurred to me that the try/with/resources feature in JDK 7 isn't just for the nasty things in life, well resources, you can use it for any operation that might previously used a try/finally for.



   public void doSomething() {

       try (CloseableContext c = contextClassLoader(Example.class)) {

           // Class class that required the context class loader
           Endpoint.publish(null, null);            
       }
   }


It would have been nice to just call the method an not to allocate any variables as in the following example but it isn't allowable in the spec.


   public void doSomething() {

       try (contextClassLoader(Example.class)) { // Compilation errors

           // Class class that required the context class loader
           Endpoint.publish(null, null);            
       }
   }


Still the implementation of this is rather trivial and does still tidy up the original code. The only wrinkle is the  need to have a public class/ interface subtype of AutoCloseable so that we can narrow the throws clause on the close() operation. If you don't do this then the original code has to deal with "throws Exception".



   public static CloseableContext contextClassLoader(Class loader) {
       return contextClassLoader(loader.getClassLoader());
   }

   public static CloseableContext contextClassLoader(ClassLoader loader) {
       final Thread currentThread = Thread.currentThread();
       final ClassLoader ocl = currentThread.getContextClassLoader();
       currentThread.setContextClassLoader(loader);
       return new CloseableContext(currentThread, ocl);
   }

   public static class CloseableContext implements AutoCloseable {
       private Thread _currentThread;
       private ClassLoader _ocl;

       private CloseableContext(Thread currentThread, ClassLoader ocl) {
           this._currentThread = currentThread;
           this._ocl = ocl;
       }

       @Override
       public void close() {
           this._currentThread.setContextClassLoader(this._ocl);
       }
   }

Saturday, May 26, 2012

Ignoring the return value of a command in Hudson/Jenkins sh task

So I was was trying to run pylint and nosetest running on a Jenkins instance; but these python commands tend to return a non zero status code if they see a non zero return code. This is a problem as it means that any further steps are ignored. The most obvious thing to try was this:

pylint src/openhea -f parseable ; true

The problem is that both statements are treated as separate steps so when the first one fails it never does the return true. Instead, and pointed out by a helpful chap in the #efdhack2012 room was to do the following

pylint src/openhea -f parseable || true

This correctly ignores the false status code, the only wrinkle is that you need to be careful when piping the output, it has to be to the left of the bars.

pylint src/openhea -f parseable > output.report || true

Thursday, May 10, 2012

Common try-with-resources idiom won't clean up properly

So I was re-reading some blogs on the JDK 7 language changes and I noticed the following idiom seems popular:

//
try (BufferedReader br = new BufferedReader(
        new FileReader("/tmp/click.xml"))) {
   System.out.println(br.readLine());
}

That seems all well and good; but consider what happens should something goes wrong constructing the BufferedReader. The contract for try-with-resources will only try to close and tidy up the declared field, if something goes wrong then FileReader is never closed.

So consider this example where the constructor of BufferedReader throws an Error, it could well be an OutOfMemoryError or any number of other failure modes.

//
package client;

import java.io.*;

public class BufferedFileExample {

    public static void main(String[] args) throws FileNotFoundException, 
                                                  IOException {

        try (BufferedReader br = new MyBufferedReader(
            new MyFileReader("/tmp/click.xml"))) {
            System.out.println(br.readLine());
        }
    }
    
    public static class MyFileReader extends FileReader 
    {

        public MyFileReader(String in) throws FileNotFoundException {
            super(in);
        }
        
        public void close() throws IOException {
            super.close();
            System.out.println("Close called");
        }
    }
    
    
    
    public static class MyBufferedReader extends BufferedReader 
    {

        public MyBufferedReader(Reader in) {
            super(in);
            throw new Error();
        }
    }
}

This gets us the following output and as such the close is not performed on the FileReader which until the finaliser is called. You are stuck until the gc wakes up in the future to tidy it up.

Exception in thread "main" java.lang.Error
 at client.BufferedFileExample$MyBufferedReader.(BufferedFileExample.java:38)
 at client.BufferedFileExample.main(BufferedFileExample.java:12)
Process exited with exit code 1.

Luckily there is an easy fix for this, the language change supports multiple entries in try statement, so you can modify this code to be:

//
try (FileReader fr = new MyFileReader("/tmp/click.xml");
     BufferedReader br = new MyBufferedReader(
        fr)) {
   System.out.println(br.readLine());
}

So if you run the code with the modification above then you find that close is now called:

Close called
Exception in thread "main" java.lang.Error
 at client.BufferedFileExample$MyBufferedReader.(BufferedFileExample.java:38)
 at client.BufferedFileExample.main(BufferedFileExample.java:12)
Process exited with exit code 1.

So problem solved, well unfortunately there is another wrinkle here, if we remove the code that throws the Error then we will see the following output:

Close called
Close called
Process exited with exit code 0.

So this is fine for classes that implement the existing java.io.Closeble interface because calling close for a second time is fine; but the more generic interface that is used for other closeable resources unfortunately doesn't have this restriction, so quote the spec

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.

So in order to using a split-try-with-resources idiom you first need to make sure that the resources have a idempotent close method. I suspect that most API will do this; but you need to check first and perhaps need to further wrap your objects to make this the case.

One final point with try-with-resource is the handling of exceptions when the close and construction fails. JDK 7 introduced the concept of suppressed exceptions, so you it make the split version of the code throw an exception both in the constructor or the MyBufferedReader and in the close of MyFileReader you get to see the following novel stack trace.

Close called
Exception in thread "main" java.lang.Error
 at client.BufferedFileExample$MyBufferedReader.(BufferedFileExample.java:38)
 at client.BufferedFileExample.main(BufferedFileExample.java:12)
 Suppressed: java.lang.Error: close
  at client.BufferedFileExample$MyFileReader.close(BufferedFileExample.java:27)
  at client.BufferedFileExample.main(BufferedFileExample.java:14)
Process exited with exit code 1.

This might not be what you calling code is expecting - certainly it might differ slightly from what the try/finally code you are replacing would produce, worth know thing that exceptions are handled slightly differently. For example if there is just an Error thrown during the close method would would see this odd self-referential stack trace.

Close called
Close called
Exception in thread "main" java.lang.Error: close
 at client.BufferedFileExample$MyFileReader.close(BufferedFileExample.java:28)
 at java.io.BufferedReader.close(BufferedReader.java:517)
 at client.BufferedFileExample.main(BufferedFileExample.java:15)
 Suppressed: java.lang.Error: close
  at client.BufferedFileExample$MyFileReader.close(BufferedFileExample.java:28)
  ... 1 more
Process exited with exit code 1.

So the lesson here is that the impact of some of the new JDK 7 constructs are going to a little bit subtler than we might expect. Many thanks to my valued colleague Mark Warner for talking this one through with me.

Tuesday, April 3, 2012

Off-loading test execution using Hudson part 3, skipping the queue

Previously I had looked at preflighting, (1, 2) with Hudson (And Jenkins) but forgot to mention a very important plugin that is essential if you want to convince your developer to preflight there work. The problem is that is the slave allotment/smallholder/farm is busy running other jobs then they are forced to wait before merging.

The easy solution to this problem is the priority sorter plugin. This allows you to specify that some jobs are more or less important then others. The default priority is 100, so seeing your preflight job to 1000 should see it jump to the front of the queue.

It is interesting how the length of tests affects my commuting behaviour, now that is take around an hour to run the long tests just for our components. It makes sense to start a work at home, kick of a job and you should have you nice shiny test results by the time we get into work. One day I might even get a blue ball if I am so very lucky with our dependencies. :-)

Friday, March 16, 2012

Catalog support for WADL client generation

I have just been fixing a few bugs in the WADL client generator that I have been working on recently. In particular one bug relates to being able to control the server the client uses at deploy time. (WADL-44)

So for example you have a standard packaged ?ar file that contains a client to a production service, in order to run automated testing you want to be able to use the same archive; but redirect the request to an internal server. Using a deployment plan, for example, you can update or introduce an extra deployment descriptor called META-INF/jax-rs-catalog.xml.

Only the base URI for each root resource in the WADL is updated; but this should be enough for most cases. (Would be interested to hear where people though this was limiting). This simple example redirects the client from a production service to a qa server.

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
  <uri name="http://production.example.com/resource"
          uri="http://qa.example.com/resource"/>
</catalog>

If you want to play with this you are going to have to check out the tip of the WADL client project for the moment; but in the coming weeks it will be part of the 1.1.2 release. Feedback always welcome.

Monday, January 23, 2012

Off-loading test execution using Hudson part 2

Previously I have written about using Hudson to perform pre-flights using branches on source control systems; but sometimes you just have a patch file that you want to run your tests against.

It turns out this can be quite simple, you just need to make use of a job parameter that takes a File as it's input, this is then written to the specified location in the workspace. In my example I have the following two parameters, the Title allow me to name the job and this property is picked up later by the job Description plugin.

Once you know where the patch is located you can just apply the patch before you perform the required build steps, here is an example using SVN so we use the unix patch command, git users can use the git command instead for this.

And there you are, you can test a user submitted patch for testing without tying up your development machine. You can also run the tests more than once to check for any intermittent tests which can be very valuable in concurrent environments.