JBuilder 3.5 - Preparing for JBuilder Certification

By: Kenneth A. Faw

Abstract: This paper will provide the information needed to successfully guide individuals towards JBuilder certification.

Introduction

This preconference tutorial is designed to walk you through requisite information to become certified in JBuilder 3.5 Enterprise, Borland's award-winning Java development environment. The organization of this tutorial is taken largely from the JBuilder Certification Study Guide, also available online.

Since the Study Guide is broken into four main categories, we will do the same. The summary will also provide information about the Borland Partnership Programs at the date of this writing.

The following list provides quick links to each section that follows:

JBuilder 3 Technical Resources

The main technical resource which will help you with certification is the JBuilder 3.5 courseware, available when you take the JBuilder 3.5 Enterprise Foundations course from and certified Borland Authorized Education Center. (Editorial: If you follow this link, make sure you check out the partners in the beautiful state of Michigan, where we have more golf courses and boating licenses than anywhere else!)

There are also many books available about JBuilder, but my recommendation is that you start with a solid foundation in Java, take the official course, and then browse through the JBuilder manuals for anything else you might have missed. The course covers most of what you need. If you would like resources on Java, consider the following:

...and probably many others we cannot fit in this document. A good list of JBuilder books is available on the Borland web site. (Go there...)

(back to intro)

General Knowledge

The Study Guide has all the questions regarding the requisite general knowledge to certify in JBuilder. Since this is a tutorial on JBuilder certification, it ought to have some answers.

Section 1: Java Virtual Machine

You should know how Java achieves portability. Java source code is portable, because it complies with the Java language specification. It can be compiled by any compliant compiler. A compliant compiler must produce valid Java byte codes for the version of the Java language specification it supports. The resulting byte code is portable to any platform with a compliant Java virtual machine, that is, any platform with a JVM certified to handle the version of the Java language specification used to write the original source.

One of the features that makes Java portable is its treatment of primitive types. Whereas most languages define primitives types in terms of the native CPU size, Java defines all primitives to be the same, regardless of deployment platform. That means that an integer in Java (represented by the int type) is 32 bits, whether the native operating system is 32 bits or 64 bits. The results is that files written from Java on one OS should be readable into Java on a different OS without concern for formatting. (You should also learn the primitive types, but that is part of section 3.)

Also important to the production use of Java is the advent of the JIT compiler. A JIT compiler is a Java Virtual Machine that loads and interprets Java byte codes just as any other virtual machine. However, the JIT compiler caches the resulting machine code for quicker execution at a later time, rather than working in a strictly interpretive mode. Recently, JIT compilers have appeared that use predictive algorithms to look ahead of your process and compile Java byte code before you need it, enhancing performance even more. (Sun's HotSpot Performance Engine is an example of such a machine.)

Section 2: Java Development Kit

In addition to the information in the previous section, certifying in JBuilder requires knowledge of some common Java terms like obfuscation and deprecation. Obfuscation is a compiler option that mangles your Java byte code to make it harder for someone else to decompile it later. Since Java is portable, and the specification for the language, the byte codes and the mapping between the two is readily available, a Java class can always be decompiled unless otherwise encrypted.

Deprecation is an unrelated term that refers to methods and classes in a previous version of the JDK which were replaced by newer substitutes in the current version. Again, it is a compiler option that generates warnings whenever deprecated methods are used in your code. It is a good idea, in general, to remove references to deprecated methods in favor of their newer alternatives, since deprecated methods may be completely removed from a subsequent JDK release.

Often, a deprecated method is replaced by more than one method, or by an entire collaboration of classes, so replacing the method call may not be trivial. In other cases, methods are deprecated without a suggested alternative. Such is the case with the stop method and other related methods of the Thread class. Explicitly stopping a Thread can be dangerous and lead to deadlocks because the Thread does not have a chance to release its resources or other locks before termination. During the tutorial, you will get an alternative pattern you can use. If you wish, here is some space to take notes:
 


 
 
 
 
 
 
 
 

 

You are welcome.

Another feature of the JDK is its support for Unicode characters. Unicode characters are 16 bits, rather than the typical ASCII character set which is 8 bits. (ASCII is also called Latin-1, or ISO 8850-1, and is also a standard.) As a larger character format, Unicode supports 65,535 characters, providing Java international language capabilities. All characters manipulated within the JVM are in Unicode, and Java provides methods for reading and writing Unicode text files. Most ASCII manipulation is not affected by Unicode, since the printing ASCII characters map directly to Unicode equivalents.

Finally in this section, we have to talk about Java Servlets. A topic in itself, servlets are one of the current rages of Java programming today. Servlets allow us to extend the functionality of our web servers, returning any HTTP response given any HTTP request. Servlets are not required to communicate via HTML, and extensive web applications can be constructed using servlets as a mechanism to tie web clients into your internal Java distributed object bus (if available).

To write a servlet, you typically override a method called doGet or doPost, or both, depending on what your servlet intends to do. For more general servlet requests, you can always override the default service method instead. Typically, the web server calls the service method, which checks the type of the request, and either calls doGet or doPost. Most servlet methods take an HTTPRequest and HTTPResponse object as parameters, which they use to communicate with the web server to handle the request.

Section 3: Java Language

The Java language is huge, as you probably knew before taking this tutorial. This section intends to review concepts you should already know. We have included a few quizzes along the way to test your knowledge.

Basics

In this section, we will review those basic features of Java that are outlined in the Study Guide. The guide mentions knowing how to construct comments and the differences between looping constructs: for, while, and do...while. The branching constructs (if...else and switch) are also useful to review, but we will spend time on those things which may need a little more explanation than simple syntactical convention.
Packages and the import Declaration
Java classes are organized into packages, making them easier to distinctly identify and deploy, and providing a means by which the JVM can try to verify their correctness. Defining packages also has an impact on class and member visibility to instances of other classes. Classes within the same package have privileged access to more data and function members than do classes in other packages.

When writing code for a class in package p1, you may need to reference a class defined in package p2. By placing an import declaration at the top of your source code file similar to:

import p1.*;
- or -
import p1.ClassName;
you can refer to the class ClassName without specifying its package. Otherwise, you could still use the class, but your source code would refer to it using p1.ClassName. The effect of the import directive is to alert the compiler to a shorthand notation you would like to use, but no code is actually generated from this declaration. In that case, import is not functionally equivalent to the C/C++ #include directive, which is a precompiler instruction to copy the contents of another file into the current one before actual compilation takes place. Furthermore, a good Java compiler should generate the same byte code whether or not any import directives are used. Its use is simply a shorthand designation for this source code file.

In the event that an import statement results in an ambiguity to the compiler, you will have to use the fully qualified class name to refer to either class in question. For example, the following code is ambiguous and will not compile as-is:

1:  import org.omg.CORBA.*;
2:  public class C {
3:    ...
4:    public Object f() {
5:      ...
6:      return null;
7:    }
8:  }
The problem is in line 4, since it is ambiguous whether the function returns an instance of java.lang.Object (since java.lang.* is always implicitly imported into every Java source file) or an object that implements the org.omg.CORBA.Object interface. Function f has to declare exactly which Object type it returns before the compiler can proceed, due to the ambiguity caused by the import statement.
Overloading Methods
A given function may be implemented several times with different parameter lists. This technique is called overloading, and it allows you to call whichever function is more convenient, based on the parameters you have available at the time of invocation.
Reference Semantics
Although Java is an Object Oriented language, you cannot directly refer to an object in your code. That is, you cannot declare an Object type of variable. Instead, we declare what are called class-type variables, whose value may be either null, or an indirect reference to an Object.

Consider the following declarations:

Object o1, o2;
The variables o1 and o2 are variables of the Object type. They may have the value null, which means that they do not currently refer to any Object. Alternatively, their value may be a reference to a physical Object allocated on the heap. In this way, references may seem similar to pointers in other languages, except that in Java, there is no way to allocate or deallocate memory to a reference. You cannot dereference a reference as you can a pointer, and you cannot perform arithmetic with references as you can with pointers.

The JVM implements a garbage collector as a low priority thread that scans for unused objects that have been allocated-- that is, those objects with no current references. When an object has no current references, the garbage collector will attempt to restore the memory allocated to the object to the heap.

Of particular interest is the methods available in Java to compare references. The equality operator is normally applied to primitive types as follows: (x == y) is true if and only if x and y have the same value. For reference types, (x == y) is true if and only if x and y refer to the same object on the heap. In pointer parlance, you might say that x and y point to the same address in memory.

Many times we are more concerned whether the objects that x and y refer to are equivalent (they are the same, member for member). In that case, we use the equals method found in every Java object: (x.equals(y)) is true if the object y refers to is equivalent in value to the object x refers to. Note that x.equals(y) does not imply y.equals(x): the Java programmer can define in their equals method what it means for another object to be equivalent. By default, the equals method does a member-for-member comparison using the == operator.

Incidentally, it is strongly recommended that if two objects references are ==, they should always be equals as well. Again, this is not required, but don't think too long about it... it should always hold true.

Object-Oriented Features

An object oriented language like Java has four main characteristics: abstraction, encapsulation, inheritance (typically implementation inheritance), and polymorphism. Abstraction refers to our ability to express real-world concepts in user defined types. Encapsulation provides a separation between the observable behavior of an object and its internal implementation, which gives us flexibility to change internal implementation without impacting users of the object. Inheritance promotes code reuse by defining generalization/specialization relationships between classes (often called "is-a" relationships"). Finally, polymorphism lets us write programs using general types, knowing that new types added to the system plug in seamlessly, all the while providing their new functionality.
Abstraction and Encapsulation
To implement an abstraction, we typically define classes to represent our real-world concept or type. Within these classes, we implement encapsulation using the visibility modifiers: public, protected and private. Alternatively, if no modifier is specified, we say that the member variable or function has package-level visibility. The definitions of these modifiers is shown in the table below:
 
Java Visibility Modifiers for Member Variables and Functions
Modifier Definition
public Visible everywhere this object is visible
(package, no modifier specified) Visible to any object within this same package
protected Visible to any object that inherits from this class, and to object that
are within the same package
private Visible only within this class

Java classes also have visibility modifiers: a class may be either public or not (as before, no modifier implies package-level visibility). For any public class, the Java compiler requires that its source code file have the same name as the class. This implies that there can be only one public class per Java source file. There is no limitation of this sort for non-public classes.

Go ahead and cover the table above, then try this quiz:

Given the following diagram:

a) What is the visibility of class A?  ________________
b) Which of class A's members is visible to each of the following classes?
 
A A1 A2 B C
private
(package-level)
protected
public
Encapsulating an object is accomplished by first declaring all its data members private: if the outside world cannot directly access the object's data, we preserve the integrity of this data by only exposing function members that leave the object in a valid state. Furthermore, we prevent external objects from relying heavily on the representation of the data internal to the object, which affords us some freedom and flexibility to modify that representation at a later time. This goes a long way toward satisfying Faw's Law #1:
 
The state of an object should be valid from the moment the object is created, through all valid transitions during the life of the object.

So if an object hides its data inside and provides only valid methods for manipulating that data, how do we make sure the internal data start out in a valid state? We write one or more constructors that tell the object how to initialize!

A Java constructor always has the following attributes:

  1. A constructor looks like a function, including visibility modifiers, but
  2. It must have the exact same name as the class (remember case sensitivity), and
  3. It cannot return any type, not even void!
When a constructor is provided for a class, you can create (instantiate) an object out of the class using the new operator as follows:
JTextField jtfLastName = new JTextField(<parameters>);
Your constructor specifies which parameter must be supplied to create the object, and it can perform validation on these parameters before allowing you to manipulate the object. As with methods, constructors may be overloaded to increase usability by simply writing additional constructor with different parameter lists.

If you do not provide a constructor for a particular class, a default constructor is provided that:

  1. Takes no parameters, and
  2. Calls the parameterless constructor of its inherited class
In this case, all the instance variables of the class are initialized to the values specified in their declaration, or their default (zero-equivalent) values. If the inherited class does not have a parameterless constructor, your derived class will not compile without an explicit constructor that you write.
Implementation Inheritance
Implementation inheritance, often simply called inheritance, is a mechanism for extending the functionality of a general type, by creating one that is more specific. A homeowner's insurance policy is a specific kind of policy, a television may be a specific kind of product, etc. By defining generalized and specialized types, you have one placeholder for general business rules, and another another for specialized rules, respectively. The specialized type enhances or extends the general type by modifying inherited functionality or adding its own.

A Java class may inherit from only one other class (this is called single inheritance), and all classes in Java ultimately inherit from a common general (base) class, java.lang.Object. By relating all classes in Java to one common ancestor, the Object class provides application-wide utility functions that are available to all Java objects. We already discussed the equals method in our section on reference semantics, but Object also contains methods like toString, clone, and others.

When a class like HomePolicy inherits functionality from a Policy class, it may be necessary to modify the inherited behavior. This modification is facilitated by overriding the inherited functionality-- writing a new implementation for the method, with exactly the same parameter list and return type. Overriding a method provides enables polymorphism, which is discussed in the next section.

There are times when you know how to override a method, but you have more difficulty with the general implementation than the specific. For example, the getPremium method of a HomePolicy might be expressed in terms of house location, building materials, flood zones, dead-bolt locks, etc. But if HomePolicy inherits the method from the Policy class, how would you implement getPremium in the Policy class?

This problem provides two original options you might choose think of:

  1. Remove getPremium from the Policy class-- Unfortunately, then, it is no longer true that all policies have a getPremium method. If a new BoatPolicy class were created and the developer of the class neglected to include getPremium, you would have no way to retrieve the premium on a BoatPolicy.
  2. Provide a default implementation in Policy that generates an exception-- In this case, all policies have a premium, and if a developer forgets to override the method, it will generate an error. However, code that uses any policy type will have to catch the error, in case it occurs.
What would be better is if we could define the method in the Policy class in such a way that it would generate an error at compile time if the method is not overridden. This type of method is called an abstract method, which looks like the method signature, followed by a semicolon, but no curly braces for implementation.

Any class that has at least one abstract method must be declared abstract as well. Furthermore, the Java compiler does not let you use the new operator on any abstract class. This implies that to create an instance of a BoatPolicy, the developer must implement the getPremium method.

While the term abstract implies that you have to create a subclass before creating an instance, the term final implies that a class may not be subclassed. The final keyword is used throughout the JDK in places where Sun does not intend you to create new subclasses that might override expected or required functionality. For example, the String class is a final class: you cannot extend the class to override any of its methods.

Just as a class can be marked final, individual methods may also be marked final. In that case, the class can be extended, but its final methods may not be overridden.

Polymorphism
As mentioned in the introduction to this section, polymorphism allows us to write code using general class types to invoke specific behaviors. Consider the following code:
public void getPortfolioTotalCost(Policy[] portfolio) {
  double total = 0;
  for (int i = 0; i < portfolio.length; i++)
    total += portfolio[i].getPremium();
  return total;
}
The parameter to this function is an array of Policy references. These references could be auto policies, home policies, boat policies, etc., assuming that each of those policy types inherits from the Policy class. You probably agree that different types of policies compute their premiums in different ways, so it is important that each Policy subtype (AutoPolicy, HomePolicy, and BoatPolicy) override the getPremium method, in accordance with the previous section.

Now in real-life, if you have a collection of insurance policies, you might refer to them general as a portfolio. But if you thumb through each one, totaling their premium, you expect that looking at each policy, you will get its exact premium, and not some general default. Polymorphism allows us to simulate the same effect in software.

You see every object reference in Java has two types: its perceived type at compile-time, and its actual type at runtime. Our function would not compile the call to getPremium if all policies did not have this method. However, the actual behavior of the method call is not determined until this code actually executes with some real portfolio of specific policy types. By our own definition, we have written code that deals with a general class (Policy) and used polymorphism to get specific behavior out of each specific policy type.
 

Polymorphism is the key to building flexible object oriented systems. It allows us to add new types to a system and receive the benefits of their enhanced behaviors. While inheritance gives us code reuse, polymorphism gives us flexibility. If we could achieve polymorphism without implementation inheritance, then we benefit from flexibility without requiring inheritance relationships.

Since the compiler prevents us from accessing specific methods and data that are not defined at the general level, is there any way to access that information after placing a specific object into a generic reference? In Java, we can always test the runtime type of an object using the instanceof operator. Then you can typecast to extract your specific information as follows:

if (portfolio[i] instanceof HomePolicy) {
  HomePolicy homePolicy = (HomePolicy)portfolios[i];
  riskManager.assessRisk(homePolicy.getOutstandingLiens());
}
Unfortunately, to check an objects runtime type, you make reference to the specific HomePolicy class, which makes your code more specific and less flexible to adding new types. The instanceof operator is also rather slow, so you might exercise caution if you have to use it too often.
Interface Inheritance
Another of the ways Java achieves polymorphism is through interface inheritance. Implementation inheritance, as described in previous sections, is a relationship between classes whose implementation is similar. Meanwhile, interface inheritance describes a relationship between classes that have the same set of functions, even if the functions are implemented in different ways. This relationship is weaker than our previous form of inheritance, and is therefore more flexible to changes.

Java defines a type, similar to a class, called an interface. This interface specifies a collection of function signatures, which are implicitly public and abstract. (Optionally, any variables declared in an interface are implicitly public, static and final.) A class that implements the interface must provide code for each of the functions it declares, or the class is also abstract and cannot be instantiated.

Using interfaces allows you to define new types in Java, whose instances do not have to be related through inheritance. In essence, any object that implements a given interface is substitutable for any other object that implements the same interface. This gives us the benefits of polymorphism, without tying us into a rigid hierarchical inheritance structure.

The Java language allows a class to inherit its implementation from only one other class, although a class can implement as many interfaces as necessary. In this sense, Java support single implementation inheritance, but multiple interface inheritance.

Special Considerations

The following subsections provide additional information about the Java language that is not covered in the sections above.
Static Members
Variables and functions can be declared static, meaning that they belong to the class in which they are defined. Only one copy of a static variable is ever created, no matter how many instances of its class exist, and that one copy is shared by all instances. Moreover, you can reference a static variable from any instance, or from the class itself. For the following class declaration:
class MyClass {
  public static int i;
}
... if you have an object myObject of type MyClass, you can refer to the value of the static variable i using either myObject.i or MyClass.i.

Similarly, a static function also belongs to its class, and can be referenced from any instance or from the class itself. A function declared static cannot reference the implicit this variable or any instance variables, since it may have been invoked on the class. These types of functions are useful to implement certain important object oriented design patterns, to bootstrap an application, or to write the Java equivalent of library (utility) functions.

Strings
Strings are full-fledged Java classes. You do not normally create a String by explicitly calling a constructor. Instead, you usually start with a String literal, enclosed in double quotes, or you concatenate a value into a String using + or +=.

Strings are immutable in Java, meaning that you cannot change their value after creation. In the following example...

String s1 = "Hello";
String s2 = "World";
s1 += s2;
... the reference s1 is redirected to point to a new String object containing the value "HelloWorld". The value of the old String "Hello" remains unchanged, since other variables might refer to the same object.

This is especially significant when you wish to compare two strings. Keep in mind that String references are object references, not primitive types. Using the == operator checks whether two references refer to the same String object, while the equals method compares whether two strings have equals values. Strings also provide several useful utility method, including equalsIgnoreCase, which compares the strings in a case insensitive way.

Inner Classes
Java provides four different ways to declare a class, as divisions of two main categories: standard classes and inner classes. This section briefly describes the latter category.

An inner class is simply a class defined within another class. The benefits of inner classes may be elusive at first, especially when you consider that some inner classes are not visible outside a localized scope. This usually implies that inner classes are not as reusable, which leads many developers away from using them.

Inner classes perform a vital role in solid Java development, however. Inner classes preserve encapsulation by providing the class access to the private variables of its containing class. There are some who feel that this violates encapsulation, since another class has access to internal state, but remember that the entire inner class is also part of the internals of the object!

Your alternative using standard classes is to pass Object references to these external objects, through which callbacks provide access to state, either as non-private instance data, or through mutator functions that must be made available not only to the external class, but also must be available to the entire package. Inner classes let you keep your data, and even many of your functions, private from the perspective of the outside world.

Of the inner class types, you can define simple inner classes within other classes. You can also define local classes, which are classes defined in the scope of a particular method, and have the added advantage of accessing local data and parameters declared final. Lastly, you can define anonymous inner classes, which are local classes that are declared and instantiated on-the-fly, without assigning a class name. These classes are most often used for event handler adapters in GUI development.

Section 4: Applets

             a.What is a Java Plug-in?
             b.Which JDK tool can be used to sign applets?
             c.Which methods initialize and run an applet?
             d.What are the roles of the CODE and CODEBASE parameters in the APPLET tag?
 

Sections 5 - 7: Using JBuilder

Discussion of the following sections, which cover the JBuilder environment, will make use of the projection system, but the following outline should serve as a guide, and a convenient place to take notes.
The IDE
  • The AppBrowser refers to that portion of the JBuilder environment under the main menubar and toolbars. It is divided into the Navigation Pane, the Structure Pane and the Content Pane.
  • Use the Tool Options... menu item in JBuilder's Tools menu, as shown in the image to the left.
  • To switch JDK's in JBuilder 35, you first have to define the target JDK you wish to switch to. From the Project Properties dialog, select the Paths tab, and click the "Set..." button next to the JDK version text field. This will bring up the option to select your target JDK, or you can click New to define a new target version. Locate the home directory of the new JDK version, and select OK a few times to create the new target and associate it with your project. The version of the JDK you wish to use may impact debugging and deployment, so you will have to keep this in mind.
  • In JBuilder 35, all standard output goes to a tab in the message area of the UI, the execution log is gone.
  • CodeInsight provides information about the methods callable from a specified object and the overridden parameter sets to those methods, in addition to information about syntax errors as you type.
  • The Object Inspector provides information when in the GUI designer about the selected JavaBeans properties and events.
  • To set menu shortcuts, set the mnemonic property to the character that you wish to use to invoke the menu item. To specify a menu accelerator, set the accelerator property to an instance of KeyStroke you have created within the container class.
  • JBuilder 35 libraries associate a portion of your runtime classpath with an alias name that describes the main API's the classpath represents.
  • JBuilder has a compiler option to "make packages stable", which instructs the compiler to build all files in a package, and mark the package "stable". By default, JBuilder will check whether a stable package has changed when determining what to compile on subsequent builds, saving compile time.
  • JBuilder ships with the following command-line tools:
  • JBuilder Command Line Tools
    CD Image Tool Purpose
    Borland JBuilder 3.5 java, javaw, javac, javap, javah, javadoc, jarsigner,
    keytool, jdb, appletviewer, rmic, rmiregistry, etc.
    JDK tools
    DataStore Explorer Browsing and querying the all-Java DataStore
    Borland AppServer gatekeeper, osagent, oad, oadutil, vregedit, printIOR,
    osfind 
    VisiBroker for Java command line tools
Configuration
  • The batch file setvars.bat initializes the command line environment to a similar configuration that JBuilder executes in (specifically the PATH and CLASSPATH environment variables).
  • To make a Java library available to JBuilder designers, you have to add a line to the JBuilder.config file similar to:

  • addjars c:myjars, which tells JBuilder on startup to includes all jar files in that directory in its classpath.
  • JBuilder projects are defined in files with a JPR extension.
  • The following configuration files are provided for customizing the JBuilder environment:
  • JBuilder Configuration Files
    File Name Location Purpose
    Column.properties user profile directory Stores the default properties for creating database column objects of different specified types
    Default.jpr user profile directory Stores the configuration properties used by JBuilder to create new projects
    library.properties user profile directory Stores the definitions of add-on Java libraries for use in JBuilder projects
    palette.ini user profile directory The configuration of the GUI component palette
    propertyEditors.properties user profile directory Stores the association of JBuilder types to their GUI property editors
    tools.cfg user profile directory Specifies the customized options in your tools menu and how to spawn them
    user.properties user profile directory User-customized settings as modified by the options in the Tools|IDE Options... menu
    JBuilder.config JBuilder binary directory Establishes the JVM and classpath used by the JBuilder IDE, dynamically includes jdk.config
    jdk.config JBuilder binary directory Defines the core JVM used by the JBuilder environment
    jdbce.config JBuilder binary directory Configuration for the JDBC Explorer
    dss.config JBuilder binary directory Configuration for DataStore Server
    dse.config JBuilder binary directory Configuration for DataStore Explorer
Keyboard Shortcuts in the Default Keymapping
  • Within the source code, you can explore any class or interface by placing the cursor on the type, or an instance of the type, and pressing CTRL+ENTER. As an alternative, you can also right-click the identifier and select "Browse Symbol" from the context menu.
  • JBuilder 35 does not allow record and playback of simple macros. Instead, set up named macros using Tools|IDE Options|Code Templates. Specify a short name and a description for your template, then type the template into the dialog space provided. To activate the template, type its short name into the source code editor, and press CTRL+j.
  • The source code editor provides shortcuts for creating bookmarks for quick navigation. You can have up to ten per file. To set a bookmark, place your cursor in the desired place, then press CTRL+SHIFT+<a number>. From any other place in the file, you can navigate to your bookmark using just CTRL+<the number>.
  • There is also a shortcut for finding matching delimiters '(', ')', '[', ']', '{', and '}', even with comments and strings. Simply press the ALT key and the left or right square bracket when your cursor is on one delimiter, and it will jump to the matching delimiter.
  • To make a quick clone of a GUI component or a selection, press the CTRL key while dragging. To nudge a component one pixel in any direction, hold the CTRL key when selecting the component(s) and press the arrow key corresponding to the direction you wish to move.
JDBC & SQL
  • A SQL statement may be parameterized using question marks (?) to denote its parameters. Using JDBC, parameterized queries are created using a PreparedStatement. In DataExpress, a normal QueryDataSet will do, but you have to specify parameter values using another ReadWriteRow that you supply.
  • JDBC drivers are vendor implementations of the java.sql.Driver interface that implement connection capabilities to one or more databases. There are four levels or types of JDBC drivers, and they differ based on their architecture and network protocol. Of the different types available, type 3 and type 4 drivers provide an all-Java client speaking over the open network. These drivers are considered portable and deployable with a Java application, as opposed to types 1 and 2, which require client configuration.
Data Express

DataExpress is the database architecture for quickly building database applications in JBuilder. As a thin layer over JDBC, DataExpress provides facilities for filtering, sorting and searching through resultsets that may be cached locally in memory, persisted on disk, or distributed as a serializable Java object. A class hierarchy of the main DataExpress classes is shown in the graphic to the right. The following key points address questions asked in the Study Guide about DataExpress:

  • Among the usability features of DataExpress, there are several methods for navigating through records, including first, next, prior, last, and locate. While navigating, you may also make use of atFirst, atLast, and inBounds.
  • When DataExpress is used, GUI components can be linked directly to a dataset through their dataset property, if available, or you can use any of a set of predefined models and "binders" to associate DataExpress data with third party or standard java components that are not otherwise "data aware".
  • Components that may be directly linked to DataExpress data have icons with small gray grids in their backgrounds. Those that manipulate only a single column of the dataset have a columnName property.
  • DataExpress includes a Java interface called DataModule, which allows developers to use the JBuilder visual designers for non-visual components. As a tag interface (one with no method requirements), any class could implement DataModule.
  • A master-detail relationship is established to represent a one to many relationship in the resultset cache in which the values on the many side are trimmed to just those corresponding to values on the one side. To establish the master-detail relationship property, set the masterlink property of the detail dataset.
  • Certain master-detail relationships can be set up to use "delayed fetching". Setting this property instructs the detail dataset to fetch records only when required to support the relationship with the master dataset.
  • By default, storage datasets persist their data to a block of physical memory. You can redirect this storage to a JDataStore to persist the data to your file system instead. Using JDataStore results in a slight degradation of performance for small datasets, but tends to be faster and require less memory when working with larger datasets.
JavaBeans
  • BeansExpress is a series of editors that provide easy-to-use features to write beans conforming to the JavaBeans specification.
  • Within BeansExpress, you can define properties, event sets, editors and customization information for a JavaBean you are writing.
  • JavaBeans properties are implemented by optional accessor and mutator methods, often called "getters" and "setters". Properties may also be "bound" or "constrained", which signifies that changes and attempts to change to property values will fire events, allowing external notification and validation, respectively.
  • JBuilder is able to determine the properties and events of a JavaBean using introspection of the class members. Introspection provide meta-information about the member of a class, and if the class compiles with JavaBeans standards, a GUI builder tool can interpret which methods correspond to properties, providing the appropriate property editors.
  • There are times when the bean itself is not enough to correctly manipulate properties in JBuilder. In some cases, you will associate a BeanInfo class with your bean that more comprehensively describes its features. A BeanInfo class may specify customized property editors for your bean, bitmaps for use in JBuilder's component palette, tooltip text for each property and event handler method, method descriptions, etc.
  • Property editors provide GUI developers assistance in setting property values, by representing those values in English terms, by using visual metaphors like lists, dialogs or colors, or any other information related to the property.
  • Using JBuilder, you can also create Enterprise JavaBeans. The types available include both session and entity bean types.
(back to intro)

Certification Program and Benefits

Product certification is a vital part of the Borland Enterprise Solutions Program (ESP). This section outlines the certification requirements for developers and technical instructors, concluding with a description of some of the benefits of the ESP program for certified individuals and their employers. The ESP program focuses on five groups of partners:
  • Systems Integration Companies
  • Technical Education Centers
  • Tool and Component Developers and Development Companies
  • Technical Instructors
  • Individual Developers
Our first look at certification involves certification as a developer, then we will look at additional requirements for instructors.

Developer Certification

First, the exam... The JBuilder 3 Client/Server Suite Foundations Exam is available at Sylvan Prometric testing centers worldwide. The cost of the exam is $250 US. There are 100 questions on the exam, and a passing grade is 80%. Candidates are given two hours to complete the test. Sylvan may be contacted to schedule an appointment to take the exam by calling 1-800-430-3926, referencing test number 9J0-009.

After successful completion of the exam, you will be Borland Product Certified. You will receive an official plaque and be granted the use of a logo as evidence of your qualifications to show to employers and customers. Your certification positions you to meet increasing customer demands for qualified service providers and sets you apart from other developers in your field. Certification also verifies the specific knowledge and skill you brings to a job, and the credential becomes increasingly important as skill demands for IT professionals change rapidly.

There are also benefits to your organization, which can effectively distinguish who has the skills needed for particular technical jobs and more efficiently recruit, train, and deploy technical staff.

Instructor Certification

Through the Certified Borland Instructor Program, Borland has established requirements for instructors of Borland products to ensure consistent, high-quality teaching for customers. Becoming a Certified Instructor is both a personal and professional achievement. Individuals who achieve certification have demonstrated that they possess a rare combination of thorough product knowledge and excellent teaching skills. This pool of training talent is available to Borland and its customers to address the needs of the Borland customer base. Only Certified Instructors are qualified to license and teach official Borland courseware.

In addition to passing the Borland Product Certification exam for JBuilder, it is the responsibility of prospective certified instructors to be sure they meet the following prerequisites:

  • A working knowledge of Java
  • A working knowledge of another database programming platform (e.g. Visual Basic, PowerBuilder)
  • Development experience for one of the following SQL database servers:

  • InterBase 4.x/5.x, Microsoft SQL Server, Sybase, Oracle, Informix, or an ODBC-supported server.
  • Recommended reading: Java in a Nutshell, David Flanagan, O'Reilly Press, 2nd Edition, ISBN#1-56592-262-X, Chapters 1-10
Instructors must also attend a 4 day Train-the-Trainer before their certification is complete. The class fee is $1,000 for instructors new to a product, or $500 for instructors renewing certification on a new version of the same product family. The class focuses on teaching techniques as well as courseware changes and errata. Intense teach-backs also serve to verify the candidate's product knowledge and teaching skills. Much of the attention revolves around successful methods for teaching the product itself. Individuals are required to pass a written product certification examination during the class to become certified. A copy of the Instructor and Student materials is included in the cost of the class.

It is recommended, though not required, that an instructor attend the applicable product Foundations class before attending a Train-the-Trainer class. By taking the class at least once, it is hoped that prospective instructors learn more about the scope and flow of the class, as well as trouble areas and points of confusion for real students.

Finally, all certified instructors must sign a contractual agreement with Borland which details the responsibilities of both parties. Their employer must also complete and Authorized Education Center application before open enrollment classes may begin.

Benefits of the ESP Program

The Enterprise Solutions Program delivers a complete and flexible set of essential services, including technical services, products, sales and marketing support, and partner communications to Borland partners. Services vary by partner category:
  Technical Services
  • Discounts on technical support (dependent on partner category)
  • Authorization and/or certification for applicable Borland products
  • Discounts on technical training and conferences
  • Monthly Technical TeleForums
  • Train-the-trainer sessions for qualified ESP Partners
  • Free technology briefings
  • Product Benefits
  • Discounts on development and deployment software
  • Free product for interoperability testing
  • Free product for prototyping and educational purposes
  • Early access to beta/gamma releases
  • Sales and Marketing Support
  • Opportunities to work with the Borland sales organization
  • Sales training opportunities
  • Promotion in the Borland Online Partner Directory
  • Case studies
  • Lead-sharing
  • Sales and marketing guides
  • Presentation materials, product demos, and collateral
  • Partner Communications
  • Borland Partner Handbook
  • Password-protected, partners-only Web site
  • Quarterly newsletter
  • Early product information
  • (back to intro)

    Summary

    In this tutorial, we covered the requisite information for JBuilder certification as outlined in the current version of the JBuilder Certification Study Guide. While this paper detailed fundamental Java information in prose, specific JBuilder details are not explicitly written, but were bulleted in this paper and discussed in greater detail by the presenter. If these topics alone are insufficient to successfully take and pass the JBuilder certification exam, they should be sufficient to prompt further study into a candidate's weak areas and provide a list of study areas before attempting to take the exam.

    JBuilder certification, especially as an instructor, is a privilege and an honor, rewarding an individual time-and-again with esteem from peers and pupils alike. The Borland certified community is a high-profile assembly of developers and technology evangelists, a close network of business professionals who interact to increase visibility, knowledge and opportunity for their companies. Some travel around the world teaching and mentoring, others have authored popular technical resources, and still more are executives and founders of startup and mid-size training and consulting organizations.

    To close, let me just add that I hope today is the day that you join our ranks. Speaking for the certified development community, I believe that I can safely say, we would love to add another to our ranks and to take the opportunity to leverage your knowledge and experiences as our community grows in support of Borland development tools and platforms.

    (back to intro)

    About the Author

    Kenneth Faw is the executive vice president of PILLAR Technology Group, a Borland ESP Partner and Authorized Education Center for five years. Ken is certified as an instructor in JBuilder, VisiBroker, Delphi, and C++Builder, and frequently speaks on distributed technologies and Java. He has delivered presentations at the last two Borland conferences, as well as panel presentations at Comdex.

    Paper originally presented at the 11th Annual Borland Conference, July 2000.

    Server Response from: SC3