Saturday, 30 June 2007

JDev OTN Forums vs Oracle Support: are OTN Forums enough?

It's a common past-time of non Oracle employees to make negative comments about Oracle Support.

This isn't one of those posts.

What this post is actually about:

In the last 3 years while I've been working with JDeveloper I've seen a great dedication by the JDev team in answering the JDev OTN Forums, as well as good input by the relative JDeveloper community at large. In fact it's so good that I rarely have to resort to Metalink or Oracle Support for support on JDeveloper; the exception being bug reports which don't appear in a public forum, but within Metalink.

So my question to you is this. Where do you now go predominately for JDeveloper support: JDev OTN Forums or Oracle Support/Metalink?

And my 2nd question: Is there any support like information you can find in the Forums that you can't find at Oracle Support/Metalink and vice versa?

What's your thoughts? Your constructive ideas appreciated.

Tuesday, 19 June 2007

I rest my case: Converting ADF BC EO/VO attributes to upper and lower case with custom properties

Oracle Forms at the item level has a property for ensuring string data entered is forced to uppercase or lowercase, or leaving the case unchanged. At this time in JDev 10.1.3.x there is no out of the box facility to do this. However there are a number of methods that can be employed to implement this feature. In this post we'll specifically look at using custom properties on the ADF Business Component (ADF BC) Entity Object (EO) attributes to flag to a custom method to convert the data to upper or lower case as required, or leaving the case in its original state if not.

The goal of this post is 3 fold: firstly a technique to solve the problem at hand, but secondly to show why custom properties are useful, and thirdly what a custom ADF BC framework can allow you to do.

What is a custom property?

JDeveloper's ADF BC Entity Objects and View Objects are comprised of 1 or more attributes representing the columns of data stored within the objects. For each attribute under the associated editor, on selecting a specific attribute, 3 tabs show: Entity Attributes, Custom Properties, and Control Hints.

The Entity Attributes tab shows a number of predefined properties against the attribute that the developer may set and change at design time that are used at runtime to determine the behaviour of the attributes. However sometimes we may wish to extend the default properties for the attributes to store other information and create custom behaviour. For example we could create a custom property for something as simple as a description of the attribute, or alternatively a custom property that your own code can make use of at runtime to flag forcing the data to upper or lowercase.

The JDev team has therefore included custom properties to allow extensibility in the ADF BC framework.

(For the record, custom properties in addition to being defined at the EO/VO attribute level, can also be defined at the EO and VO parent level, as well as for Application Modules (AM), allowing extensibility across the full range of ADF BC object types.)

Defining a custom property

Returning to our problem, within an EO we may have a certain attribute, that is a String, that we want to force to uppercase or lowercase regardless of what case the user supplies the data in. The first step in solving this problem is we create a custom property on an EO attribute in our ADF BC stack, called for example CASE, with a value such as U for Uppercase or L for Lowercase.

For example in the following picture, it demonstrates for the Description attribute of the Events EO, I have defined a custom property CASE with value L implying the Description attribute should be converted to lowercase once entered by the user.


Creating a custom ADF BC framework

The next step in the solution is to write some code that will capture an insert/update of any String attribute in our ADF BC EOs. On capturing this event our code will check if the custom property CASE exists for the attribute, and will convert the submitted String value to uppercase or lowercase dependent on the custom property's value (U or L).

In order to capture the insert/update of all attributes in ADF BC, we need to override the oracle.jbo.server.EntityImpl.setInternalAttribute() method. Section "25.2 Creating a Layer of Framework Extensions" of the Oracle Application Development Framework Developer's Guide for Forms 4GL/ Developers shows how to create a custom ADF BC framework that overrides all classes. Implementing the ADF BC custom framework as described in section 25.2 is considered good practice, though in this specific blog post we're only interested in providing a custom EntityImpl implementation where we can override the setInternalAttribute() method.

The end result is you will end up with a custom EntityImpl class that looks something like this:

public class EntityImpl extends oracle.jbo.server.EntityImpl {
  protected void setAttributeInternal(int i, Object object) {
    super.setAttributeInternal(i, object);

  }
}


Note I've added the setAttributeInternal() method by selecting the Source menu and Override Methods sub-option with the above code showing, then selecting the setAttributeInternal(int i, Object object) method out of the list.


If you've already created a number of ADF BC objects and associated classes, you'll need to change the existing classes to extend your new custom classes rather than the default JDev ones. eg:

public class EventsImpl extends model.common.EntityImpl


Overriding the setAttributeInternal method

The final part of our solution is to override the setAttributeInternal() method as follows:

protected void setAttributeInternal(int i, Object object) {

  AttributeDef attrDef = getEntityDef().getAttributeDef(i);

  if (attrDef != null &&
      attrDef.getJavaType().getName().equals("java.lang.String")) {
    String caseProperty =
      getEntityDef().getAttributeDef(i).getProperty("CASE").toString();

    if (caseProperty != null && !caseProperty.equals("")) {
      String value = (String)object;
      if (caseProperty.equals("U")) {
        value = value.toUpperCase();
      } else if (caseProperty.equals("L")) {
        value = value.toLowerCase();
      } else {
        // Do nothing; unknown value
      }
      object = value;
    }
  }
  super.setAttributeInternal(i, object);
}

The new method:
  1. Retrieves the definition for the current attribute which we need to retrieve the attribute datatype and custom property
  2. Checks if the attribute is based on java.lang.String
  3. Retrieves the CASE property from the attribute definition if it exists
  4. If the CASE value is U converts the settable value via a call to toUpperCase()
  5. If the CASE value is L converts the settable value via a call to toLowerCase()
  6. If the custom property CASE isn't present, the attribute isn't a String, or the CASE value isn't U or L, does not modify the settable value
  7. Calls the super setAttributeInternal() method to do the rest of the work.
Note how the custom ADF BC framework only requires us to define this code once, overriding and extended the default ADF BC facilities, rather than coding this facility across all our EOs.

Alternative methods for case conversion

As indicated in the header of this post, this is not the only method for achieving this. If you're using ADF Faces for your UI, you can utilise CSS styles or Javascript to force the data to uppercase. Of course you could also achieve this in the database by converting values to upper/lowercase via db triggers.

As normal in computing, there are a number of different ways to skin a cat, and which is best for you depends on your circumstances.

Sunday, 17 June 2007

4 things I read more recently

The 4 following posts caught my eye more recently:
  • Is REST Winning? - last time I worked with Web Services, REST had just appeared on the radar. With my head in the JDeveloper ADF box more recently, I missed a whole discussion on WS vs REST. However it's good for once to come in at the tail end of the debate saving me some actual "thinking" about the whole issue on my part. Stefan Tilkov gives his thoughts instead in this post.
  • Uses of Pseudo Code in Development - my sweet point in coding is when I have to write a tricky routine, and need to resort to pseudo code to nut out the details. The challenge is made easier by the simple technique of pseudo code, a dry run of coding if you will without the constraint of whatever language you're using. It still surprises me I don't see more coders (read: any) using this technique. Nick Halstead gives a good summary and pointers on this .

Thursday, 14 June 2007

Across the Nullarbor with a taste of Java

Mid July I'll be driving the 3430kms from Melbourne to Perth for, well, um, I'm not sure, but it'll be an interesting drive across the Nullarbor. The drive across from east to west is seen as a bit of right of passage for Australians, only being bettered by driving around the whole country.

The Nullarbor trip is certainly something you want to do once. Huge expanses of nothing. You have to drive it to experience it, or so I'm told. Driving it twice or more, given its renown for being just a tad monotonous, shows that maybe you just don't have much going on in your life ;)

In between dodging kangaroos, overtaking road trains, and paying through the nose for petrol, the South Australian branch of the Australian Oracle User Group (AUSOUG) has asked me to stop over in Adelaide and present on Java at their monthly meeting Wednesday July 18th. I'll be running with the popular presentation I ran at the AUSOUG Perth conference last year and that at the NZOUG conference earlier this year:

All you (ever) needed to know about Java - a 2hr Java introduction for the not-so feint-hearted. This presentation is aimed at PL/SQL programmers and DBAs who want to quickly discover that the Java language isn't really that hard regardless of what moaning you've heard elsewhere, and why it's important to know something about Java even as an Oracle expert.

This presentation is normally part of Sage Computing Services' JDeveloper 5 day workshop that we teach to clients in Australia. Previous attendees have admitted they learned more about Java in this workshop than in all their previous struggles to come to terms with the language.

If you're interested in attending contact the AUSOUG SA committee members (their details are accessible via the AUSOUG website). I look forward to seeing you there.

(With thanks to Yewenyi for releasing the Nullarbor photo on Flickr under CC)

Monday, 11 June 2007

My 15 minutes of fame - Oracle Regional Director

On my walk to work today I saw a great little quote in an art store:

"In the future everybody will have their 15 minutes of fame"

For me my 15 minutes has arrived today. Please ensure to stay on this page for an entire 15 minutes so I'm not short changed. I'll be checking my blog stats continuously so don't skimp me or there will be trouble :P

Oracle has kindly accepted my nomination for an Oracle Regional Director role. I'm appreciative of Oracle (and specifically to their staff -- you know who you are) for this. As I've expressed before, there are a large amount of individuals who don't work for Oracle and spend a large time promoting Oracle products and services, possibly through user group activities such as for myself, and other forums. Volunteering and working for user groups can be a thankless task; you really have to work for a simple thank you sometimes. So a little appreciation and recognition from another direction such as Oracle's efforts here go a long way (well, you sold me anyhow) into keeping things running.

The problem is now I've a reputation to live up to, given all the other great Regional Directors!

Thursday, 7 June 2007

Wider considerations on adopting JDeveloper - may you live in interesting times

Picking up a new tool like JDeveloper and its Application Development Framework including ADF Business Components and ADF Faces can provide interesting and exciting times for developers. New technologies offer new opportunities, especially the chance to have a good old play with something cool. Java programming, yes! JavaServer Faces, you bet! AJAX web components, yeehaw! But in developing with a new tool it's too easy to become focused on the tool itself and ignore the greater picture of how the technology will fit in.

Duncan Mills & Peter Koletzke have an excellent book Oracle JDeveloper 10g for Forms and PL/SQL Developers that considers the design & development methods that you may wish to follow when designing a JDeveloper application for the first time. Their recommendations come from experience and provide a good step ahead on implementing a successful new project.

From my own experience I'd like to suggest that IT organisations moving from a traditional Oracle Forms background or elsewhere, looking to go 100% JDeveloper need to expose themselves to the following concerns that aren't necessarily obvious and documented:

LDAP based security including OID - Java Enterprise Edition (JEE or what was J2EE) applications through their use of the Java JAZN/JAAS security facilities lean themselves heavily to introducing LDAP based security servers into your organisation rather than relying on database security, including JDeveloper's ADF. Software engineering suggests development should consider security as early as possible in the design cycle. JDev developers should consider a POC project to get a flavour of how security works itself into JDeveloper's ADF framework. Your DBAs need to get OID or whatever LDAP server up and running in a dev, test and prod environment to understand the complexities, as well as dictating how they want to standardise the setup of LDAP users and roles/groups and pass this onto the developers. Such thoughts don't want to be retrofitted late into the system development.

File version control system such as CVS or Subversion - a number of sites, particular Oracle Forms sites run with antiquated file version control systems (or none at all!) such as PVCS, RCS, or older MS-Visual SourceSafe versions. The Java world prefers change control systems such as CVS or SVN (Subversion) and this is true of JDev. Plug-ins for other version control systems are available but these are provided by 3rd parties, while the CVS/Subversion support is in the core product. A backed up CVS or Subversion code repository is essential, but luckily the software is also free.

CVS and SVN utilise a lazy locking model, allowing 2 developers to change the same file at the same time. The rude shock is that the developers may be required to merge their code changes on check-in unlike other hard-locking 1-developer-can-change-only systems. JDev application development can certainly be structured to avoid this to a degree, but for developers this understanding generally comes through experience rather than best practices. This problem is exasperated by the fact that new developers will build JDev applications in isolation for the first time and a little knowledge can be a dangerous thing. Later programmers code together based on a CVS/SVN code repository, are changing files here-there-and-everywhere, and suddenly a huge mess of code requiring merging exists. Wouldn't you rather avoid this with a little experimenting early on?

OC4J - a deployed ADF application will run within Oracle's OC4J container, a JEE compliant application server buried within OAS. OC4J is a sophisticated product and rightly so as it's designed to serve a scalable amount of users. On its first install it runs with default settings that prove satisfactory for your applications, but not for production purposes. Somebody needs to understand its facilities, how to configure it, what logging is required, its shareable library infrastructure (10.1.3+), failover support, load balancing support -- etc -- I said it's a sophisticated tool didn't I? A number of sites have come to grief by leaving their setup and understanding of OAS and OC4J till user acceptance testing and production deployments. There's nothing like a failing server to make your new system look poor.

Maybe the database isn't the best place for absolutely everything - a number of sites demand if they used to store absolutely everything in the database about their application, such as multilingual field names, application menu logic, user interface security rules, then the new tool should do it too. Now I'm not arguing this isn't an amicable goal and the database is the best place for data processing, but are you creating a mountain out of a mole hill for your initial development requirements? Remember picking up any tool is a difficult task, so don't make it harder than you need to straight away, otherwise your project is going to fail (read: KISS). Consider how the new tool wants to do things by default and maybe just maybe bend a little. Give consideration that tools' architects might have had bigger issues in mind than what you've considered -- so do some research why they want you to do certain things that way. Later when you're experts and you think you know better, feel free to rewrite everything to your needs. Maybe even send the original tool architects a nasty email.

Check out the wider JSF community - not really a concern but just some general advice. Oracle's ADF Faces is based on JavaServer Faces. Oracle is not the only JSF vendor out there. Take time to look further a field to understand what the rest of the community is working on. You may be pleasantly surprised to discover that the "why did Oracle do this?" will become an "ahhhhh" moment, or an "Oracle hasn't provided any examples" to an "Oracle didn't provide any examples because Sun documented it sufficiently already".


The implementation of a JDev system will certainly provide interesting times for any organisation. A bit of expended time working outside the JDev box will ensure you're not stuck in the box having no idea where to turn when project crunch time comes to the fore.

Happy JDeveloper-ing!

Sunday, 3 June 2007

JDeveloper - forget lines of code, data bound web pages in only 29 mouse clicks

Programming language complexity (or how easy development is with the language) is often judged by the lines of code the programmer has to write to generate anything useful. Take the whole Ruby on Rails camp's arguments about how few lines of code they need to generate a database bound web page over traditional Java applications. The "Blah blah 15 lines of code vs blah blah 200 line of code" argument.

Bah! Lines of code, shmlines of pode I say! (I say that with the broad hope that my comment doesn't translate in a non-English language to "My Mother has shingles")

In JDeveloper using ADF Business Components and ADF Faces, a database bound web page showing a table of data, can be created in as little as 29 mouse clicks, without a single line of code written by the programmer!

In fact it gets better than that, because once you've created your first web page, things become even faster! It only takes 12 mouse clicks to create your 2nd web page! That's an efficiency gain of 58%!

Imagine how fast your 3rd, 4th and 5th web pages will be created..... by the time you've finished your application, JDeveloper will in fact be pressing the mouse button for you ;)

Here's the facts, for both JDev 10.1.3.2 and the JDev 11g Tech Preview release:

JDev 10.1.3.2

(This assumes the database connection already exists in JDev 10.1.3.2 and the database is running.)

  1. Start JDev
  2. Right click Applications node in Application Navigator
  3. Left click New Application
  4. In Create Application dialog, left click Application Template poplist.
  5. Left click Web Application option.
  6. Left click ok button.
  7. Right click Model project.
  8. In New Gallery, left click ADF Business Components option left-pane
  9. Business Components from Tables wizard is default option, left click ok button.
  10. In Initialize Business Component Projects dialog, take default connection and left click ok button.
  11. Login dialog accept default username/password, left click ok button.
  12. Left click next button first page of Create Business Components from Tables wizard to skip welcome page.
  13. Page 1 left click right double arrow button to shuffle all tables from available to selected list.
  14. Left click ok button.
  15. Page 2 select the right double arrow button to shuffle all EOs to selected list.
  16. Accept all other defaults and finish the wizard by left click Finish button.
  17. In Application Navigator right click ViewController project.
  18. Left click new option.
  19. Left click JSF option under Web Tier option.
  20. JSF JSP is default option right window. Left click ok button.
  21. In Create JSF JSP wizard, select Next button to skip wizard welcome screen.
  22. On second page select all defaults for wizard and select Finish button.
  23. Left click data control palette (assuming window open by default).
  24. Left click expand icon for default AppModuleDataControl.
  25. Drag and drop first exposed VO onto web page.
  26. From context menu move mouse over Tables option then select ADF Read Only Table.
  27. In Edit Table Dialog accept defaults and press ok button.
  28. Left click run button on toolbar.

JDev 10.1.3.2 2nd web page

  1. In Application Navigator right click ViewController project.
  2. Left click new option.
  3. Left click JSF option under Web Tier option.
  4. JSF JSP is default option right window. Left click ok button.
  5. In Create JSF JSP wizard, select Next button to skip wizard welcome screen.
  6. On second page select all defaults for wizard and select Finish button.
  7. Left click data control palette (assuming window open by default).
  8. Left click expand icon for default AppModuleDataControl.
  9. Drag and drop second exposed VO onto web page.
  10. From context menu move mouse over Tables option then select ADF Read Only Table.
  11. In Edit Table Dialog accept defaults and press ok button.
  12. Left click run button on toolbar.

JDev 11g Tech Preview

(In JDev 11g we create the database connection per application. We still assume the database is running.)

  1. Start JDev
  2. In Application Navigator left click Application dropdown.
  3. Left click New Application option.
  4. In Create Application dialog, left click Application Template poplist.
  5. Left click Web Application [ADF Faces, ADF Page Flow, ADF BC] option.
  6. Right click Model project.
  7. In New Gallery, left click ADF Business Components option left-pane
  8. Business Components from Tables wizard is default option, left click ok button.
  9. In Initialize Business Components Projects dialog select the New button.
  10. In the Create Database Connection dialog enter: A username, Password, Hostname, SID
  11. Left click Test connection button.
  12. Left click ok button.
  13. In Create Business Components from Tables wizard, left click query button.
  14. Left click right double arrow button to move all tables to selected list.
  15. Left click next button.
  16. Left click right double arrow to move all EOs from available list to selected list.
  17. Left click finish button to accept other defaults.
  18. Right click ViewController project.
  19. Left click New button.
  20. In New Gallery, left click JSF option under web tier option.
  21. Left click JSF JSP option in Items list.
  22. Left click ok button.
  23. In Create JSF JSP dialog, accept defaults and left click ok button.
  24. Left click Data controls palette option under Application Navigator window.
  25. Left click the expand icon on the AppModuleDataControl.
  26. Drag and drop exposed VO onto web page.
  27. From context menu move mouse over Tables option then select ADF Read Only Table.
  28. In Edit Table Columns dialog accept defaults and press ok button.
  29. Left click run button on toolbar.

JDev 11g 2nd web page

  1. Right click ViewController project.
  2. Left click New button.
  3. In New Gallery, left click JSF option under web tier option.
  4. Left click JSF JSP option in Items list.
  5. Left click ok button.
  6. In Create JSF JSP dialog, accept defaults and left click ok button.
  7. Left click Data controls palette option under Application Navigator window.
  8. Left click the expand icon on the AppModuleDataControl.
  9. Drag and drop exposed VO onto web page.
  10. From context menu move mouse over Tables option then select ADF Read Only Table.
  11. In Edit Table Columns dialog accept defaults and press ok button.
  12. Left click run button on toolbar.

..... yeah yeah yeah, obviously this is a bit of joke, and don't take it too seriously. Of course you'd never see such a hard hitting blog post from Oracle's blogging team ;)

But it's nice to show how easy web page development is in JDeveloper with ADF BC and ADF Faces. And without needing to write a single line of that "Evil Java Code" either ;)

Friday, 1 June 2007

The forgotten IDE? - JDeveloper

There is an interesting JDev OTN forum post at the moment. Jan Vervecken posed the question about why is JDeveloper "The forgotten Java IDE?" This question straddles all sorts of issues including the Java IDE wars, anti-Java-bias by non Java (read: Oracle) programmers, anti-Oracle/proprietary bias by Java programmers and so on.

There has been a substantial amount of views and responses including some from the Oracle JDeveloper team heavy weights and Oracle Regional Directors.

Worth a read & maybe your $0.02 worth too.

Thanks to Jan for discussing the issue.