Saturday, 30 October 2010

AUSOUG'10 Perth conference - REST web services with JDev


It's that time of the year again when the Perth Australian Oracle User Group (AUSOUG) conference comes around. This conference is guaranteed to be only 0.005% as large as Oracle Open World, way more personable though, with better lunches, involves less walking & definitely is less tiring. Coffee is better too.

This year I'll be selling Oracle wares with the following double slot presentation:

A change is as good as a REST: JDeveloper 11g's REST web services

23rd November - "Studio 2" - 11am-12:45

Abstract: SOAP based web services can seem a hard slog to develop with their contract first design requirements, and over engineered specification that includes everything plus the kitchen sink. REST based web services provide light relief for quick web service development where the constraints of SOAP web services feel extreme for some short sharp development. Luckily Oracle's JDeveloper provides support for both styles, and in this presentation Chris Muir will demonstrate a short and sweet demonstration to getting REST web services up and running, using JDeveloper's JAX-RS support.


I look forward to seeing you there.

Tuesday, 26 October 2010

Closing Applications (Correctly) in JDeveloper

The following documents a somewhat small issue we're having with JDeveloper 11.1.1.2.0. At this time I'm unable to lodge an SR with Oracle Support as we don't understand the circumstances under which it occurs, thus we can't build the usual simple "Hello World" test case that Support so thrives on. However as we've identified the symptoms of the problem and the associated workaround I'll publish them here for others to benefit (including my team) so we don't hit the issue again.

Note this issue is only verified under JDev 11.1.1.2.0. I have no knowledge if the issue can be replicated in other JDev versions as this stage.

Issue Symptoms

From time to time after checking out an application from SVN inside JDeveloper:



....we'd discover JDev has incidentally modified one of the project files. In the following example the ViewController project is italicized meaning it has been modified:


Pressing "Save all" and then comparing the modified file against the previous revision reveals that the ViewController project has reverted back to the default settings, losing all the changes from the previous ViewController revision:


With the ViewController modified, the project can no longer compile (because among other things it's lost the attached libraries), and the change is effectively destructive. Whatever you do, don't check the ViewController project file back into SVN as it's just plain wrong.

Workaround #1

If you've arrived at this point where a project has been automatically modified by JDeveloper when checked out of SVN, the workaround in this situation is to Revert the project file back to the previous revision.

A Known Unknown Bug

In the example above I've identified the issue with a ViewController project in an ADF application. However note this problem isn't specific to any project type (e.g. Model, ViewController, whatever). We've experienced this issue across different projects in different applications from time to time. The converse of this issue is there's been a whole lot of projects this issue doesn't occur for too (i.e. in the above example, the Model project wasn't incidentally modified too), so the problem has something to do with the specific project configuration where the error occurs. Unfortunately we're unsure what that specific configuration is. However once the problem is detected it is consistently replicable on the problematic project at hand.

Bug Preconditions

While we haven't been able to work out what configuration in the project files causes the bug, we are aware of a set of steps that do lead up to the bug.

From a day by day basis our programmers will have an application open in JDeveloper, synced with an SVN repository:


From time to time the programmer makes a decision that rather than syncing each individual file change coming from the SVN repository into the application, it's just easier to delete the local working copy of the application and check out a whole brand new copy. To do this the developer:

a) Closes JDeveloper
b) Identifies the working copy application directory on the filesystem
c) Deletes it
d) Opens JDeveloper
e) Checks out the same application from the SVN Repository into the *same* directory that the previous working copy was checked out

It's at this point we see the issue described, but as mentioned, not for all application projects, just some projects, sometimes. However once this problem occurs, repeating steps "a" to "e" from above the issue is consistently reproducible.

From what we can see for step "e" is if we check out to any other directory, the problem isn't replicated.

What we found odd about this issue is if another developer on another machine checks out the same application, the said problematic project file wouldn't be automatically modified by JDeveloper. Yet this gave us the spark of an idea of what's going wrong and how to avoid it in the first place.

Workaround #2

You'll note in the "a" to "e" description above, the developer closes JDev, then deletes the application from the file system, then re-opens JDev. What we're not giving the JDev IDE here is a chance to recognize that one of the applications it had opened has been removed completely from the file system.

The IDE seems to be partially smart in that the application is removed from the application poplist at the top of the Application Navigator when we reopen JDeveloper. Yet if we then proceed to check out the same application as described in "a" to "e" we hit the described problem.

A workaround to the problem is before closing the JDev IDE, via the Application menu selecting Close, to close the selected application. If this option is done first the end problem is not seen. The conclusion is this gives JDev a chance to tidy up it's internal state about which applications and projects are open, and somehow this avoids the bug we're experiencing.

Arguably the IDE should be able to handle this situation regardless. The fact that the bug is destructive to the project configuration is a major concern, especially if a junior programmer doesn't understand what's happening and checks in the changed project file regardless, but in the end following the workaround steps here avoid the issue in the first place.

Wednesday, 20 October 2010

Can't we all just get along? JDeveloper vs Apple QuickTime

Every once in a while on running an application via JDev, usually just before I'm about to present (argh!), the integrated WLS doesn't start, displaying the following error message:

*** Using port 7101 ***
C:\Users\Chris\AppData\Roaming\JDeveloper\system11.1.1.2.36.55.36\DefaultDomain\bin\startWebLogic.cmd
[waiting for the server to complete its initialization...]
\QuickTime\QTSystem\QTJava.zip was unexpected at this time.
Process exited.

This error occurs because under Windows, anytime I update Apple's iTunes on my PC, which in turn more often than not installs a new version of Apple QuickTime, the QuickTime installer adds the following entry to the CLASSPATH environment variable:

CLASSPATH=.;C:\Program Files (x86)\QuickTime\QTSystem\QTJava.zip

It can be fixed by removing the entry, and restarting JDev.

Tuesday, 12 October 2010

ADF BC - Read Only View Objects and missing PK attributes – A Passivation Issue

A recommended ADF development best practice from Oracle is to check your applications are Activation Safe. In recent testing of an ADF 11g application we discovered the following scenario where our application failed Activation Safe testing, documented for others to read-but-not-experience-first-hand.

Problem Scope

Consider an application displaying employee details. The first screen contains a table of employees, and on selecting a specific row, the 2nd screen shows the details of the selected employee.


Note in the screen shots, selecting employee ID 106 in the table, displays employee ID 106 in the form screen. Essentially the expected behaviour.

In this example from the ADF BC point of view the employees data is backed by a Read Only View Object (VO) based on the employees table from Oracle's HR schema. By default the employees VO contains the following attributes. Note the PK employee ID:


By chance if we disable the PK and run the application, it performs in the same way as described in the first picture above on the developer's PC. Selecting employee ID 106 in the table results in the same record 106 shown in the second page.

Interestingly in the JDev console, as we select the employee in the table, the following message is displayed:

<CurrencyRowKeySet><_computeCurrentRowKey> ADFv: Rowkey does not have any primary key attributes. Rowkey: oracle.jbo.Key[], table: oracle.jbo.server.ViewObjectImpl@e48114.

Yet as stated the application works correctly. Can we ignore this error?

Activation Safe testing teases out the problem in more detail. Activation Safe testing requires us to right click the Application Module -> then select Configurations -> AppModuleLocal -> Pooling and Scalability, and then *disable* the Enable Application Module property:


On re-running our application we see the following behaviour:


...that is on selecting employee ID 105, and navigating to the next page, oddly the record shown is employee ID 100. Selecting the back button, on returning to the table page, it still shows employee ID 100 as the selected record regardless of our original selection.

On looking at the JDev console window when selecting employee ID 105, we see that the log message has expanded:

<CurrencyRowKeySet><_computeCurrentRowKey> ADFv: Rowkey does not have any primary key attributes. Rowkey: oracle.jbo.Key[], table: oracle.jbo.server.ViewObjectImpl@9ddef9.
<FacesCtrlHierBinding$FacesModel><makeCurrent> ADFv: No row found for rowKey: [oracle.jbo.Key[]].

If you turn on the -Djbo.debugoutput=console option when running the program the problem is revealed in more detail:

[978] Warning! Binding:noCtrl_oracle_adfinternal_view_faces_ model_binding_FacesCtrlHierNodeBinding_1 requires key attributes to be able to locate nodes in the hierarchy.

Conclusion

From identifying this problem the natural conclusion is in order to build an Activation Safe application, amongst other issues your View Objects require a primary key. Typically this isn't an issue as most VOs are based on EOs, where the IDE enforces each EO has at least one primary key attribute that is shared to the VO. But in the case of Read Only VOs not based on an EO, it's fairly easy to create a VO without a PK attribute. In the simple example from this blog, of course the employees table has a PK attribute, but, if we're building a customised VO based around some complex query, in particular if we use the expert-mode VO option, no PK is defined by default. Thus our application becomes Activation unsafe.

Addendum

Tested under JDev 11.1.1.2.0 build 5536.

Saturday, 2 October 2010

REST Web Services in Oracle's JDeveloper in 10 easy steps

I'm currently writing a REST Web Service presentation for the Australian Oracle User Group, and thought it would be useful to document in 10 quick steps how to enable REST Web Services in Oracle's JDeveloper using the Jersey implementation of JAX-RS (JSR311). This is documented in Oracle's online documentation, but that's never stopped me writing a blog entry before in my usual succinct manner.

Step 1 – Create your Application Workspace – base it on the Generic Application template:

...and let it create the default project with no technologies:

...with this result in the Application Navigator:

Step 2 – Download the required Jersey libraries . Note JDev 11.1.1.3.0 that this blog entry is written in supports Jersey 1.1.5.1 and above. At the time of writing the latest non-beta release was 1.4 and is used as a basis for this blog.

From the Jersey download documentation page this requires you to download 3 files:

jersey-server.jar
jersey-core.jar
asm.jar

Alternatively you can use the Jersey bundle, implying you need to download:

jersey-bundle.jar
asm.jar

We'll assume you've downloaded the 3 JARs for the rest of this blog.

Step 3 – locate the JDev Application Workspace on the filesystem, create a subdirectory "lib" and copy the 3 downloaded JARs into this directory:

Step 4 – open the project properties (right click -> Project Properties) in the Application Navigator and add the 3 JARs under the Libraries and Classpaths option – Add JAR/Directory option:

Step 5 – create a simple POJO in the Project, with a simple method to return a String:
public class MySimplePojo {
public String helloRESTWebServices() {
return "helloRESTWebServices";
}
}
Step 6 – add the @Path annotation to the class and add the appropriate import:
import javax.ws.rs.Path;

@Path("myRESTWebService")
public class MySimplePojo {

public String helloRESTWebServices() {
return "helloRESTWebServices";
}
}
Step 7 – Note the orange squiggly line under the @Path annotation. Click on the Path keyword, then select the light globe in the left margin. It will show the option "Configure web.xml for Jersey JAX-RS web services" which when selected will configure the project correctly to run the web service once deployed:

....you'll see the web.xml file added in the Application Navigator:

Step 8 – Annotate the simple method with the @GET and @Produces annotations:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("myRESTWebService")
public class MySimplePojo {

@GET
@Produces("plain/text")
public String helloRESTWebServices() {
return "helloRESTWebServices";
}
}
Step 9 – Save all

Step 10 – Right click the POJO in the Application Navigator and select Test Web Service:

...this will deploy the app to the integrated WebLogic Server, and open the HTTP Analyzer window. From here you can send a request to the deployed REST Web Service and see the result:

And you're done.

In all seriousness step 9 wasn't even much of a step, but "Express REST Web Services in Oracle's JDeveloper in 9 easy steps" doesn't have much of a ring to it.

With Thanks

With my thanks to Gerard Davison for his assistance on sorting out the library details for this post.