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.