Wednesday, December 2, 2009

Have a job, join us in the JDeveloper WebServices/ Spring/ Weblogic SCA team

We are loosing a valued member of our team to Australia so we are looking to a talented developer to join us in the Reading, UK office. You can find out a little bit more by visiting the jobs page and searching for job 203089.

If you know me and are interested get in touch directly, so I can pass your information on. (Okay and claim the recruitment bonus if we take you :-) )

Monday, November 30, 2009

At UKOUG'09 today and tommorrow

REST using Jersey today, and WS-Secutiry tomorrow at lunch time. Camping out in the speakers lounge doing prep. Lovely day outside, just a bit cold to be working outside.

Monday, November 2, 2009

Debugging groovy in ADF

So I have completed my introduction to ADF course so will hopefully be able to start work on the side projects we have been given time for. It was interesting just how easy it was to do a lot of common things in ADF.

One this that did concern a lot of use was how to debug certain parts of ADF. Steve has a post on this topic but that doesn't say anything about the numerous cases where groovy is used as an expression language.

Since Groovy runs on the same VM as your application you can easily call out to external classes, so you simply need to create a handy debug class that returns the value it is passed in:

package project2;

public class Debug {
    public static <T> T debug(T object, Object... objects) {
        return object;
    }
}

You can then put this in your scripts, for example in this derived attribute on a view object:

You can then inspect both the value you have calculated along with any parameters you have passed in using the debugger:

It seems that by default the groovy scripts are not compiled to bytecode which is a shame as you can't step out into the groovy code; but this little hack can help in certain situations. Thank to my co worker Alan Davis for pointing out that there way a simpler method than generating a class with the client "breakpoint" bytecode in it :-).

Thursday, October 22, 2009

Know which class you want but not which library?

This little feature in JDeveloper often goes unnoticed as people assume the search box filters on the library name. In fact it searches all library definitions for classes of the given name:

Don't need it very often; but when you do it is a god send.

Tuesday, October 13, 2009

Taking on the Spring Extension for JDeveloper

Had some interesting news that our team in the UK is taking over the Spring tooling in JDeveloper. There has been for a long while support for Spring tooling provided as an optional extension written by Duncan Mills. This will be the first time that a team has been able to work on it full time.

Of course don't expect to see anything that is the result of this change until a release after R11 PS1*. We would of course be interested to hear any views and opinions on what lovely** new features that related to Spring integration that users would be interested in.

* Standard disclaimer, this statement shouldn't be taken as a promise that we will ship this feature at any point in the future. Nor does it promise we will ever ship another version of JDeveloper.

** The lovelyness of your new feature may down as well as up

Monday, October 12, 2009

How to have more than one instance of AWT

I have been pondering a problem with the Costello, the test recording tool in Abbot. The one main draw back to this tool is that you can't access the recording window then the application you are testing has a modal dialog showing. This is a sever limitation that we can work around to some extent by modifying the window exclusion type for the Costello window after it is shown.


import abbot.editor.Costello;
import abbot.editor.ScriptEditorFrame;


{
  ...

  Costello.showCostello(ec);


  for (Frame next : Frame.getFrames() )
  {
    if (next instanceof ScriptEditorFrame)
    {
      next.setModalExclusionType(
        Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
    }
  }

  ...
}

This is fine if you can accept that dialogs that used to be modal on Costello are no longer; but this is likely to cause bugs as the developer of Costello wasn't expecting this. (What does it mean to have two file open dialog up at the same time?)

(Anybody who believes in the sanctity of the Event Dispatch Thread please look away now, this means you Alex)

Underneath the covers swing makes use of the AppContext class to maintain the settings of a particular "instance" of AWT. For most cases you only have the one instance; but you need more in the case of applets in order to isolate them from each other. Each AppContext also has its own event thread so a deadlock in one applet cannot affect another. (Useful for helping a user when say JDeveloper deadlocks)

The actual AppContext is contained within a kinda inheritable-ThreadGroup-local variable. By default all thread groups will default to default "main" AppContext; but if you create a new ThreadGroup and an AppContext every thread and group under this will make use of the new context. Consider the following code that puts up a frame with a modal child window both on the "default" AppContext and a new AppContext created for just this occasion:


import sun.awt.AppContext;
import sun.awt.SunToolkit;

...

public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    new Example("Main Event Thread");

    ThreadGroup group = new ThreadGroup("SomeOtherGroup");
    new Thread(group, "Start Another Frame") {
            public void run() {
                // Create a new appContext
                AppContext appContext = SunToolkit.createNewAppContext();
                // Create a second frame, independent from the first
                new Example("Other Event Thread");
            }
        }.start();
}

You end up with two windows each able to show a modal dialog at the same time. You can just about make out the different look and feels:

A quick look at the debugger shows that indeed we do have two independent event dispatch threads:

The only thing that is shared between the different AppContext is java.awt.Component.LOCK which is a bit of a pain. I am thinking about logged a bug saying that the tree lock should be on the AppContext to prevent one from blocking another. You can see this would be quite a trivial DOS applet attack. The most obvious work around is to re-load the classes in a separate class loader; but that presents some interaction issues so I will leave that as an exercise to the reader.

Friday, October 9, 2009

Suspend thread in JDeveloper debugger

Just found this little feature whilst working on a narly abbot issue. Basically it allows you to "stop" a thread from executing. This is really useful when debugging threading issues as you can use it to rule out a particular thread as to be the one causing the issue.

It would have been nice if there was a "suspend all other" threads action; but I have logged a bug for this so hopefully there will be one day.

Thursday, October 8, 2009

Project Dogfood, why I am going to spend 20% of my time writing ADF apps

Most of the people working on JDeveloper spend a lot of time writing in Java to support developers who build ADF applications. Unfortunately this doesn't give us developer a lot of daily experience building the sort of application that our customer build day to day using our tools. Particular those of use like myself who work on more general JEE technologies such as web services.

To try and fix this, and hopefully improve the development experience for all of our users, our gov'ner Ted has decreed in the next cycle that every part of of the JDeveloper development team will take time out to build real ADF apps.

To do this 20% of our working week has been set aside in the next development cycle. (The one after next from the customer's point of view) We all have to work in teams to build new and hopefully interesting applications. The parameters of the applications are not defined yet; but we should see some interesting projects coming out of the wood.

This is good news for me of course as it allow me broaden my skills, CometD here I come, and to take some time to escape from web services on day a week. It will be interesting to see how this works with the pressures of releasing production software; but I hope we do get the time as this will be a very interesting experiment. I will let you know how it goes.

Monday, October 5, 2009

Proxy client based on Jersey with a bit of HATEOAS built in, version 2

I had some feedback and some time to reflect on my previous blog posting on this topic. So here is a revised version of that post. The basic proxying mechanism is the same; but how we deal with references to resource has been updated to remove any references to URIs. (Thank for the push in that direction Solomon.)

The root BucketsResource class is little changed from before, I had just added "Resource" post fix to make it easier to tell them apart from the bean.

package bucketservice;

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("buckets")
public interface BucketsResource {

    @POST
    public BucketResource createNewBucketBound(String input);

    @GET
    @Produces("application/buckets+xml")
    public BucketList getBuckets();
    
    @Path("/{id}")
    public BucketResource getBucket();
}

The BucketResource class is slightly different than before in that we now specify a JAXB mapping class. The implementation of this is not important for the moment; but behind the scenes it converts the resource into a URI. For the purposes of XML (un)marshalling this type is now a URI. (I haven't tested it but this would most likely be the type in the published schema)

package bucketservice;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.core.Response;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import proxy.ResourceAdapter;


@XmlJavaTypeAdapter(BucketResource.Adapter.class)
public interface BucketResource {
     
    public static class Adapter
      extends ResourceAdapter<BucketResource> {
        
    }
    

    @GET 
    public String getBucket();

    @DELETE 
    public Response.Status delete();

}

Finally since we have put the XML "smarts" in the resource interface the BucketList class no longer needs to have any custom code generation.

package bucketservice;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class BucketList 
{
    
    BucketResource list[];

    public void setList(BucketResource[] list) {
        this.list = list;
    }

    public BucketResource[] getList() {
        return list;
    }
}

The client code is the same as before; but instead using the native getList method rather than the method we no longer have to generate. The advantage of working this way is that the two lists don't have to be maintained in sync as we would have done previously.

The problem that is not addressed is how to easily map domain objects into URIs; but Solomon has a reasonable solution to this in his blog. I am not sure though whether this as useful for the client case as your needs are different than when writing the server.

I did some work on converting values into resource objects cleanly by reading the annotations on the supplied resources. This would make it easier for a bean to for example create a "this" resource which would render as a URI. I need to write the code that will take a resource and extract the parameters in order to make this work bi-directionally.

    // Creating new buckets
    //
        
    BucketResource b15 = of(rootResource,BucketResource.class, BucketsResource.class).build(
                   "15");

    ResourceBuilder<BucketResource> bucketBuilder =
        of(rootResource, BucketResource.class, BucketsResource.class);

    BucketResource b7 = bucketBuilder.build(
                   "7");
    BucketResource b8 = bucketBuilder.build(
                   "8");

    // Extract parameters from a given set of resources
    //

    assert "8".equals(bucketBuilder.extract(b8);

I guess you could use the following to generate a self reference; but it is just not as pretty as Solomon's version.


    // Generating a "self reference"

    public class Bean
    {
       @XmlJavaTypeAdapter(BeanResourcePropertyAdapter.class)
       private String id;
    }

    public BeanResourcePropertyAdapter extends XmlAdapter<URI, String>
    {
       // TODO work out whether ??? can be derived from a context

       public URI marshal(String id)
       {
          return = ((ProxiedResource)of(????, BeanResource.class).build(id))
              .getURI();
       }

       public String unmarshal(URI br)
       {
          return of(????, BeanResource.class).extract(br);
       }
    }

A good deal more thinking on this to be done; but enough for today. Time to get some feedback.

Friday, September 18, 2009

java.lang.reflect.Proxy client based on Jersey with a bit of HATEOAS built in

Many people prefer the kind of dynamic fluent API that Jersey provides for calling RESTful services. This doesn't suit every situation though and in some cases it would be nice to have a statically typed interface. RESTEasy provides something along these lines; but I wanted something that worked with Jersey and to take it a bit further to support basic HATEOAS.

So consider the following two interfaces and one bean class that make up the service we are trying to call. Note that there isn't a one to one mapping with the server classes as unlike with SOAP/WSDL you can be a bit flexible. It wouldn't make sense to generate a static client that supports both XML and JSON content types for example where-as the server would support both.

package bucketservice;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

@Path("buckets")
public interface Buckets {

    @POST
    public Bucket createNewBucketBound(String input);


    @GET
    @Produces("application/buckets+xml")
    public BucketList getBuckets();
    
    
    @Path("/{id}")
    public Bucket getBucket(@PathParam("id") String id);
}

Note there is a method for getting a bucket from an "id" property; but more likely you are going to want to create a resource directly from the URI. This you can do easily as we will see later.

The bucket itself is really simple as it just exposes the get and delete services.

package bucketservice;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;

public interface Bucket {

    @GET 
    public String getBucket();

    @DELETE 
    public Response.Status delete();

}

The bean class is straight forward enough but there is an extra annotation @MappedResource which is used to produce an extra method that is in terms of the resource rather than URIs. Currently this work is done with a Mk1 Human Generator but it wouldn't take too long to implement with with the APT.

package bucketservice;

import javax.xml.bind.annotation.XmlRootElement;

import proxy.MappedResource;


@XmlRootElement
public class BucketList 
{
    
    URI list[];

    public void setList(URI[] list) {
        this.list = list;
    }

    @MappedResource(Bucket.class)
    public URI[] getList() {
        return list;
    }
}

So the key part of the client example below is a static "of" method on ClientProxy that takes as it's input a web resource and the interface you want to use to talk to this resource and return a dynamic proxy based on the interface. This resource location shouldn't include any sub path information included on the interface.

The call to createNewBucketBound(...) results in a HTTP response of "201 Created" with the location of the resource as a URI. The proxy code knows the return type so will return a new proxy for the Bucket interface as determined by the return type of the method. You can then go off and happily invoke methods on this such as get or delete as if it was the real interface.

The rest of the method gets hold of a list of buckets, again these are dynamic proxies based on the interface given; deletes the resource, then show the list again to be sure.

package bucketclient;


import bucketservice.Bucket;
import bucketservice.BucketList;
import bucketservice.Buckets;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;

import static java.lang.System.out;

import java.net.URI;

import static proxy.ClientProxy.of;

import proxy.hateoas.HATEOASClientConfig;
 

public class BucketClient {
    public static void main(String[] args) {

        Client client = Client.create(new HATEOASClientConfig());
        WebResource rootResource = client.resource("http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/");
        
        // Proxy

        Buckets buckets = of(rootResource, Buckets.class);
        out.println("Using proxy " + buckets);
        
        // Create me two buckets, note nothing is returned in the body of
        // the response message, just a location in the header. 
        //
        
        Bucket firstBucketRSP = 
            buckets.createNewBucketBound("First Bucket"); // POST -> 201
        Bucket secondBucketRSP = 
            buckets.createNewBucketBound("Second Bucket"); // POST -> 201
        
        // Get the contents of each
        //

        out.println("<Contents of buckets>");
        out.println(firstBucketRSP + "First # " 
           + firstBucketRSP.getBucket()); // GET .../id -> 200 text/plain
        out.println(secondBucketRSP + "# " 
           + secondBucketRSP.getBucket()); // GET .../id -> 200 text/plain
        out.println("</Contents of buckets>");
        
        // Get the list of buckets, use the injected getListAsResource method
        // to get bound interfaces
        //

        BucketList bucketList 
            = buckets.getBuckets(); // GET .../ -> 200 application/buckets+xml
        out.println("<Bucket List>");
        for (Bucket next : bucketList.getListAsResources()) {
            out.println("   " + next);
        }
        out.println("</Bucket List>");

        // Remove our buckets using the interface we had before
        //
        
        firstBucketRSP.delete(); // DELETE .../id -> 200
        secondBucketRSP.delete(); // DELETE ../id -> 200
        
        // Trace out bucket list again
        
        bucketList 
            = buckets.getBuckets(); // GET .../ -> 200 application/buckets+xml
        out.println("<Bucket List After Delete>");
        if (bucketList.getListAsResources()!=null)
        {
            for (Bucket next : bucketList.getListAsResources()) {
                out.println("   " + next);
            }
        }
        out.println("</Bucket List After Delete>");
        
    }
}

The getListAsResource(..) method as you might have noticed is not part of the BucketList interface and would be generated based on the @MappedResource annotation. How this this would happen I am not entirely sure; but you can start to see the start of a HATEOAS enabled client. Basically you can access the next resource along without any further work. You can imagine a "Transfer" bean that exposed the resources for the "Bank" at each end of the transfer. The client can deal with wiring this all up for you.

So the output of the run looks like this, note that all the Is-A object are dynamic proxies of the resource.

Using proxy Is-A:bucketservice.Buckets@[uri=http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/buckets]
<Contents of buckets>
Is-A:bucketservice.Bucket@[uri=http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/buckets/2]First # First Bucket
Is-A:bucketservice.Bucket@[uri=http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/buckets/3]# Second Bucket
</Contents of buckets>
<Bucket List>
   Is-A:bucketservice.Bucket@[uri=http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/buckets/2]
   Is-A:bucketservice.Bucket@[uri=http://localhost:7101/RSProxyClient-BucketService-context-root/jersey/buckets/3]
</Bucket List>
<Bucket List After Delete>
</Bucket List After Delete>

I hope you can see by example how easy it is to convert a URI into a strongly typed interface.

   URI bucket = ....
   Bucket bucketIF = of(client.resource(bucket), Bucket.class);

Ideally the interfaces would be generated from a sub set of a WADL, you would want to be able to filter by content-type and resource path. Again this kind of focused generation would have been much harder with JAX-WS / WSDL.

The code for this is still on my laptop, except for the code generation, and unfortunately it is not something I can distribute at the moment. This is something I am going to look into if people find this approach interesting.

Tuesday, September 15, 2009

Wssp1.2-2007-Https-ClientCertReq.xml required further configuration

Just a quick post to note a problem I found with the above mentioned security policy. This policy should enabled mutual or two-way https; but you will find that if you deploy this service to what appears to be a properly configured service that it will fail:

@WebService
@Policy(uri="policy:Wssp1.2-2007-Https-ClientCertReq.xml")
public class HelloTwoWay {
   public String sayHello(String name)
   {
      return "Hello " + name;
   }
}

You need another step compared with other https policies to have this work. You need to go to Servers -> [ServerName] -> SSL -> Advanced and under "Two Way Cert Behaviour" you need at least "Client Certs Requested". You can go for the enforced option if you want to use mutual everywhere; but in that case you can use the more general https policies so it doesn't really make sense.

Thursday, September 10, 2009

A programatic implementation of dump stack trace

When you program hangs you can always ask the user to perform a dump stack trace; jstack or run visual vm; but when you are trying to run automated UI tests there isn't a user on hand so you need a programmatic solution. Now you can do something with Threads and ThreadGroup classes; but you can get a much better dump of current thread state using management beans. This sound complicated right, well it turns out that there are nice static methods to get hold of those beans for the current VM.

Here is a simple example using a JFrame to give some interest to the output:

package management;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import javax.swing.JFrame;


public class DumpStackTrace {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setVisible(true);

        new DumpStackTrace().dumpStack();
        
        System.exit(0);
    }
    
    public synchronized void  dumpStack() {
        
        ThreadMXBean theadMxBean = ManagementFactory.getThreadMXBean();
        
        for (ThreadInfo ti : theadMxBean.dumpAllThreads(true, true)) {
            System.out.print(ti.toString());
        }
    }
}

This is the output on the console, note in this form you can even see the result of the synchronized on the dumpStack method.

"AWT-EventQueue-0" Id=14 RUNNABLE (in native)
 at sun.awt.windows.WComponentPeer._requestFocus(Native Method)
 at sun.awt.windows.WComponentPeer.requestFocus(WComponentPeer.java:586)
 at java.awt.Component.requestFocusHelper(Component.java:7260)
 at java.awt.Component.requestFocusInWindow(Component.java:7151)
 at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:361)
 at java.awt.Component.dispatchEventImpl(Component.java:4373)
 at java.awt.Container.dispatchEventImpl(Container.java:2081)
 at java.awt.Window.dispatchEventImpl(Window.java:2458)
 ...

"AWT-Windows" Id=10 RUNNABLE
 at java.awt.KeyboardFocusManager.shouldNativelyFocusHeavyweight(KeyboardFocusManager.java:2386)
 -  locked java.util.LinkedList@ff057f
 at sun.awt.windows.WToolkit.eventLoop(Native Method)
 at sun.awt.windows.WToolkit.run(WToolkit.java:291)
 at java.lang.Thread.run(Thread.java:619)

"AWT-Shutdown" Id=11 WAITING on java.lang.Object@b8deef
 at java.lang.Object.wait(Native Method)
 -  waiting on java.lang.Object@b8deef
 at java.lang.Object.wait(Object.java:485)
 at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:259)
 at java.lang.Thread.run(Thread.java:619)

"Java2D Disposer" Id=9 WAITING on java.lang.ref.ReferenceQueue$Lock@1342ba4
 at java.lang.Object.wait(Native Method)
 -  waiting on java.lang.ref.ReferenceQueue$Lock@1342ba4
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
 at sun.java2d.Disposer.run(Disposer.java:125)
 at java.lang.Thread.run(Thread.java:619)

"Attach Listener" Id=5 RUNNABLE

"Signal Dispatcher" Id=4 RUNNABLE

"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@10a6ae2
 at java.lang.Object.wait(Native Method)
 -  waiting on java.lang.ref.ReferenceQueue$Lock@10a6ae2
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
 at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@ef2c60
 at java.lang.Object.wait(Native Method)
 -  waiting on java.lang.ref.Reference$Lock@ef2c60
 at java.lang.Object.wait(Object.java:485)
 at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)

"main" Id=1 RUNNABLE
 at sun.management.ThreadImpl.dumpThreads0(Native Method)
 at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:374)
 at management.DumpStackTrace.dumpStack(DumpStackTrace.java:26)
 -  locked management.DumpStackTrace@4a6cbf
 at management.DumpStackTrace.main(DumpStackTrace.java:17)

Simple and works a treat, just merging this code into our abbot runner.

Update 27 Jan 2011: One of the annoying problems with this solution is that it only prints out the first 8 items of the stack trace which might not be enough, turns out it is easy enough to trace out the rest

package management;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import javax.swing.JFrame;


public class DumpStackTrace {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setVisible(true);

        new DumpStackTrace().dumpStack(System.out);
        
        System.exit(0);
    }
    
    public synchronized void  dumpStack(PrintStream ps) {
        
        ThreadMXBean theadMxBean = ManagementFactory.getThreadMXBean();
        
        for (ThreadInfo ti : theadMxBean.dumpAllThreads(true, true)) {
            System.out.print(ti.toString());

           // ThreadInfo only prints out the first 8 lines, so make sure
           // we write out the rest
           StackTraceElement ste[] = ti.getStackTrace();
           if (ste.length > 8)
           {
             ps.println("[Extra stack]");
             for (int element = 8; element < ste.length; element++)
             {
                ps.println("\tat " + ste[element]);
                for (MonitorInfo mi : ti.getLockedMonitors()) {
                   if (mi.getLockedStackDepth() == element) {
                       ps.append("\t-  locked " + mi);
                       ps.append('\n');
                   }
                }
             }
             ps.println("[Extra stack]");
           }
        }
    }
}

Validating annotations at compile time, example using JAX-RS

I am in the process of re-reading Effective Java now that I have gotten around to buying the second edition. I always enjoy reading anything that Bloch puts out and I always learn something new. I was working my way through item 35 "Prefer Annotations to Naming conventions" when I noticed the following statemen that was talking about validating the annotations:

"... It would be nice if the compiler could enforce this restriction, but it can't. There are limits to how much error checking the compiler can do...."

Now it is normally very hard find something that you think that Mr Bloch has got wrong, and also be right; but I think this validation is very possible. Recently I have been looking at Project Lombok which does interesting things with the annotation processor. The general idea behind the annotation processors is that they give the ability to generate new code; but it occurred to me that an annotation processor can just check source files for errors. This allows you to extend the java compiler to do interesting non trivial annotation validation.

Rather than deal with the simple @Test example in the book, I have a solution for that one if anybody in interested, lets instead look at a real world examples from JAX-RS web services:

package restannotationtotest;

import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;

public class ExampleResource {

    @GET
    public String goodGetNoParam() {
        return "Hello";
    }

    @GET
    public String goodGetParam(@QueryParam("name")String name) {
        return "Hello " + name;
    }
    
    // This annotation will fail at deploy time    
    @GET
    public String badGet(String name) {
        return "Hello " + name;
    }
}

The last method will fail at deploy time as a HTTP GET request cannot have a method body as implied by having a method parameter that is not otherwise consumed by the framework. This is a mistake I kept on making when I started with Jersey so I though it was worth starting with. So our first goal is to flag this last method up at compile time as being in error.

In order for an annotation processor to work you need a jar file with an entry in the META-INF/services path called javax.annotation.processing.Processor. This contain a list of fully qualified processor class names in plain text. In some tools you might find that the javax.annotation.processing.Processor file is not copied to the classpath as you need to add ".Processor" to the list of file extensions copied at compile time. You also of course need a class that implements the Processor interface so my project looks like this:

First of all lets look at the basic house keeping parts of the JaxRSValidator class without worry about the meat of the class. We extend the AbstractProcessor rather than implementing the Processor interface both to gain some basic functionality and to future proof the code against interface evolution. We could have used the @SupportedAnnotationTypes annotation rather than implement the corresponding method; but for later it was handy to have a list of class literals. As you can see there is not much to the configuration:

package com.kingsfleet.rs;


import java.lang.annotation.Annotation;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedSourceVersion;

import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner6;
import javax.lang.model.util.Types;

import javax.tools.Diagnostic;

import javax.ws.rs.CookieParam;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;


@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class JaxRSValidator extends AbstractProcessor {

    private static final List<Class<? extends Annotation>> PARAMETER_ANNOTATIONS
                     = Arrays.asList(
                           CookieParam.class,
                           FormParam.class,
                           HeaderParam.class,
                           MatrixParam.class,
                           PathParam.class,
                           QueryParam.class, 
                           Context.class,
                           Resource.class);
     
    private static final List<Class<? extends Annotation>> METHOD_ANNOTATIONS
                    = Arrays.asList(
                          GET.class,
                          POST.class,
                          PUT.class,
                          DELETE.class,
                          HEAD.class,
                          OPTIONS.class);

    private static final Set<String> MATCHING_ANNOTATIONS_AS_STRING;
    static {
        Set<String> set = new HashSet<String>();
        for (Class a : METHOD_ANNOTATIONS) {
            set.add(a.getName());
        }
        // We care about path as well
        //
        set.add(Path.class.getName());
        //
        MATCHING_ANNOTATIONS_AS_STRING = Collections.unmodifiableSet(
                                           set);
    }


    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return MATCHING_ANNOTATIONS_AS_STRING;
    }

  
    // Implementation of processor
    //

}

The actual implementation of the processor is in the process method, you will notice that for most annotation processors all the work is done using a visitor or the concrete scanner implementations.

The scanner we have implemented looks for an ExecutableElement that is of type "Method". The javax.lang.model is a little bit obscure in its terminology so it did take me a little bit of time to work out that this is the correct structure. Another limitation is that you cannot drill down into the finer details of the code structure without casting this a class from com.sun.tools.javac.code.Symbol: with attendant maintenance issues of using a com.sun.* package. Fortunately for the validation I want to do I can stick with the public APIs. Hopefully a future version of Java will expand on this API.

It is a relatively simple matter after that to process each method in turn looking for a one with the @GET annotation that would suggest a message body of some kind.

    private static ElementScanner6<Void, ProcessingEnvironment> SCANNER =
        new ElementScanner6<Void, ProcessingEnvironment>() {
        @Override
        public Void visitExecutable(ExecutableElement e,
                                    ProcessingEnvironment processingEnv) {

            final Messager log = processingEnv.getMessager();
            final Types types = processingEnv.getTypeUtils();

            // Make sure for a GET all parameters are mapped to
            // to something sensible
            //

            if (e.getKind() == ElementKind.METHOD) {
                
                // GET no body
                verifyNoBodyForGET(e, log);
            }
            return null;
        }


        /**
         * Check that if we have a GET we should have no body. (Should
         *   also process OPTIONS and others)
         */
        private void verifyNoBodyForGET(ExecutableElement e,
                                        final Messager log) {
            if (e.getAnnotation(GET.class) != null) {
                
                // For each parameter check for the standard annotations
                found : for (VariableElement ve : e.getParameters()) {
                    for (Class<? extends Annotation> c : PARAMETER_ANNOTATIONS) {
                        if (ve.getAnnotation(c)!=null) {
                            break found;
                        }
                    }
                    
                    log.printMessage(Diagnostic.Kind.ERROR, 
                                     "Parameters on a @GET cannot be mapped to a request body, try one of the @*Param annotations",
                                     e);
                }
            }
        }
    };

    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {

        for (TypeElement annotation : annotations) {
            for (Element e : roundEnv.getElementsAnnotatedWith(annotation)) {
                SCANNER.scan(e, processingEnv);
            }
        }

        // Allow other processors in
        return false;
    }

It is important when you use the log.printMessage(...) method to include the Element as the final parameter as this allows tooling to correctly display the error/warning message location. So it is a simple matter to build this project into a jar file using the tool of your choice and then have it on the the classpath when you build ExampleResource that we defined earlier. (JDeveloper users note my previous post on Lombok on running javac "Out of Process" to get this working). Depending on your tool you should get an error message that looks something like this:

Lets look at a more complicated example from Jersey to build on our code. In this example we need the parameters in the @Path annotation to match @PathParam parameters on the matching method. In this case here are two that are fine and two that might fail at some point later on. Neither of the problems can be picked up by the compiler.

package restannotationtotest;

import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

public class PathResource {
    
    // Fine
    @Path("{param}")
    public ExampleResource getOneParam(@PathParam("param") String param) {
        return null;
    }

    // Fine
    @Path("{param}/someotherText/{param1}")
    public ExampleResource getOneParam(@PathParam("param") String param, @PathParam("param1") String param1) {
        return null;
    }

    // Suspect
    @Path("{param}")
    public ExampleResource getUnusedParam() {
        return null;
    }
    
    // Definitely broken
    @Path("{param}")
    public ExampleResource getMissMatch(@PathParam("paramMissMatch") String param) {
        return null;
    }
}

Our original code already visits all the methods so we need to simply extend the code to check that the parameters match entries on the @Path. We can also check for a zero length @PathParam argument which again is something that compiler can't do for free.

    private static ElementScanner6<Void, ProcessingEnvironment> SCANNER =
        new ElementScanner6<Void, ProcessingEnvironment>() {
        @Override
        public Void visitExecutable(ExecutableElement e,
                                    ProcessingEnvironment processingEnv) {

            final Messager log = processingEnv.getMessager();
            final Types types = processingEnv.getTypeUtils();

            // Make sure for a GET all parameters are mapped to
            // to something sensible
            //

            if (e.getKind() == ElementKind.METHOD) {
                
                // GET no body
                verifyNoBodyForGET(e, log);
                
                // Try to match path param to @Path
                verifyPathParamMatches(e, log);
            }
            return null;
        }

        /**
         * Check that if we have path param we have all the matching
         * path elements consumed.
         */
        private void verifyPathParamMatches(ExecutableElement e,
                                            final Messager log) {
            
            // Verify that we have a method that has resource
            //
            
            Path p = e.getAnnotation(Path.class);
            if (p!=null && p.value()!=null) {
                
                // Hack the resources out of the string, verify
                // path parameters, TODO write regex
                //
                List<String> resources = new ArrayList<String>();
                String path = p.value();
                final String[] splitByOpen = path.split("\\{");
                for (String bit : splitByOpen) {
                    String moreBits[] = bit.split("}");
                    if (moreBits.length >= 1 && moreBits[0].length() !=0) {
                        resources.add(moreBits[0]);
                    }
                }
                
                // If we have resource try to find path params to match
                if (resources.size() > 0) {
                    found : for (VariableElement ve : e.getParameters()) {

                        PathParam pp = ve.getAnnotation(PathParam.class);
                        String mappedPath = pp.value();
                        if (mappedPath==null || mappedPath.length()==0) {
                            log.printMessage(Diagnostic.Kind.ERROR, 
                                             "Missing or empty value",
                                             ve);
                        }
                        else if (!resources.contains(mappedPath)) {
                            log.printMessage(Diagnostic.Kind.WARNING, 
                                             "Value " + mappedPath + " doesn't map to path",
                                             ve);
                        }
                        else {
                            // Make this as processed
                            resources.remove(mappedPath);
                        }
                    }
                    
                    if (resources.size() > 0) {
                        log.printMessage(Diagnostic.Kind.WARNING, 
                                         "Unmapped path parameters " + resources.toString(),
                                         e);
                    }
                }
            }
        }

        /**
         * Check that if we have a GET we should have no body. (Should
         *   also process OPTIONS and others)
         */
        private void verifyNoBodyForGET(ExecutableElement e,
                                        final Messager log) {
            ...
        }
    };

Again you can simple compile the project with ExampleResource and PathResources using your favorite build tool and you should see something like:

Note the second method gets two warnings, the line numbers are the same.

So this contrary to the original statement it is possible to get the compilers to perform quite complex validation of annotations. I wonder if we could convince some of the annotation based JEE projects and libraries to come with a validation jar file that contains a matching processor to validate against the spec. It would save a lot of confusion. Tools developers like myself would also be able to harness the same code in code editors to provide in line error feedback in a consistent way. Interesting stuff.

Friday, September 4, 2009

Project lombok, interesting bean shortcuts with the annotation processor

I came across a mention of project lombok recently whilst looking for something else. It is a combination of annotations and annotation processors to make bean programming more declarative. For the purposes of this blog I am going to use a quick example using the @Data annotation. So for this simple class the attention of the @Data annotation will at compile time add in getters/settings equals/hashCode and a nice toString implementation.


import lombok.Data;

@Data
public class DataExample {
  
  
   private String name;
   private double score;
   private String tags[];
  
}

Now lombok has integration with Eclipse and javac, since we are using JDeveloper I am stuck with the latter. In theory all you need to do is to make sure that JDeveloper compiles with "javac" with the lombok.jar on your classpath. It turns out that at least in the more recent versions of JDeveloper we use the compiler API directly which doesn't appear to properly invoke the annotation processors in the library. (Look under lombok.jar!/META-INF/services to see how this is wired up) The trick is to configure JDeveloper to run javac "out of process":

Now before you compile JDeveloper might complain that it can't find any of the new methods; but as soon as the classpath is populated even code insight works correctly (although not inside of the DataElement class):

Using the above data you can see how the toString() method is puts together some nice tidy output:

DataExample(name=Bob, score=4.0, tags=[Fun, Tall])

I wonder if the ADF team could use something similar to reduce the amount of boilerplate code that they have to generate. Also with a little bit of work you could get far cleaner JAXB and EJB artifacts. It would also be good if this project was extended to support bound attributes transparently and perhaps create a builder which always takes far too much time in my book.

Friday, August 21, 2009

THC, and a bit of Thunking. (Creative ways to deal with multiple return types)

Often is the case that you really do want a method to return multiple values as different client require different parts back. This is often simpler than creating multiple methods; but it might not be worth creating a bean class for. For simple two value return types you can use a nice generic version of Pair; but things get harder if you have more value. (You can use a holder class to simulate IN/OUT parameters, but it doesn't result in pretty code) I was working on a method that needed to return four values depending on the calling context so I turned to a type safe heterogeneous container from the Effective java book:

/**
 * An implementation of a type safe heterogeneous container, taken from
 * effective java
 */
public class THC
{
   final private Map<Class<?>, Object> container = new HashMap<Class<?>, Object>();
   
   public <T> void put(Class<T> key, T value)
   {
      if (key==null) throw new NullPointerException("Key cannot be null");
      container.put(key, value);
   }
   
   
   public <T> T get(Class<T> key)
   {
      // Return the value of think the thunk if required
      //
      Object object = container.get(key);
      return key.cast(object);
   }
}

It doesn't provide full compile time safety; but it is close enough for our purposes. You can write code that looks like:


   THC thc = getSSLConfiguration(...);
   SSLContext sslContext = thc.get(SSLContext.class);
 
   // or in another case

   KeyManager kms[] = thc.get(KeyManager[].class);
   TrustManager tms[] = thc.get(TrustManager[].class);


So this is fine, except as you see from the example above that depending on the context I need different subset of the objects. Some are derived from others so I could end up doing extra work to populate a part of the return value that is never used.

I decided to look at using a Thunk as a way to optimize the work done on the return value of this method. So I modified the THC class to include a new public interface Thunk with one method that takes a reference to the original container.

/**
 * An implementation of a type safe heterogeneous container, taken from
 * effective java
 */
public class THC
{
   /**
    * Allow the client to provide a derived value
    * @param <T>
    */
   public interface Thunk<T>
   {
      public T get(THC that);
   }

   /**
    * Place a value in the structure that has yet to be derived.
    * @param key
    * @param value The value to be thought of in the future
    */
   public <T> void put(Class<T> key, Thunk<T> value)
   {
      if (key==null) throw new NullPointerException("Key cannot be null");
      container.put(key, value);
   }
   
   public <T> T get(Class<T> key)
   {
      // Return the value of thinking the thunk if required
      //
      Object object = container.get(key);
      if (object instanceof Thunk)
      {
         object = ((Thunk)object).get(this);
         container.put(key, object);
      }

      return key.cast(object);
   }

}

You find that because Thunk takes a parameter of the THC the adapter classes can be constants, this saves a little bit on object creation. So I can write something like:



  static final private Thunk<SSLContext> contextT = new Thunk<SSLContext>()
  {
     public SSLContext get(THC that)
     {
        SSLContext c = SSLContext.getInstance("SSL");
        c.init(that.get(KeyManager[].class)
               that.get(TrustManager[].class), null);
        return c;
     }
  }

  static final private Thunk<SSLSocketFactory> factoryT = new Thunk<SSLSocketFactory>()
  {
     public SSLSocketFactory get(THC that)
     {
        return that.get(SSLSocketFactory.class).getSSLSocketFactory();
     }
  }

  public THC getSSLConfiguration(...)
  {
     ...

     THC thc = new THC();
     thc.put(KeyManager[].class, kms);
     thc.put(TrustManager[].class, tms);
     thc.put(SSLContext.class, contextT);
     thc.put(SSLSocketFactory.class, factoryT);
  }

So I can now write my client code as follows and the SSLContext and SSLSocketFactory are created on demand:

   THC context = getSSLConfiguration(...);
   SSLSocketFactory sf = context.get(SSLSocketFactory.class);

Perhaps not a technique that is applicable to all situations; but interesting all the same.

Update: Some time later it occurred that the THC interface if of course not particularly pretty, so an obvious extension is to have THC return a Proxy based on a interface that can be used to define the return types. Not written this yet; but it would be pretty trivial to do.

Wednesday, August 19, 2009

Favourite minor JDeveloper feature, auto highlighting

Following on from Chris' post auto highlight is my favorite minor feature. Just highlights all instances of whatever the cursor is on. Has been available in previous version of jdev as an extension so not that much woo-hoo.

WssConfiguration and JAX-WS

In weblogic you can have multiple security configurations for web services but in 10.3 JAX-WS could only make use of the "default_wss" configuration. There was an annotation to control this; but it only worked for JAX-RPC service. But in 10.3.1, aka AS11R1, it now works for JAX-WS as well. And for completeness here is an example on a JAX-WS service.

Monday, August 10, 2009

Reminder edocs.bea.com -> OTN migration

Just a quick reminder that on the 31st of August edocs.bea.com will be turned off; but the good news is that all of the documentation has moved to the current bea page on document section on otn. Specifically Weblogic Server 10.3 and Weblogic Server 10.3.1 that is part of AS11R1. Guess we need to get used to a new page layout!

Tuesday, August 4, 2009

New default password for the integrated weblogic server in JDeveloper R1

I guess it must be hidden in the help somewhere but it is not 100% clear that the default password for the integrated copy of weblogic server that comes with JDeveloper changed for R1. Rather than weblogic/weblogic it is now weblogic/weblogic1. Not a big change but enough to cause problems for some users.

Monday, August 3, 2009

Problem running Jersey on the Integrated Server in JDeveloper on windows

Prior to the latest 1.1.2EA builds you will find that if you deploy Jersey to the integrated weblogic server in JDeveloper on window that you might see a deployment issue due to the fact that the weblogic domain will have a space in its filename. (Think c:\Document and Settings\%USER_NAME%\Application Data\)

This is logged as oracle bug 8752995, this is fixed in the latest builds but there is a workaround and that is to edit ..jdevevloper/jdev/bin/jdev.boot and change the following entry to a path without spaces in it.

ide.user.dir = D:/MyJdev/LocalSettings

Note without the NLS fix in the previous blog entry deployment will fail with a stack trace that looks like this:

com.sun.jersey.api.container.ContainerException: [failed to localize] no.root.res.in.res.cfg()
        at com.sun.jersey.server.impl.application.WebApplicationImpl.processRootResources(WebApplicationImpl.java:718)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:590)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:383)
        at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:377)
        at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:242)

Useful localization fix in Jersey Achive 1.1.2EA

There was a problem in the 1.1.X series of Jersey builds in that error messages were not localized properly. This has been fixed in the latest 1.1.2EA build so it is well worth downloading this very as it is much easier to diagnose failures.

Monday, July 20, 2009

Applying a template to the domain used for the Integrated WebLogic Server

JDeveloper provides you with pre-build install of weblogic and a bunch of useful templates for JRF etc. There are time though when you really need to apply a new template. (For example if you are doing Async web services).

This isn't a problem on windows as the domain is easy to find, $USER_HOME/Application Data/JDeveloper/system.X.X.X.X/DefaultDomain, but on Unix the location is under a "dot" directory, ~/.jdeveloper/system.X.X.X.X/DefaultDomain. This causes a problem for the graphical domain configuration wizard because it wont let you pick a domain that lives in a hidden directory. It also doesn't have a box where you can just type your path which is annoying.

The most obvious workaround is to use the configuration wizard in text only mode which gives you an old fashioned but workable UI. In this interface you can just type the path of the system directory when it asks you where your domains live. Don't fall into the trap I did of giving it the full location of the DefaultDomain, it will prompt you for this on the next page.

If you prefer you can also use wlst for the same work. Just issue a readDomain, then an addTemplate, updateDomain, then a final closeDomain.

Friday, July 17, 2009

Jersey, your code, might be vulnerable to XXE attack

XXE is an interesting security hole where you use entity expansion in an XML document. Take for example the following xml file:

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<search><user>&xxe;</user></search>

You might get the following response from a jersey service depending on how your XML parser in configured:

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<search><response>User root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
...
not found</reponse></search>

There is a bunch of stuff in this thread on how to disable this expansion by default. This is fixed in the latest builds of Jersey 1.1.1ea so it is recommended that you upgrade. This does reproduce when running Jersey on weblogic so this is of interest. (Doesn't affect the JAX-WS stack)

Of course it is possible that any general xml parsing code you have might be vulnerable so it is worth understanding the problem so you can prevent it from happening in your application.

Friday, July 3, 2009

Java Development on the iPhone

Seems that Apple aside people are starting to find way to get java applications to run on the iPhone from the cheap and cheerful to the rather more high end products from people like Metismo. (Nice chaps, met them at JavaOne; but licenses were 10ks UKP but not for people just playing).

Perhaps I just need to bite the bullet and learn Objective-C...

Wednesday, July 1, 2009

JDeveloper 11 R1, now up on OTN

A brand spanking new version of JDeveloper to go along with the other R1 components released today. Lots of new features to play with in various components along with a whole bunch of bug fixes.

Tuesday, June 16, 2009

WS-SecurityPolicy Examples

Normally I wouldn't want to write and say that an OASIS spec makes an interesting read; but WS-SecurityPolicy Examples is interesting in that is annotates both common policy files and example messages. Could do with a little bit more fleshing out in the SAML section.

Monday, June 15, 2009

Jersey and OAuth documentation

Quick follow up from JavaOne, there is now some documentation on using Jersery with OAuth.

Friday, June 12, 2009

JavaOne 2009, day three

The keynote on the thursday morning was from Microsoft, some of it was fairly content free but the interoperability stuff was interesting. There have a special lab that work on interoperability that works with a range of technologies. It is refreshing to see the amount of work that has gone into this after years of apparently making things harder than necessary for developers. Probably it is just a matter of the software development world growing up and will hopefully be the trend for the future.

From the web services point of view the most interesting presentation of the day was concerning the Stonehenge project hosted on Apache. This looked at a modularized business application where component from either .NET or JEE can be swapped in and out at will. Interesting example of how WS-* standard are maturing and the good work Sun and MS have done in this area.

There were two numbers that were of interest in this presentation. The first is 73% which is the number of developer who use .NET as part of there day to day work. (Pretty sure this must include anybody who uses IE for example; but it was made clear) The second is 41, the poor chap from Microsoft unfortunately got the meaning to life the universe any everything quite wrong. :-)

TS-4402 Metro Web Services Security Usage Scenarios

Conveniently in the same room as I as presenting in Harold Carr who is the lead for all things web services in Sun. He had some really nice slides explain the details of WS-Security in various combination which are well worth a look. Netbeans was used to show the basic security profiles, looks like it makes it much easier to get started and pick a relevant technology combination. There is a lot we can learn from how Netbeans deals with security.

TS-4993 Dealing with Asynchrony n Java Technology Based Web Services

This appeared to go over okay, really quite happy with the numbers. (We think around 300-400 which was good given the overall numbers from last year). I guess time and review forms will tell if the crowd liked it. Had Lucas Jellema in the front row taking pictures now and then which made the occasion just that little bit more relaxed.

Got a good question about Async and REST, gave me a lot to ponder as I got lost on the way back from my afternoon meetings.

Lunch / afternoon meeting / after dark

Had a nice lunch with Manoj my co presenter, Lucas and Wouter who works with Lucas. Then I had a meeting with the weblogic web service team who happen to work in down town SF so I got to go topside for a few hours.

It was nice to put some faces to people, hey Thorick say hi to everybody for me, and then have a very civilized afternoon tea with bone china cups and cucumber sandwiches that is a tradition in that office. (Feels like home) I did then make a tactical mistake on the walk back to my hotel; glad I 'discovered' Broad Street in the sun rather than at night.

By the time I had managed to get back to the hotel, I had just enough time to pick up a nice big glass of wine at the after dark bash along with some food before my planned evening sessions. I would have enjoyed the after dark party better if it had been outside; but apparently there was as chance of rain..... oh well. Also it would be nice if the party continued until an hour *after* the presentation finished to give more time for socializing... oh well.

BOF-4903 A RESTful approach to Identity-Based Web Services

Didn't really get a lot from this, it might have been just the long walk; but I didn't really jell with what the presenters were saying. Some mention of ID-WSF was made.

BOF-5376 Building Consistent RESTful APIs in a High Performance Environment

This was a really interesting presentation from the developers behind the LinkedIn RESTful API. They have to scale so they have been thinking a lot about how things fit together. They described the tension between Variety, the ability to get just what you want, and Uniformity which is different APIs return a consistent model.

In order to ensure Uniformity they talked about the importance of a consistent data model. A old concept but something that people seem to have forgotten in the rush to REST. To deal with the Variety issue that made an interesting use of matrix URIs to allow clients to only get the information back they want:

Basic data model is:

/people
  /id
  /name
  /email
  /photo
  /best-friend
  /friends (People[])
  /jobs (Jobs[])
/companies

Return the basic record for user 123, probably too much information for most cases

.../people/123

Return just the name and photo for user 123

.../people/123:(name,photo)

Return the friends for user 123 with there names and the names and pictures of there best friends

.../people/123/friends:(name,photo,best-friends:(name,photo))

Return the friends for user 123 with there sorted by name

.../people/123/friends;sort=name:(name,photo)


The cool thing about these is that they appear in the HTTP log so it is easy to see which is getting hit the most and optimize for that case. In one case study they reduced traffic to a partner by 28% which I guess all adds up. I guess you need be more relaxed about how your schemas are designed if using XML. Less of a problem if you are using JSON. I wonder how hard this would be to do in Jersey.....

Roy Fielding's Untangled blog

Came up a few times at JavaOne, makes an interesting read.

Thursday, June 11, 2009

JavaOne 2009, day two

So day two started with a general mobility technical session which I am afraid I didn't stick around for very long in. It did appear to introduce a new word "Trendencies"; but still nothing being demoed really caught my eye. JavaFX for mobile is interesting I guess; but still iPhone appears to have a better experience. (Not that I actually own one of the beasties.)

Back to the speakers lounge then for presentation prep and catching up on emails.... until the real fun of the day begins.

TS-4641 State: You're doing it Wrong - Alternative Concurrency Paradigms on the JVM

I have to say that in general I was really impressed with this presentation although I was slightly disappointed that all of the examples given were in languages such as Clojure and Scala. He did make some convincing arguments though at in some particular cases you can on deal with this problem with language support and that with the VM you can ring fence that code.

The basic problem is that in order to deal with multi-core processors you need some way of dealing with shared state There are some helper classes in the VM with the addition of locks and queue; but that the basic model of synchronization is hard to use and maintain. Most people make mistakes at one time or another.

He first covered share transactional memory using Clojure, (more on Clojure state managment here.). Showed some pretty powerful examples, I would recommend you download the presentation when posted on the JavaOne site in a few weeks. It was one of those dense presentations where if you took notes you missed something important or interesting.

Then we went onto the Actor model. which is better for co-ordination applications. The examples where in Scala; but the classic implementation of this is in Erlang. Interesting case study of Ericson using this model to achieve 31ms of down time a year in there ATM switches.

The final topic covered was Data Flow Concurrency using either Oz or a library knocked together library based on Scala that the presenter has put together. The intriguing thing about this model is that the model is deterministic. It will either always deadlock or never deadlock, which makes testing so much easier.

Again very dense; but the slides were very detailed so well worth reading when they become available.

TS 5154 XTP: Patterns for Scalng the SOA, WOA and REST Predictably with Java Technology-Based Data Grid

Now this was actually by an oracle bod; but sometimes the easiest way to see these presentations live is at conferences. This was concerned with dealing with cases where you need to deal with high loads, XTP == eXtreme Transaction Processing.

Now in SOA you tend to end up passing a particular document through various steps via technologies such as ESB. Each hope can be expensive and XML is moved and serialized. You can't throw more hardware at this problem and at some point you need to changes how things are put together.

The suggestion is to use the Application Grid to store the information passed into the system and then pass a key into this share memory store around. You can also rely on asynchronous writes to the SQL database from the grid which means that you are never blocked in this way.

One other interesting use case is that use of caching in a data grid as described in the presentation can save a lot by reducing load on Mainframes. Maintenance contracts on old big iron is often related to load so reducing the amount of network accesses can result in cost savings. Interesting not only in this context.

You can find more on this topic in this article in SOA Journal.

Food at the Moscone

A brief interlude to talk about the lunches at Moscone: yuech. Now I have gotten that over with...

TS 5217 "Effective Java": Still Effective After All These Years

Josh is always a engaging speaker it is well worth going even if you have read the 2nd edition of the book. (For one reason of another I just got around to the updated version). I wont cover this too much as you should just read the book but it is worth mentioning the "PECS" mnemonic in Item 28 when coverings designing APIs.

PECS = Producer extends, consumer super

This is useful when you are trying to decided whether to use "super" or "extends" when defining generic parameters. It is slightly tricky because you are considering what the parameter to the method is doing not the method itself. For example:

public interface Stack<<E>
{

   public <E> pushAll(Set<? extends E> src); // src produces objects
   public void popInto(Collection<? super E> dst); // dst consumes items from the stack

}

There is an interesting corner case that the JDK doesn't deal with cases where the defined generic types are not directly related. You need to us an explicit type parameter which I have not come across before.


Set<Integer> ints = ....
Set<Double> doubles = ....
Set<Number> numbers = Set.union(ints,doubles);

// Wont compile, instead use an explicit type parameter

Set<Number> numbers = Set.<Number>union(ints,doubles);

Again just buy the book. :-)

TS-5295 Designing and Building Security into REST Applications

This was a presentation that didn't 100% match the abstract; but was interesting none the less. The first part focused on REST apis for administering OpenSSO instance and some fairly basic stuff about securing the web. The second part dealt with OAuth which I had to admit I had never heard of before; but was mentioned more than once over the time I was at JavaOne.

The most interested usecase of OAuth is for delegated access. So for example you your mashup site needs to access some resources from say Flikr.com. OAuth defines how your mashup site requests authorization and provided a set of HTTP headers that allow the site to access a particular defined resource. Useful if you want to share something for just a day for example.

They have recently checked in a bunch of Jersey filters to help implement OAuth on the client side. Nothing documented yet outside slide sets but you can peek at the source here.

TS-4883 Coding REST and SOAP Together

I was hoping that this presentation would give some insights on how to make a resource hierarchy into SOAP messages and vice vera. They didn't go into such details which is a shame as this topic would really be quite interesting. Probably I didn't read the abstract closely enough.

One point work mentioning is that if you take a class with both JAX-WS and JAX-RS annotation on it remember you have to secure it twice. Securing the service with WS-* won't protect the REST side.

More food

I was kinda obsessed by food that day having forgotten to eat yesterday so decided to skip out of the conference center for some food, I ended up at Lori's diner on Powell Street. Nice fresh air before diving back into dungeon.

BOF-5105 Hudson Commnity Meet-Up

The most interest part of this presentation was on a Hudson extension called drools. (Documentation to come) This allowed you to basically draw a process flow for you build system, including human step and splits joins etc, and deploy it to the hudson server. Look quite powerful to me. Hopefully there will be some more documentation on this soon so I can download and start playing.

There was also some demos of Netbeans integration. Being able to create a hudson job from a project was nice - also some monitoring tools.

There was one question about maintaining and building project branches; but the answer was to either clone jobs - which we do already or write your own extension.

BOF Test tools BOF

This was a little bit of a infomercial for PushToTest; but it did contain some interesting bits and bobs.

First of was the Windmill project as an alternative to Selenium. Appears to be moving faster and support authoring on more platforms. The second was they by using Rhino HTMLUnit is now able to run most of JQuery without even involving a web browser. Interesting from an automation point of view. Push to test have an open source script fixture that mashes up Selenium and HTMLUnit to this affect; but the life of me I couldn't find it on the website.

Friday, June 5, 2009

Async REST

I was asked today at the end of the presentation about what we thought an Async REST service would look like. At the time I was not sure; but after thinking about it the pattern is probably quite simple.

Consider an business making an insurance claim of some kind on behalf of an employee. So the client sends a POST message to the insurance resource as it want to create a new insurance claim. In the message it contains not only a reference to the resource for the employee but also a new sub resource for the employee that represents the claim. Since we are doing async the server response with 201 and with a URI to a resource to represent the insurance claim.

Time passes...

Eventually the server processing the work will POST its response back into the particular claim resource which we specified on invocation. In my example the message contains a reference to the insurance claim; but I suspect this is not required as would be implicit in the use of the resource on the client.

Now since the response is a POST as well it creates a new resource, in this case a claim response, which is returned to the server. In my experience insurance claims often take multiple goes so there could be multiple responses for a give claim. This would appear to complete the asynchronous message exchanges.

Does appear to make sense, mind you it is 00:30 at the moment so I will have to review in the morning, and all without the use of any WS-* standard.

Thursday, June 4, 2009

Logging with music , eh?

Sometimes it is the presentation you miss that sound interesting, take for example a presentation on JFugue and Log4Fugue. A Java API for making music and one for converting log messages into tunes.

Reminds me of the Anthem spread sheet in the first Dirk Gently book. (Bonus Geek fact this story started life as a Doctor Episode)

Wednesday, June 3, 2009

JavaOne Session write ups

Running a little bit behind on this, just too much to see and do it seems. I suppose I could just dump my notes directly; but it seems more polite to write them up properly so that they are some use to others.

Hopefully catch up on the flight home if I get a better seat on the plane... now on to "More Effective Java"....

JavaOne 2009, day one, part two

TS-3966 Using REST and WS-* Together for SOA

I really liked this presentation it appeared to give a balanced view of the topic and the presenter was clear. The key point to take home from this presentation is that both WS-*, SOAP web services, and REST services are valid implementations for SOA. Neither thought are ideal for all situations.

The key point of SOA from the point of view of this presentation the key point of SOA is to introduce loose coupling so you can change implementations on the fly. This is contrasted to RPC style services where even changing the number of parameters would require the service to be shutdown and all client modified.

On balance SOAP has all the enterprise features such as WS-TX and WS-RM; but REST, at least over HTTP, works better over the web. (Even simple stuff like allowing GET for caching) You can roll your own enterprise features on top of REST/HTTP but you pretty much end up with the complication seen in WS-*.

Is it interesting to understand that just at the moment we have a consistent WS interop story that the technical world want to drop all of this and start again. Having said that REST does work better over the net, you can cache values where required although I am not sure how this works in practice.

Interestingly if we had a SOAP 1.3 that had come control over HTTP methods then you could get many of the advantages of REST but with the consistent interop standard that SOAP gives you.

The presenters view was that the RESTvsSOAP debate was useful and instructive; but that going forward we should focus more fixing the problems with both rather than bickering. Which I kinda agree with.

The summary was that for cross web use REST/HTTP but for interop at the moment you will find that WS-* wins because of the number of add-hoc relationships you currently see in REST because of the lack of standard. Interesting point of view.

Tuesday afternoon technical session

I was a bit late as Lucas Jellema happen to pick the one of the hundreds of tables at lunch that I was sitting at. Very odd to hear the words ... "Do you know Gerard Davison". Might 2.5 seconds of fame I guess.

I had a good chat with Lucas even had some time to give him some quick previews of some features in JDeveloper. But pressed for time at that point; but was happy to bump into him and will hope to keep in touch.

Lots of stuff in JDK 7 in the presentation; but nothing particularly interesting. The one significant project was "Jigsaw" which reduces the JDK into much smaller modules. For example desktop profile made up of base; awt and swing. Really does cut down on the core download. Oh for the day we don't have to download the Corba support all those useless classes which pollute code insight.

There was the a little bit on EE6; but to be honest not anything new apart some new scheduling annotations in EJB 3.1 which are nice for timed events.

The one really interesting API is JSR 303 Bean Validation. This allows you to perform assertions such as string length etc. Using meta annotations you can define you only validators, this looks like a nice API for general use.

Then a little bit on profiles, in particular the web one. Then a really nice demo using net beans and glassfish. They think Sept'09 for the final version of EE6 along with a matching glassfish soon after.

The final demo was for there Open ESB demo app http://www.cluedin.org. Had some really nice web ui as part of project Fuji that allowed you to draw out a lot of the interaction flow. Looks very powerful.

TS-4629 Tips and Tricks for Ajax Push Applications

Pretty fun presentation; but the take home message is that you have to be really careful to architect you broadcast mechanism to deal with client that die of block. So if you need to broadcast to 30 browsers you need to consider how many thread you need to service this and perhaps us non-blocking NIO.2 to service these request. The other thing to consider is even consolidation, for example an application that updates x,y location and drop some intermediate event to improve performance.

Also to consider is conversation fragmentation in a cluster, but the solution to this was not covered in detail except that in most cases it is going to involve a JMS queue of some kind.

TS 4544 Introduction to CEP

Interesting stuff about monitoring real world information, this was in particular a demo of the Oracle implementation which was interesting. Runs on top of the RT version of the RocketVM because of the needs to continuously monitor events and correlate them as they arrive.

A good introduction to this topic; but I don't know enough to comment any further... Pretty cool fire service demo at the end showing real world information being integrated in real time.

TS 4213 Securing Web and Service Orientated Architectures with Apache Axis, WSS4J, Spring and OpenLDAP.

Now I have notes to prove I went to this presentation; but I think JetLag was hitting hard. I cannot make any sense of them at all. :-)

BOF-5493 Qup Vadis JavaFX Production Suite

Just a lot of work on making JavaFX very tool able. One thing of interest is the idea of a event bus so you can listen to common events and easily wire them up to actions. They have a special file format to encode designed artifacts, FXD/FXZ, that the designers can export from the normal design tooling such as creator.

Some things for the future would be a UI Contract that the designer can verify they are creating the correct objects and controls that the programmer has asked for. Also a binary format that better allows incremental load would be nice.

The tooling we demoed in several keynotes and was really quite impressive to my mind, I wonder how much it will cost.

BOF-3826 The Collections Connection

Started of with talking about collections is JDK the first thing we quite interesting in that they were proposing language changes to support array literal and look ups. Granted this is syntactic sugar; but something you should really expect from a modern language.

 

List<String> list = ["a", "b", "c"];
Map<Integer, String> map = {1: "One"}

// Or treat as arrays

print(list[0]);
map["1"] = "One";

Collections.sort in JDK 7 is much faster for lists that have some order and is much more efficient in it usage of memory. They we going to use the TimSort algorithm from Python.

They then went onto talk about Google collections which is nearly at 1.0; but not quite.

They have support for proper immutable lists rather than the Unmodifiable wrapper we currently have in Java. Written from the ground up to be faster as have less to worry about when compared to writable list. For example immutable set has a 2-3x smaller memory footprint when compared to the normal set. Also they provide builder methods to create literal immutable arrays which is nice. The suggestion is to always use immutable collection, never pass mutable ones which I kinda can agree with.

They have nice support for MultiSet and MultiMaps. Now original I wasn sure why you would need a MutliSet as it appeared to be the same as list. The main difference is that it has different rules for order equality. The MultiSet doesn't care about order to it is useful in some situations.

Really nice map builder interface to configure just the right amount of soft / weak keys in a map. Really useful for caches.

Take a look at the google collections project; but bare in mind some will make it into the JDK.

BOF-5009 Comet for Everyone, Everywhere

Nothing much new here that I haven't mentioned on the blog before, apart from the code snippet to launch a local version, kinda like Endpoint for JAX-WS:

// Like Endpoint.publish
SelectorThread st = GrizzlServerFactory.create("http://localhost:9999/");

They did mention the MessageTransformer class used to help prevent XSS hacks and injection bugs, they also talked a little bit about getting the broadcaster to be more efficient.

I did ask if you could get a broadcaster by name, and they said they would look into it.

And then with my brain thoroughly frazzled it was time to find some room service back at the code as it was after 10:30pm. (Right no it is actually Friday, time for me to catch a plane)

Tuesday, June 2, 2009

Larry Ellison makes an appearance on stage at JavaOne 2009 keynote

You can watch it live on the java one conference page. Or the recording later here, Larry is about 1:15 in or so.

JavaOne 2009, day one, part one

Morning keynote

So after a fitful nights sleeps I make it to the keynote which a little time to spare. The keynote room in 90 degree on from last year which give a good feel for the smaller numbers. Normally it would fill this massive underground room at Moscone, today it looks like only about 60% of it. Still the atmosphere is much better today, I guess that I could chalk up yesterday to the jet lag.

On minor niggle is that in previous year you always go an extra gift if you were either a speaker or a Alumni. (I am both) This year only paying Alumni get anything, which is a shame as I need a new jacket for Canoeing. Oh well as they say beggars can't be choosers.

From the stands at the pavilion last night you can guess there will be a lot about the cloud. I am not personally sure how this one will end up but from my experience there is at least a strong need for little fluffy clouds (lfc) within organizations. For example farms to build and test code using Hudson is something I have been involved with recently at work. Of course with the right infrastructure these should be transparently relocatable to big iron clouds on the internet. Just how much companies want to expose there system this way though is open for debate. For example I can't see many companies risking source code on the net just so they could make use of cloud services to build and test.

But I guess onto the keynote presentation, lovely DJ at the start which set the mood at start of the presentation.

The keynote did seem to start with an announcement that JDK 7 had been released, this was later corrected, but it did cause some confusion and lots of frantic web surfing in the crowd. This was correct in the afternoon keynote.

They did a bit on how ebay uses java. Billions of database transaction; but what was interesting is that they didn't explicitly say they used JEE technology. That could just be a typo though.

With a bit of a tease the next section was announced as the world most successful smart phone. I suspect that more than a few people in the crowd thought we were going to get Java on the iPhone; but it was of course RIM talking about blackberries. The demo was kind-of retro at least in the parts of the UI that were from blackberry. Didn't make me want to develop for that platform really no compared with the stuff that comes out from apple.

Moved on to consumer stuff, such as kindle. Demo of BluRay but appears more of a plug for Sony films rather than any specific for Java. Verizon then Intel followed and I was kinda loosing hope.....

Things go more interesting when they showed JavaFX running on a LG HD tv. Interesting that the java VM on the TV had lost of graphics acceleration so you can quite happily run java apps that overlay and embed HD video.

Nandini Ramani, no idea why I thought to note that down, came on stage to present on JavaFX tooling. Using web start which is interesting as sun really seems to bringing this back. Perhaps this relates to the Java Application store which makes a lots of use Some really nice feature to show FX for different displays at the same time. Lots of NeXT like screen guides for laying items out. Some nice visual wiring so you can connect say buttons to video assets. Looks like really nice tooling, works with the apple store. Annoyingly this tool wont be available until the end of the year would have been better if they said that at the start of the presentation.

The next segment focused on the new app store. They have been playing with the idea for some time; but the key is to make it easy for developer to convert there work into money without having to build out loads of infrastructure. I wonder if this will be linked with some kind of cloud offering to support the back end of applications.

Note there are two URL to look at http://store.java.com which is the public face and http://java.sun.com/warehouse which is the developer front end. Interesting in the public beta everything is free. They specifically want feedback on the money model which is kind-of interesting.

One final feature is that because underneath they are using web start you can preview apps without doing a full install. You can just "Preview" it in the app store which basically does a temporary download and install.

To highlight the different programming models they highlighted RuneScape which looked kinda fun. (Apparently in the Guinness book of records and the worlds most downloaded game or something) The game is free to play but they make money by converting users into paying subscribers. (They claim a 20% conversion rate which is pretty good)

Now on to some back patting and a video about the start of java etc. Talk about management is bravery etc, appeared to be focusing on old times. End of an era feel it to.... followed by the standard T-Shirt silliness.

The keynote ended with Larry Ellison coming on stage after some Oracle / Sun merger jokes. Not going to talk about this as we have been specifically asked not to comment on the merger. You can always watch the keynote on the javaone site as I previous noted.

Then up to the gardens above the Moscone center to do presentation prep... which took me to the end of the first morning.