Monday, November 24, 2008

UKOUG'08 Presentation Schedule

So being a busy developer I wont get up to the conference until Wednesday morning and the train wont be there until 11ish; but then I have a pretty hectic schedule of presentations:

Wednesday 13:20-14:20 : How the Oracle JDeveloper team test JDeveloper. Co-presenting this with Geoff Waymark and will cover our usage of both Abbot and Selenium to test the "hard bits". I reckon this is the one mostly likely to have a big fat demo failure in it!

Thursday 10:45-11:30 : Integrating your J2EE Application with SOA. Only doing the demo here, a little bit of asynchronous web service consumption.

Thursday 11:55-12:40 : Who moved my Code? Team Development in JDeveloper. I am being the "Developer" in a demo, should be good as Susan is a lot of fun.

Thursday 17:30-18:15 : From developer to production, promoting your webservices. This presentation will look at how you take the different parts of a webservice application and move it from the developers machine to a production environment. Will cover policies and deployment plans.

Hopefully I will get to see some other talks, although I suspect that I might be busy in the speakers lounge putting the finishing touches to the last presentation.

Thursday, November 20, 2008

Insulting Error Messages?

I was noodling around with deployment plans in weblogic and wanted to just it was doing what I expected by making it fail. I was a little supprised when I saw this error message....

Until I remembered that I had change the URL for an outgoing web service to "http://idiot". The full text of the error message was java.net.UnknownHostException : idiot. But it did make me smile in this form.

Wednesday, November 19, 2008

Self Referential Error Dialog Title

Made us chukle, not that I can claim never to check in the odd typo:

Errant gam_server process on Linux

This isn't a problem necessarily with JDeveloper as such, but running JDeveloper makes this much more likely to happen because of the number of files it deals with. The "gam_server" which monitors file system changes can sometimes go, and I am sorry to use a technical term, "go mental" an eat up at nearly 100% of a CPU. (Luckily it is single threaded so it doesn't got to the dreaded 200%)

Turn out you can ask gam to be a little less aggressive by creating a .gaminrc file in your home directory. Mine looks like:

fsset nfs poll 10
fsset ext3 kernel

This tells gam_server to poll at 10 second intervals for nfs mounts but use the kernel for the main file system. This seems to help a lot on my machine as most of our source control system is via nfs mounts. I very rarely get the gam of death.

More information on this configuration file can be found here.

Friday, November 14, 2008

Invoke a Asychronous 10.1.3 BPEL service from JAX-WS

In JDeveloper the web service proxy wizard for JAX-WS will recognize when a service is asynchronous and offer to generate both the invoking proxy and a service implementation to deal with the response. The problems is that the proxy generator in JDeveloper assumes that version of WS-Addressing is going to be Final (2005) or Member Submission (2004) and that the headers are implicit. By default BPEL 10.1.3 uses the 2003 Draft version of WS-Addressing and has explicit headers. This means you are going to have to do a bit more work to make it work with JAX-WS.

This examples makes use of the AsyncBPELService that comes with the Oracle BPEL server. All it does is echo a loan request back to the user. The same steps would work with any other asynchronous example - AmericanLoan for example.

So if you already know the WSDL url use that. I cheated a little bit and created a WSIL connection in the "Resource Palette" to "http://xxxxx:8889/inspection.wsil" and navigated to the right BPEL service from there. Either way bring up the web service proxy wizard and accept all of the defaults.

An inviting client source file example will show first, but lets clean up the callback service before we do this. In this case it is "AsyncBPELServiceCallbackImpl.java". You of course need to put some code in there; but the println we generate by default is enough for this example. As I said before the WS-Addressing header is an explicit parameter so in the two methods that get generated you need to replace:

    // get the messageId to correlate this reply with the original request
    HeaderList headerList = (HeaderList)wsContext.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
    Header realtesToheader = headerList.get(WS_ADDR_VER.relatesToTag, true);
    String relatesToMessageId = realtesToheader.getStringContent();
    System.out.println("RelatesTo message id: " + relatesToMessageId);

With:

     System.out.println("RelatesTo message id: " + RelatesTo.getValue());

Right lets go back to the client class "AsyncBPELServicePortClient.java" and for a change lets do a JSE client for the service and publish and endpoint as the first thing we do in the main method:

    // publish the endpoint
    //
            
    Endpoint e = Endpoint.publish(
        "http://xxxx:7001/response",
        new AsyncBPELServiceCallbackImpl());  

Although not the most direct way for this example you can use the endpoint to create the WSEndpoint object directly, so you can make this minor fix. This is more useful in the normal '2005 and '2004 cases.

    WSEndpointReference replyTo =
        new WSEndpointReference("http://......", WS_ADDR_VER);

With:

    WSEndpointReference replyTo =
        new WSEndpointReference(e.getEndpointReference(), WS_ADDR_VER);

We then comment out the next block because it generates headers in the wrong WS-Addressing version, then we put in place the right code to invoke the service:

    // Add your code to call the desired methods.

    LoanApplicationType applicationType = new LoanApplicationType();
    applicationType.setCarModel("207");
    applicationType.setCarYear("1");
    applicationType.setCreditRating(2);
    applicationType.setCustomerName("Bob");
    applicationType.setEmail("bob@bobo.com");
    applicationType.setLoanAmount(1000d);
    applicationType.setSSN("143134-134-135--1345");

    // Set the reply to address to match that of the service
    //
    EndpointReferenceType replyToType = new EndpointReferenceType();
    AttributedURI replyToTypeURI = new AttributedURI();
    replyToTypeURI.setValue(replyTo.getAddress());
    replyToType.setAddress(replyToTypeURI);
    
    // Set the message id
    AttributedURI messageId = new AttributedURI();
    messageId.setValue(uuid);
    asyncBPELService.initiate(applicationType, replyToType, messageId);
    

And that is it really, the only thing to note is that you need to do System.exit(...) at some point as the Endpoint method starts on a non daemon thread. Just don't do it in the onResult method otherwise the BPEL service might record an error if the communication is not completed properly.

Wednesday, November 12, 2008

UKOUG'08 Fear / loathing tipping point

As UKOUG'08 approaches I have finally reached the point where fear of not starting on my presentation(s) has override the loathing I feel when I open power point. Still spend a good few tens of minutes sketching out the testing presentation with Geoff this afternoon so onto a good start.

Looks like I could be taking part in anything from 1-4 presentations include the one about testing I have previously talked about. More information on those as they become more clear.

Now since I have started one presentation, time to procrastinate... I wonder if they have any more cakes in the restaurant......

Using the DemoIdentity and DemoTrust keystores that come with weblogic

Having come from the world of OC4J where enabling https required the sacrifices of your first born: it is nice to know that in weblogic you can start working with just a tick of a box. (For the internal JDeveloper instance http://localhost:7101/console -> Servers -> DefaultServer(Admin) -> SSL Listen Port Enabled)

It is worth knowing that to make this trick happen weblogic generates a new DemoIdentity on install that is unique to your machine. The key in this is then used to set up of the https channel.

If you are connecting to the server you need to know where the key stores live, so here is a table with all the default values in:

Property Value
Trust store location %ORACLE_HOME%/weblogic/wlserver_10.3/ server/lib/DemoTrust.jks
Trust store passwordDemoTrustKeyStorePassPhrase
Key store location %ORACLE_HOME%/weblogic/wlserver_10.3/ server/lib/DemoIdentity.jks
Key store passwordDemoIdentityKeyStorePassPhrase
Private key passwordDemoIdentityPassPhrase

Most of the time you will be using the trust store to talk to the server. (Generally by passing in -Djavax.net.ssl.trustStore=.../DemoTrust.jks to the java process is enough)

If you are trying to configure the http analyzer in JDeveloper to run with https you will run into a problem as it assumes that the keystore and private key password are the same. (This should be fixed in a future version of JDeveloper if all goes well) This is not the case with the weblogic DemoIdentity.jks store. You workaround this is to use the "keytool -importkeystore" command to import the DemoIdentity in a keystore where both password are the same. This would look something like:

  keytool -importkeystore -srckeystore .../DefaultIdentity.jks 
     -srcstorepass DemoIdentityKeyStorePassPhrase -srcalias demoidentity 
     -srckeypass DemoIdentityPassPhrase 
     -destkeystore .../server.jks -deststorepass 
     -deststorepass welcome -destalias demoidentity -destkeypass welcome