Creating a Highly Productive Java-based Development Environment

Dr. Paul Dorsey, Dulcian, Inc.

Several issues arise when you move towards a Java-Based Development environment.  Since many developers are migrating from Oracle Forms and traditional languages like C, they naturally want to carry over the skills and techniques they used so successfully in those environments.  However Java is not just an upgraded "Internet" version of these products.  While there are many parallel aspects in each of these environments, there are also several key differences.  These differences fall into several categories:

 

1.       Features that Java does not support

2.       New features that are unique to Java and the Java Development tools

3.       Features that are similar but implemented differently

Each category will be discussed in turn along with a discussion of some of the available Java tools.

 

1. Features that Java does not support

The Java language does not support certain fundamental features due to the security conscious, object-oriented premise that is the foundation for this powerful and dynamic language.  Perhaps the most significant difference is the deliberate elimination of pointers in Java.  Pointers have been around since the beginning of modern programming.  They were suitably designed for isolated applications that could run independently, and had total ownership of all system resources.  Pointers do not exist in Java because of their inherent lack of security.  The use of traditional pointers allows any application to have access to memory outside of the limits set aside for it in a multitasking environment.  Pointers thus make it possible for the “bad guys” to gain access to data, or to damage other programs that were running concurrently.  Thus many programming techniques such as indirect addressing, and incremented-pointer array access must be implemented in other ways when coding in Java. 

 

Some Other Important – “Missing Features”

·         Java does not allow the use of Default arguments.  All parameters must be defined and passed, as coded in the more rigid Java statements.

·         Java does not support function-overloading or operator-overloading.  It was a judgment call to eliminate these features to reduce the confusion they might create during code development and maintenance.

·         Java does not have global variables, as such.  Instead Java is an object–oriented language where code is encapsulated in one or more classes.  Each class can have access to all of its inherited classes and objects, thus providing a way for the code to share objects that act like traditional global variables.

·         Java’s class structure does not support multiple super-classes.  Java’s simple inheritance structure provides for a single-class inheritance hierarchy (i.e.  C inherits B, and B inherits A…  thus C has access to A).

·         Java does not provide for automatic type conversions.  All conversions must be explicitly cast.

 


Strategy

To make the Java environment efficient, you need to develop very precise coding and GUI standards so that developers do not waste a great deal of time "doing their own thing".  In creating a strategy to overcome the conversion problems, you must deal with the code structures that have changed in the basic language, and select an appropriate Java toolset to reduce the laborious task of producing Java source code.  The key to success in creating a rapid development process is the construction of reusable components that bridge the gap between the old and new tools.

 

Some Examples that deal with the basic language conversion concepts

The following examples illustrate some of the issues of converting to the Java language.

 

1. Converting code to handle Indirect-Addressing

For the most part it is easy to upgrade pointers to the Java development environment.  Since Java passes all objects by reference, it is possible to create Java "Classes/Methods" that can act like pointers in many respects.  By implementing object-reference-variables it is possible to access both an object and its reference.  By passing references to a temporary variable in Java, it is possible to create an implementation, which functionally acts just like an Indirect-Address-Pointer.

See the following example, which calculates the Volume of several Boxes and uses a Temp variable to access/update these Boxes by reference.

a. Indirect-Address Example

Create a simple Class to hold the dimensions for a Box:

 

public class Box {

  double width;

  double height;

  double depth;

}

 

Create a second Class to calculate the Volume of two Boxes, using a single Temp reference object as an indirect address reference to the Box objects:

 

   public class BoxDemo {

 

     public static void main(String args[]) {

   

       double volume;  //variable to hold the results

 

             /* Create 1st Box */

 Box mybox1 = new Box(); //allocates memory for 1st Box

 /* Assigns values to variables for 1st Box */

    mybox1.width  = 10; 

    mybox1.height = 20;

    mybox1.depth  = 15;

 

 /* Show Results: Calculate Volume and print output */

     volume = mybox1.width * mybox1.height * mybox1.depth;

     System.out.println("Volume 1 is " + volume);

The Output produced by this line:

  Volume 1 is 3000.0   

 

 /* The 2nd Box */

 Box mybox2 = new Box(); //allocates memory for 2nd Box

    mybox2.width  = 20;

    mybox2.height = 20;

    mybox2.depth  = 15;

     volume = mybox2.width * mybox2.height * mybox2.depth;

     System.out.println("Volume 2 is " + volume);

The Output produced by this line:

                                  Volume 2 is 6000.0

 

 /* Now create a plain Box Reference Object that can be used to

   point at the two boxes that have already been created */

 Box myboxTemp;          //No allocation - just a reference

 

 

 /* Copy 1stBox's reference(like a pointer) to the Temp variable */

 myboxTemp = mybox1;

 

     /* Now the Temp references the 1stBox's data */

     // Show resutls:

     volume = myboxTemp.width * myboxTemp.height * myboxTemp.depth;

     System.out.println("Volume Temp is " + volume);

The Output produced by this line:

                                  Volume Temp is 3000.0

 

 /* Change the Temp variable to reference 2ndBox */

 myboxTemp = mybox2;

 

     /* Now the Temp references the 2ndBox's data */

     volume = myboxTemp.width * myboxTemp.height * myboxTemp.depth;

     System.out.println("Volume Temp is " + volume);

                         The Output produced by this line:

                                                                   Volume Temp is 6000.0

 

  

 /* Change 2ndBox's width using the Temp variable as a reference */

 myboxTemp.width = 1;

 

     volume = myboxTemp.width * myboxTemp.height * myboxTemp.depth;

     System.out.println("Volume Temp is " + volume);

      volume = mybox2.width * mybox2.height * mybox2.depth;

      System.out.println("Volume 2 is " + volume);

      volume = mybox1.width * mybox1.height * mybox1.depth;

      System.out.println("Volume 1 is " + volume);

                         The Output produced by these lines:

                                                                   Volume Temp is 300.0

      Volume 2 is 300.0

   Volume 1 is 3000.0

  }

}

 

The preceding example illustrated how Java could use an object-reference-variable as a workaround for Indirect-Addressing.  Note that when a reference is copied to the Temp object, all data remains unchanged.  Only when explicit calls are made to the underlying data stored in the width, height, and depth variables, are changes actually made to the stored data.

 

2. Example that deals with Java language conversion

A second example for converting to Java is presented below.

 

Converting code to handle Default Arguments

One extensively used feature of Oracle Forms and PL/SQL, that Java does not support, is Default Values for function-arguments.  A traditional Oracle practice for overloading functions is to use these Default Values for some arguments.  Java does not allow this practice since it requires unique methods to be defined for every function.  Consider the following PL/SQL function, which calculates the area of square or rectangle by passing either one or two arguments.

 

Function area (Length In number, Width In number := 0 )

RETURN number

IS

  areaOut number;

BEGIN

  IF (width ==0)

  THEN

   areaOut := Length * Length;

  ELSE

   areaOut := Length * Width;

  ENDIF;

  RETURN (areaOut);

END;

 

Procedure TestArea

IS

BEGIN

  Dbms_output.put_line('Area of 2.2 by 3.4 rectangle: '||

                         area(2.2, 3.4) );

  Dbms_output.put_line('Area of 3.0 by 3.0 square: '||

                         area(3.0) );

END;

 

As you can see in this PL/SQL example, if the area function is called using just one argument it calculates the area for a square.  When the function receives both arguments, then the area of a rectangle is calculated using the length and width.  While this is very convenient and saves writing almost duplicate blocks of code, using Default Arguments for Overloading is not actually a necessary construct for the language.  In Java you can quickly construct a workaround by writing two overloaded methods.  Construct one method for the area of a square with one argument, and a second method for the area of a rectangle with two arguments.

 

Using this approach the PL/SQL area function can be rewritten as follows:

 

//Java version of the PL/SQL area function

 

Class TestArea (

 

 /* First method for a Square */

 static double area(double Length) {

  RETURN Length * Length;

 }

 

 /* Second method for a Rectangle*/

 static double area(double Length, double Width) {

  RETURN Length * Width;

 }

 

 

 

 /* Test methods */

 public static void main(String args[] {

  System.out.println("Area of 2.2 by 3.4 rectangle: " +

                          area(2.2, 3.4);

 

  System.out.println("Area of 3.0 by 3.0 square: " +

                          area(3.0);

 }

}

 

 

2. New Features that have been added by Java

The following is a list of some new features Java uses to make a significant impact on its applicability to today’s multitasking environment.

·         Java can spawn multiple “threads” concurrently.  This significant Java feature allows the simultaneous execution of several code-segments using simple and straightforward commands.

·         Java incorporates an improved memory allocation methodology.  It does not require any explicit commands to free memory when an object no longer has any valid references.  A garbage collection routine automatically deletes the object after it detects that the last reference has been dropped.

·         Java adds its own API's classes that provide an ever-growing library of new code segments that improve functionality and productivity.  With the Internet GUI as its prime focus, Java encompasses an almost limitless supply of new Look-and-Feel components for the application developer.  The use of these object-oriented components is not limited to just Java applications; they can also be used directly in the Oracle Developer Products (Form Builder and Report Builder R6.0) and can be stored in the latest releases of the Oracle RDBMS products.

 

3. Features that are implemented differently

While Java has many features that are very similar to other languages, they are implemented slightly differently.  Generally Java uses a more disciplined and restrictive implementation for its coding practices.

·         Access specifiers in Java only apply to the object directly following the specifier.   In other languages they may apply to a whole group of objects that follow the specifier.   

·         Exceptions in Java must be "caught".  Other languages may not be as strict in their handling of exceptions.

·         Boolean operators in Java are predefined as literals "true and false", and these are the only values that Java will recognize.  Other languages may allow Non-Zero values to represent True, etc....

 

Selecting and using Java Development Tools

The selection of a toolset to help you implement your application with today's Internet/Intranet_multi-tier_thin-client requirements is a challenge for every member of a Rapid Development team.  Developers are caught by a two-edge sword.  One edge represents the need to ship today's products, which leaves developers little time to explore the new features.  The other edge represents the loss of potential productivity the new features might provide.  The following is a quick and dirty overview of what you should look for, as you make your selection of Java development tools and integrate them in your Application Development process.

 

Trade Offs to ponder

Will it be user-friendly?  Will it have good performance?  Is it maintainable?  Can you replicate it quickly?  Can you test it before deployment?  ...All of these are good questions, each dictating its own need for prioritization.  Some developers will set the implementation of their own pet tool or method as their priority, whereas the extreme hacker might focus on 34hour non-stop coding stretches.  To the vertical-market developer, priority may mean rapid-reusable code segments that can be used to prototype applications in a single day!  No single answer will meet everyone's needs. However ,everyone will agree that in today's climate, development speed will have an enormous impact on success and profits.

 

Success for rapid development arises from:

·         Building applications from other partially-built pieces.  Whether they are called templates, classes, methods, SmartClasses, libraries, packages, beans, etc....  The message is the same "Don't re-invent the wheel".

·         Re-using the skills and techniques that were so successful in your current environment (Oracle Forms, C, VisualBasic, etc...).

·         Mixing the old with the new (products, processes, technologies, etc..).

 

The Answer: Use Java to extend your development tools

Java and its related development tools, such as Oracle's JDeveloper can work well as a supplement to your development tools.  For instance, if you are currently using Oracle Developer, you can make the most productive use of Java by first noting the differences in focus between Developer and JDeveloper:

·         Language Support
JDeveloper = Java Environment plus PLSQL, whereas Oracle Developer, which also supports PL/SQL, uses it as its primary language.

·         White-Box vs. Black-Box
JDeveloper allows you to manipulate the code that it generates to build a form, whereas the Oracle Developer Forms product allows the addition of things like triggers, but offers little utility to modify the generated code.

·         Stability
Oracle Developer (Developer/2000) has been around a lot longer than JDeveloper.  The growth of JDeveloper is so rapid that it has struggled through three major releases in less than one year.

 

The Strength of Java

Perhaps the most significant member of the Java family is the JavaBean.  Simply stated, the JavaBean is just a reusable piece of Java code.  Java code can be used to create almost anything, such as a pre-defined box (color, font, size, placement, borders, beveled edges, scroll bars, lists, sliders, buttons, progress bars, check boxes, info trees, tab panels, menu bars, navigation controls, login dialogs, status bars, pop-up menus, find panels, editor panes, grids, tables, charts, graphics, etc.) to display data. The coherent JavaBean Specification is fundamental to its widespread acceptance, and the JavaBean provides the front door to the complexities of this Internet-friendly language.  To automate what would otherwise be a rather laborious and error prone activity, it is paramount that you select a Java tool set that will create and edit these Beans.  Just as very few developers hack out pure HTML code, it is likewise not necessary for you to become a Java Nerd in order to utilize one of today's user-friendly tools such as Oracle's JDeveloper.

 

 

Development Tools

The Java development tools you select should be equipped to integrate the "nuts and bolts code for visual data presentation" independently from the "business logic code" behind data selection.  Also both types of code should be re-useable in either a pure Java environment (like a JavaBean) or be capable of being ported back to Oracle Developer Forms as a "Pluggable Java Component"(PJC). 

 

Using JavaBeans

No rapid development environment would be useful if it did not allow you to reuse your components.  In JDeveloper reusing components (i.e. JavaBeans) is provided by a number of palettes.

 

The basic component palette, which is the primary tool used to access JavaBeans, is a fully configurable tab set.  You can add/delete/edit pages to your heart's content.  JavaBeans can be shared by putting them in a JAR or used directly from your package library.  To identify your JavaBeans, you can even add new GIF icons to the menu bars and palettes.  Adding new JavaBeans to your collection is one of the best ways to utilize your historical code segments and property preferences, thereby giving your application its own look-and-feel.  In fact, JDeveloper has its own Look-and-Feel class, which is fully modifiable and can be used to set the initial values for any of the properties used in the accessible classes.  The predefined values for Metal, CDE/Motif and Windows environments in JDeveloper's Look_and_Feel class, provide many of the basic property settings for today's most popular Internet applications.

 

JDeveloper also provides for the organization, storage and retrieval of code via:

·         Libraries (Swing1.1, JDeveloper Runtime, JBCL 2.0, JGL 3.1.0, ...)

·         Archives (*.Jar , *.Zip, ...)

·         Package Trees ( javax, javax.swing, javax.swing.text, ...)

·         Single Packages (javax.swing.text.html.parser, ...)

·         Classes (javax.swing.text.html.parser.DocumentParser, ...)

 

 

Using the Pluggable Java Component(PJC)

The Pluggable Java Component (PJC) is a simple way for you to extend the reach of your Java code.  By using the JDeveloper's PJC-Wizard (in JDeveloper3.0 or later) you can encapsulate any Java class and automatically generate the code necessary to allow you to use your components in Oracle Developer Forms.  The message here is that the PJC meets the Java Component Model that Oracle Forms (6.0 or later) supports.  Also, JDeveloper generates all of the interfacing code necessary for your Java class to be directly imported into Oracle Forms.  The PJC also has "Properties".  Please note that these are Oracle Form's properties, not Java Bean properties.  JDeveloper provides tools for you to override any of the Oracle Form properties by simply "pointing and clicking" on the displayed assessors for the inherited members you would like to override.  JDeveloper then generates the default code for you.  The final step would be for you to write the override code to meet your custom requirements.

 

What Else?

Rapid development tools need to interact with the data-source.  Several tools are provided across most Java Development tool sets.  In JDeveloper, SQL support is provided through the SQLJ syntax.  This syntax allows SQL semantics to be checked during pre-compilation and it also provides for de-bugging of the SQLJ source code.  This helps to catch potential runtime errors before the code is deployed.  Dynamic SQL, supported through the Java Database Access Standard (JDBC), is the industry's accepted method for database access.  This standard was developed to enable Java-based applications to connect to a variety of databases across multiple platforms.   While inheriting many of the attributes of its C-Language predecessor ODBC, JDBC is an entirely new standard for the collection of object-oriented classes that perform the same tasks the older ODBC functions provided.

 

The Next Level in  JDeveloper

The bulk of the application developer's time is spent in writing code that implements the Business Logic of the application, or in the efficient accessing of data for viewing, updating, insertion and/or deletion.  Using and/or developing intelligent building blocks can achieve a significant reduction in development, deployment, customization and maintenance of an application.  To this end, Oracle has restructured JDeveloper to incorporate the following new Java Business Components:

·         Entity Objects      

·         Associations

·         View Objects

·         View Links

·         Domains

·         Validation rules

 

Many of these Java components can be generated automatically using the JDeveloper Reverse-Engineering wizards that inspect the database for referential constraints and column metadata.   Additional custom business logic can be applied to the results and any code generated by the wizards can be modified to meet specialized needs.

 

Entity Objects

Entity Objects encapsulate business logic and database storage details for your business objects (database Tables).  This includes Attribute (Column) definitions and metadata for database mapping.  In addition, custom business methods can be included with Attribute and Entity level validation.

 

Associations

An Association between two Java Entity Objects establishes an active link between the objects.  These associations are used to capture your business entity relationships.  They capture Cardinality, Composition and Accessors.  The associations are saved in a XML file, thus they require no Java in their implementation.  The association is used to automatically coordinate parent-child data validation prior to sending any updates to the database.

 

View Objects

View objects are reusable components based on arbitrarily-complex SQL statements that control exactly which data is returned from the database.  Each View Object has related metadata in its XML file, which connects the column data returned in the SELECT statement to the Entity Object Attributes (Columns).  This information allows Java to coordinate the business logic rules on the client side, before any update rows are sent to the database.  Multiple views referencing the same Entity Objects are automatically coordinated through the Java framework.  This lets all views in the same session instantly see the changes made on the client side.

 

View Links

View links are used to keep the Master-Detail queries synchronized.  They link two View Objects and automatically keep the detail resultset in sync with the master resultset.

 

Domains

Domains are fixed classes that represent data types that appear repeatedly in your applications.  You can create Domains called Address, Telephone, Zip, etc. and include a validation routine in the Domain's constructor that automatically performs all of those little check routines that you find yourself writing over and over again.

 

Validation rules

Validation rules are stored in JavaBeans, thus allowing their reuse with any Entity Object that may need them.   These rules can be attached at the object level (database Table) and/or at the attribute (column) level.  

 

Template Construction

A template can be built to support JDeveloper.  This template is similar in design philosophy to templates built to support Oracle Forms. This template should include Java components that mirror Forms’ template SmartClasses and reusable components. A complex code library should be built to support the organization’s coding standards.

 

The same degree of thought needs to be put into a JDeveloper template as is used with the construction of a Forms template.  In fact, it may be more important to give serious thought to the template since JDeveloper does not provide as mature a developer interface as Oracle Forms.

 

Conclusion

JDeveloper cannot yet rival Oracle Forms in terms of productivity. Even with a the best template that we can imagine, a skilled Forms’ team should be able to out perform a JDeveloper team.  However, Java provides a better platform for web development and has greater market acceptance outside of the Oracle community. JDeveloper is still suffering from growth pains.  However, we are optimistic about its future as a Java development environment.

© 1999 Dulcian, Inc.