Sun's J2EE: The Standard for Developing Multitier Enterprise Applications

WITH THE RELEASE of its Java 2 Enterprise Edition (J2EE), Sun Microsystems has staked out some serious territory in the enterprise. As readers of Java Report are sure to know, J2EE is a standard architecture definition using the Java language. More specifically, J2EE is a framework that defines a standard for developing multitier enterprise applications. It simplifies enterprise apps by basing them on standardized, modular components, and it provides a complete set of services to those components. J2EE is built on features from the Java 2 Standard Edition (J2SE). In J2EE, Sun has added support for EJB, the Java Servlet API, and JSPs.

The complete list of J2EE technologies is a long one. It includes:

  • Enterprise JavaBeans (EJB) Architecture
  • Java Server Page (JSP) technology
  • Java Servlet API
  • Java Naming and Directory Interface (JNDI)
  • Java Interface Definition Language (IDL)
  • Java Database Connectivity (JDBC)
  • Java Message Service (JMS) specification
  • Java Transaction API
  • Java Transaction Service
  • JavaMail API
  • An implementation of the Java RMI API over IIOP
In this issue, Todd Zino and Frank Flowers take a pros-and-cons look at three of J2EE's key technologies: JDBC, the JMS specification, and JSPs. In a related article, David Reilly examines J2EE's support for the Object Management Group's (OMG) Common Object Request Broker Architecture (CORBA) as an alternative to remote method invocation systems.

In future issues, we will take a closer look at other components of the platform.

—John K. Waters, Product Editor

JDBC: A Growing Legacy?

How will the new JDBC fit into the grand J2EE scheme?

Todd C. Zino

IT SEEMS AS though an eternity has passed in Web time between the debut of JDBC and the new updates that are just now beginning to appear in the Java 2 Platform classes. During that time, most developers became more involved with the various third-party packages and Beans to handle the complex enterprise-grade database tasks that the java.sql library lacked. JDBC was simply a primitive underlying layer to initialize a database connection and maybe execute a statement or two.

JDBC 2.0 has been available for some time now, and Java J2EE is making its grand splash. A new set of features has been added in the javax.sql package (known officially as the JDBC 2.0 Standard Extension API). Of course, vendors are only now starting to support the wealth of core 2.0 extensions: scrollable ResultSets, better object/stream/SQL3 type support, and inplace updates. The big question many developers and planners are asking is, how will the new JDBC fit into the grand J2EE scheme? Moreover, how will it fit into an enterprise world that is still highly entrenched in previous versions of Java and the aforementioned proprietary products?

For the most part, the new extensions in javax.sql are essentially tie-ins to the highly touted pan-J2EE technologies (more than they are brand new "features")—which is far from a bad thing. The majority of new J2EE classes are geared to smoother data access and stronger middleware. The primary J2EE additions are a new DataSource interface (for use with JNDI) and RowSet (basically a Bean wrapper for ResultSet). There's also connection pooling and distributed transactions, which are new to JDBC. However, these are primarily for vendor drivers rather than user code, and initially they will be competing with the vendor classes that provided this functionality in the pre-J2EE universe.

Improved DataSource
The DataSource interface is essentially a factory for java.sql.Connection objects. Its principle use is with JNDI, where it replaces the old URL and DriverManager way of establishing database connections. The real power here is in the interface's ability to let JNDI's InitialContext class handle the naming service, configuration, login, and other auxiliary administrative stuff that should be dealt with centrally by middleware rather than spelled out in each connection instantiation.

When a connection is necessary in the data access code, you can simply create a new DataSource object, an InitialContext, do the lookup on the desired database, and call DataSource.getConnection(). It could not be simpler, and its implications will, I hope, go beyond trivial connection code when developers learn to harness the J2EE notions of deploying data sources dynamically after all the code is tested and written. Further possibilities may abound when the emerging Lightweight Directory Access Protocol (LDAP) type protocols become the de facto way of centralizing data access.

A Jumble of Connections
On the other hand, the interfaces and guidelines for connection pooling and distributed transactions (via the Java Transaction Architecture (JTA)) run a schizophrenic line between misleadingly simple and potentially confusing. It should be noted that most developers can get away with simply getting the connection from the DataSource—and you must use DataSource rather than DriverManager to initialize the connection for pooling and JTA to work.

If the vendor's driver supports connection pooling, the new connection will automatically be part of a pool. The same is true of distributed transactions. The idea behind this is to make DataSource the focal point of the vendor-specific implementation details. This is a noble pursuit. The problem lies in what is not explicitly declared in the code, and somewhat ironically, what is implicitly declared in the invisible DataSource layer that actually handles pooling and transactions.

When a DataSource is initialized that supports distributed transactions, the connection's auto-commit is automatically set to off, in stark contrast to normal DriverManager and non-XADataSource connections! For all of the MetaData methods in the JDBC 2.0 package, there is no Boolean function to determine whether or not a connection is part of a pool or distributed transaction. For this very reason, the commit() and rollback() methods should never be called in this code. In other words, the code should be kept basic for connections and transactions, with the deployment Beans and vendor drivers carefully set up so that you know what you're getting in DataSource's enterprise capabilities.

There are XADataSource and ConnectionPoolDataSource interfaces in the package, although documentation strongly recommends that these be used only by vendors for implementing these features. When using pooled connections, the obscure finally{} block should be added under the inevitable SQLException catch{} blocks to explicitly close the connection with a null test.

There's an inherent paradox in JDBC's hype for these new enterprise connection and transaction features: While they are "supported" now in JDBC, most of the design guidelines point right back to their being hidden in the vendor's driver spec. At some point, there's little difference between a JDBC driver and the same vendors' various beans and Java-based middleware that already provide these features; both require money investment in a proprietary product. This makes a majority of JDBC's new enterprise like the emperor's new clothes, but the addition of standardized, core package code is certainly all gain and no loss.

Beans Come Home to JDBC
One of the more intriguing additions in the J2EE package is the RowSet bean. A subclass of the new and improved JDBC 2.0 ResultSet, RowSet provides all the functionality therein as well as the expected JavaBeans component methods for registering and listening on events. The principle advantages of this (aside from the ability to be easily loaded into IDE tools and middleware brokers as a genuine component) are the caching and transfer of RowSets across the network and even onto local storage, and the ability to have database events trigger updates elsewhere in the application.

Sun has released a prototype of CachedRowSet, still in developer preview at the time of this writing. This Bean in particular is designed to give an easy means of opening and closing a connection to a DataSource and saving the results in memory (which can also then be serialized to disk in instances of remote access where updating client data on the go is desired).

RowSets can easily be implemented as EJB by wrapping the appropriate interface code and managing the EJB properties. This brings it up to par with the other J2EE deployment architectures, and allows for transaction specifics to be handled at that level. More than the DataSource connections, RowSet can be explicitly extended and customized by middleware developers to suit their needs. It remains to be seen if JavaSoft will provide for more reference Beans than CachedRowSet. As with most of the javax.sql, however, there are currently quite a few cached row classes and Beans on the market that may shorten development time for those looking to deploy ASAP and willing to spend the cash.

Recommendations and Analysis
Overall, the key JDBC changes are not found in the J2EE Standard Extension but rather in the jump from 1.x to 2.0, which is still maturing in vendor drivers despite having been out for some time now. Unlike a lot of the GUI and utility enrichments to Java 2, JDBC is of course only as good as the driver and DBMS you're using with it. With that said, the foundations laid by J2EE and its interfaces in JDBC are a great step in the right direction. They put an emphasis on middleware that can be reconfigured, while letting the developer retain the same code for data retrieval and updates.

One issue that might arise for those currently deploying enterprise Java is the lack of a clear migration path. Although JDBC has been constantly designed for backward compatibility, new J2EE interfaces have not. Some of the transaction-specific code might not work under connection pooling or global transactions. Nothing is ever too simple when trying to bridge the gap between relational SQL data and Java objects; you still need to exercise precision to ensure you are not declaring details in their code that are in direct conflict with how their DataSource, JNDI registrations, transaction beans, etc. are currently being deployed.

A few further modifications to the JDBC standard might be useful. A universal EJB framework for basic stored procedures and updates (the latter similar to the concepts behind RowSet) would be nice. Likewise, additions to the fields associated with ResultSet, Connection, and (especially) DataSource that would allow explicit granular control or overriding of properties such as result retrieval deblocking, connection handling, etc. similar to the TRANSACTION_* fields that currently exist. Although shielding most of this from the developer is a noble goal, there are still instances where it's desirable.

Database server products tend to be the biggest and most crucial investment in any enterprise application. That fact will probably ensure a continued tug-of-war between open Java standards and highly specific vendor implementations with their sundry extensions. As I've already said, there's a commercial product out there that has all of the included and desired features of JDBC 2.0 and the Standard Extension. I hope that, as Java continues its maturity as an ideal language for server and middleware, the standards it builds into the core libraries will continue to be supported across databases.

JMS: A New Enterprise?

Java's advantages over the fragmented native C/Java APIs

Todd C. Zino

"EVERY DAD NEEDS a MOM." So goes the pun in the fringe (yet growing) realm of Message-Oriented Middleware (MOM) for Distributed Application Development (DAD). In the struggle to seize this new technology, JMS may be Sun's ace in the hole. JMS gives current MOM vendors a common specification that fits quite well into the J2EE picture, and gives developers Java's advantages over the fragmented native C/Java APIs. At press time, IBM's MQSeries, BEA's WebLogic—and even Sun itself—have all released JMS Providers.

Let's start by clearing up some misconceptions that may have arisen from too hasty a look at JMS. The specification is frequently compared to RMI, when in fact it is nothing like the synchronous IIOP-bound method of process communication. It has even less to do with JavaMail, although many of the abstract notions of recipient, header fields, queuing, and delivery have much in common with the age-old SMTP Email model. In other words, JMS is an asynchronous way of dispatching and receiving chunks of data ("messages") from Provider middleware with a guaranteed delivery. Its potential is far-reaching in a brave new world of enterprise components that rely on dataflow and notification between Beans, without the overhead of CORBA and blocking on a response that is not immediately needed. The closest analogous product in the current Java realm would be JavaSpaces, but even that is not entirely accurate.

As for what goes into the actual "message," JMS, and MOM in general, is primarily designed for messaging between actual components rather than human-readable messages—which is not to say that the latter are without valid application. Indeed, MOM can easily be used for sending server bulletins to administrative or client users by having the incoming message trigger a dialog box to display it. The true power comes in JMS's ability to send bytestreams, name-value pairs, and any encapsulated Java objects across components. The actual MOM Provider you choose handles the routing, delivery, and network transfer of the messages. JMS has a core specification (currently at version 1.0.2) that vendors are required to implement to ensure basic interoperability and common interface.

For the purposes of testing, I decided to go with IBM's MQSeries, because of its free trial download and richly documented API for the JMS extension. It also provides a Java API for non-JMS access, perhaps devised when JMS's future seemed uncertain. Many mature MOM Providers have native APIs as well, and JMS was designed in part to make messages developed by either of these two interoperable, maybe more so than JMS messages developed across two different Providers.

JMS is mostly implemented as a series of interfaces, with Connection and MetaData calls quite similar to the JDBC model. While the javax.jms package is part of J2EE, much of the actual implementation is at the mercy of the Providers. If this sounds similar to the growing pains of JDBC, it doesn't stop there. The notions of Connection, Session pools, data storage, and XXX as implemented in JMS will be very easy to absorb for java.sql stalwarts. JMS even requires the SQL-92 syntax for querying sent and received messages, although this will seem like tedious overkill in most practical uses.

There are currently two primary implementations of messaging: point-to-point (PTP; JMS interface name prefix "Queue") and publish-and-subscribe (Pub/Sub; prefix "Topic"). As the names suggest, PTP is similar to direct email with another person, while Pub/Sub is similar to a newsgroup. The critical JMS abstract interfaces are subclassed for each of these two message types.

A lot of the terminology conventions around messaging are confusing until you get used to them, primarily because of the lack of a traditional client/server model in the MOM paradigm: Connections, Sessions, Properties, Producers, Consumers; all are ambiguous if not for their context in the JMS API. A Connection is the primary interface to the messaging Provider and is designed to be shared across multiple threads in a messaging application. In keeping with the overall J2EE vision, JMS is largely intended for use with JNDI for Connections. JNDI is also the easiest way to specify destinations for the messages. If you don't use JNDI, you'll have to rely on the Provider-specific classes (where such exist) for handling connections and addressing.

Sessions are created from Connection instances, but keep in mind that they are not designed to be threadsafe. Only one logical thread should ever have access to a Session, and it is the developer's responsibility to ensure this in the code. MessageConsumer objects receive messages from the Provider, while MessageProducer is used to create and send messages. These are both also designed for use by only one thread.

The difference between Headers and Properties is sketchy at times, but suffices to say that Headers are the basic parameters of message delivery (Destination, Type, Priority, MessageID, Timestamp, etc.) that can be accessed with hardwired Message methods. Properties are more detailed and often Provider-specific settings that are put into the message. These can be read and set with the getXXXProperty/setXXXProperty method calls, where XXX is the primitive value type of the property. Annoyingly, properties can only be cleared in bulk, not individually.

JMS provides five base types for actual message bodies: BytesMessage, MapMessage, ObjectMessage, StreamMessage, and TextMessage. MapMessage, the only non-self-explanatory type, is for the name-value pairs. These also adhere to the get/set convention for loading and reading.

The enterprise notions of JMS come into play with the actual receiving and sending. JMS ties in with the JTA package for XAConnections and XASessions. This is functionally equivalent to creating a regular Connection with the "transacted" Boolean asserted. This gives a context for grouping multiple Connections as an atomic transaction unit where such is desired.

Although JMS is an asynchronous technology, clients have the option of explicitly calling the Receive() method of MessageConsumer subclasses. A more sophisticated approach is to create a class that implements the MessageListener interface and define the onMessage() method as the event handler for incoming messages. An ExceptionListener would probably be a good idea to add in this case; otherwise the application will have no way of catching JMS Exceptions.

The last noteworthy interface of JMS is the Message Selector. This is how messages can be identified, filtered, and acted on by the code itself, based on using SQL-92 syntax to search on any value or part of the messages. It's a bit bulky to pick up at first, but makes sense where there are tons of messages to sort and selecting the appropriate messages requires knowing more than just one property field.

It would be nice to see some enhancements in future JMS implementations—most notably including universal EJBs in the package. If any Java component was destined for "Beanification," messages are certainly it. Being able to grab any database, class, or other visually represented object in an IDE and immediately build a JMS message for it would surely be a level of karma for no-nonsense middleware RAD. ProSyst Inc. has already taken steps towards this, but the lessons learned with JDBC drivers and transaction middleware might apply in getting a universal standard implemented before it becomes a vendor-dependent pay product.

While JMS is obviously an attempt to expand the language to an evolving niche, there are many key gains for both MOM and Java. There are more than a few enterprise scenarios out there that rely on too much overhead from object brokerage and all-or-nothing resource-intensive transactions, which could be more streamlined using JMS to notify other processes of impending updates.

The human-to-human factor is not to be entirely overlooked either. Workflow architectures that require critical data being propagated to different departments and DBMS servers could certainly benefit from a JMS-based model where administrators could fire up their data approval app and get the latest "messages" on which entries need approval. This notion could be extended to DBA and systems administration in general, for which most notification systems are glorified dialog boxes or boilerplate emails that lack JMS's ability to have interactive application actions and further enterprise responses tied to the message itself.

In the grander scheme of enterprise computing, messaging may prove to be as fundamental to the architectures as CORBA and relational databases are right now. When compared to the functional and syntactical awkwardness of the latter in their infancy, JMS is certainly off to a promising start in becoming an easy-to-develop standard.

JSPs: A Child Prodigy?

What is a JSP? Should I be using it for enterprise Internet development?

Frank Flowers

DEVELOPING NEW SYSTEMS is somewhat like raising children; only you probably spend more time with the project than you do with your kids. I've seen some unruly projects that, without proper discipline, became terrifying brats no one wanted to go near. A critical factor in the formula for successful completion of projects is the technical infrastructure. Good parents usually tell their child to be careful when choosing friends, because friends have a big influence on how the child develops. Likewise, most projects are greatly influenced by the tools used to develop them. As developers, we should be careful which tools we allow our projects to associate with.

Children of the Sun
There are some Web application development tools out there that have just plain grown up ugly—CGI, Perl, Visual Basic, and ASP to name a few. Java, on the other hand, started out as an appealing baby with its cute little applets, and reached an endearing early childhood and adolescence with JDK versions 1.1, 1.2, and the new 1.3. The technology has matured a great deal with the J2EE, a collection of existing Java APIs and standards. Perhaps beating my analogy until it cries, several brothers and sisters make up the Java family. I focus here on one of them: JSPs. This article is for those of you who have contemplated using JSP and read about it but haven't done so yet. I've purposefully stayed away from including any code to focus on concepts. This is not a JSP tutorial but rather a discussion of JSP technology. It'll answer the questions: What is a JSP? How does it compare to the alternatives? Should I be using it for enterprise Internet development?

Children of the Corn-y
Before we look closer at JSP, let's consider some of its predecessors. The Internet was originally designed for static pages. To help make it more dynamic, CGI programs were used. These programs had a number of disadvantages that were overcome by Java servlets. The benefits of Java servlets over CGI have been well documented and include the following: CGI applications are platform-specific, do not scale well, and, unlike servlets, a new process must be created each time a CGI script is invoked. I'm still surprised, however, at how many people use Perl and other languages to create CGI scripts. I see this most often done by non-programmers who branch out to do some coding but who lack Java training. Still, I don't consider CGI a serious contender for any enterprise projects. If we compare Web development technologies to the houses built by the three little pigs in the famous children's story, CGI is a house made of straw. The first strong wind might knock it down, and I'd hate to have to maintain it.

Servlets are a step up from CGI programs, but they don't separate the presentation (HTML-based GUI interface) from the business logic. The HTML in servlets is often crude and difficult to maintain, and requires a programming change every time some aspect of the page needs a minor tweak. Anyone familiar with this process of mingling HTML with code knows that it's a bit like mixing oil and water. The oil is ruined and you sure don't want to drink the water. You may still want to use servlets for non-HTML tasks, such as extending a Web server's functionality or generating dynamic images and other binary data. When compared to the three pigs' houses, using servlets is analogous to using sticks. It's much better than straw (CGI), but is not as durable as you'd like.

Another option might be Microsoft's Active Server Pages (ASPs). Many people have pointed out that JSP seemed to be Sun's response to ASP, and are similar even in name. If you're a Java developer, you probably don't have a lot of interest in learning ASP just so you can write scripts in another language to run on the Microsoft platform, IIS on Windows NT/Windows 2000. (ASP can run on other platforms with add-ons.) It's a bit like learning to square dance so that you can go to a modern country and western club. Don't bother. Object-oriented Java is more powerful than the ASP scripting language and has the advantage of cross-platform support. JavaBean components are easier to develop than COM objects and may be distributed across several different servers without having to be recompiled. ASP offers limited data persistence across pages, while JSP pages can share data by accessing the same JavaBean. ASP can't call methods outside of the page as JSP can. Plus, ASPs must be interpreted on each iteration, while JSPs can be precompiled and cached on the Web server. Finally, although both ASP and JSP can be cluttered with code on a Web page, only JSP allows the code to be removed from the page by using tags to refer to JavaBeans. As we'll see later in the article, this separation of presentation from business logic is essential to good application design.

Another possibility is templates. In a January 2000 article at,* Jason Hunter tried to make a case for using template engines. Some readers disagreed and found his arguments weak, as he reports in a February follow-up article. Even Mr. Hunter lists three major problems with templates: 1) No specification exists for how a template engine should behave, 2) template engines aren't widely known, and 3) template engines have yet to be highly tuned. I've had neither the time, opportunity, nor interest to work with template engines; I prefer to go with a more widely used and supported standard than to settle for a little-known solution from a small vendor. You can explore the template option further if it interests you.

JSP and the other options just mentioned are candidates over applets because they are faster (no long initial download time) and don't have such compatibility problems (because Java is executing not on the client, but on the server). Of course, you wouldn't use JSP if you had to have a heavyweight client interface. J2EE allows for both applets and JSPs.

If I want to keep the presentation logic separate from the business logic, and I don't want the drawbacks of applets, ASP, templates, CGI, or pure servlets, then a viable option is JSP used with EJBs and HTML/XML.

"Gotcha": Things to Watch For
If you try to start the J2EE server as the document "Writing Enterprise Applications with Java 2 SDK, Enterprise Edition" tells you (j2ee - verbose) you may receive the following usage statement:

Usage: java [-options] class [args...]
      (to execute a class)
  or java -jar [-options] jarfile [args...]
      (to execute a jar file)
If that happens, the problem lies in trailing slashes on some two path variables: JAVA_HOME and J2EE_HOME

This produces the error:

The following corrects the problem:

(Thanks to Antonio on Sun's Java forum for posting this fix.)

Starting and Stopping Servers
You start all the servers from the j2sdkee1.2\bin directory. To start J2EE, enter "j2ee -start". To start CloudScape, enter "cloudscape -start". But, you can also shut them down gracefully with "j2ee - stop" and "cloudscape -stop".

How Do You Uninstall an Application?
In Windows, I kept getting an error saying "ConverterAppmust be uninstalled before it can be redeployed." [ConverterAppmust is missing a space.] But, I couldn't find an uninstall button. Several newsgroup posts said to enlarge the deploy tool application window. I clicked on the maximize button, but there was still no uninstall button. Then, I pressed the button again to return it back to its original size, and "Voilà!" There was a new dialog portion on the bottom of the application window with an install button.

You can uninstall an application from the command line:

deploytool -uninstall <application name> <server name>

See Helpful Links sidebar.

Children of the Components
J2EE is made up of the three C's: components, containers, and connectors. System vendors implement containers and connectors. To the application developer, J2EE is all about cooperating components. J2EE is touted as faster development for e-commerce applications because the application model encapsulates the layers of functionality in specific types of components. Business logic is encapsulated in EJBs, reusable components that can be accessed by client programs. Enterprise beans run on a J2EE server, which functions as a middle-tier server in a three-tier client/server system. (More on that later.) The EJBs can be custom-built or purchased from a variety of vendors. How would your development time be affected if you could assemble most of your customized e-commerce site with prebuilt components? Also, the client interface can be accomplished through various methods, including JSP.

JSP is an extension to servlets that runs on a Web server to generate dynamic Web pages. It is essentially an HTML document, with special JSP tags, that is compiled into a servlet. If the JSP tags are used to call EJBs, then the business logic is separated from the HTML. Thus, a designer can create HTML pages and give them to a developer who could modify them to call EJB components. At last, we have a house made of bricks!

After downloading and installing the J2EE SDK, you can start writing and testing JSPs. (This is recommended for Windows NT/2000 and Solaris. If you're using Windows 95 or 98, the J2EE is not supported. You'll have to download the Java Server Web Development Kit [JSWDK] and use it with JDK 1.1.x or 1.2.) The J2EE server that comes with the SDK is helpful if you just want to learn about J2EE and code some things on your own, but it's not meant to run an Internet site. For that, you'll probably want a commercial application server.

Because J2EE is a Sun Microsystems' brand, not a product, you will need a Java application server that has been certified as J2EE. Any list of certified servers will be obsolete by the time you read this (because of the lead time necessary for publication), but you can check with your preferred vendor to see if they have met the compatibility tests. You can also use the free Apache server with Tomcat, the Apache Software Foundation's open source reference implementation for servlets and JSP. Components of J2EE are subject to Sun's J2EE Compatibility Test Suite (CTS), which helps ensure that EJB components, JSPs, and servlets that run on one vendor's J2EE branded configuration will run on every J2EE branded configuration. Or at least that's the theory. The J2EE specification leaves some details up to vendors, and there is no guarantee that a J2EE system developed using one vendor product will port to another product without modifications.

An application server vendor that also has a Java IDE/ADE may ship with some samples, but Sun provides a J2EE example as part of its BluePrints series—a set of documentation and examples for developing and deploying component-based enterprise applications using J2EE. The BluePrints download includes a business-to-consumer example called the Java Pet Store Demo. Also, you may want to work through the Java 2 Enterprise Edition Developer's Guide. I've read more interesting things on cereal boxes, but it will help you learn about J2EE, EJB, and JSP—if you can stay awake. The deployment tool is not as robust as I would expect; I encountered several uncaught exceptions while working with it. It would have been helpful to receive more user-friendly messages, but I expect that most professional developers will end up using a vendor's J2EE product to do serious application development.

There are two basic ways to create a JSP: 1) Java code embedded in the HTML (called scriptlets) and 2) JSP tags. These can be custom tags or standard tags used to call JavaBeans. The ability to use custom tags allows vendors to extend the JSP tag language, something that can't be done with ASP.

Embedding code into your HTML gives you the full power of the Java programming language, but doing so takes away from one of the primary reasons for using JSP in the first place: to separate your presentation layer from your business logic. Therefore, I don't think a well-defined application would normally embed business logic within Java code on an HTML page, although there might be times when it is used for simple things like prototypes. That leaves the second alternative.

Web page designers with a bit of training on how to code the appropriate JSP tags can create JSPs without having to know Java. Developers can create business logic by writing JavaBeans. Also, vendors can create off-the-shelf bean packages that reduce development time. The beans' machine-readable format supports visual editors and development tools. Visual development tools (IDEs/ADEs) with beans can be used to build JSP components and pages, reducing development time even more. The finished product should be portable not only across different platforms but also across multiple J2EE application servers. The division of components logically leads to a division of labor among skilled professionals.

Using components affects the application's design. The J2EE Application Programming Model presents variations of the Model-View-Controller (MVC) Architecture—see Figure 1. (If MVC is new to you, then you may be interested in knowing that it appears to have originated with Xerox PARC Smalltalk-80 in 1987, was adopted by the developers of the Apple Lisa and Macintosh, and has been used extensively since then.) Simply put, an application is divided up into three main parts. The presentation, or user interface, is handled by the View. The program control that handles events is the Controller. And, the data is handled in the (data) Model. You can read more about it in Design Guidelines for J2EE, part of the BluePrints download mentioned earlier. The important point here is that JSP with EJB is an essential part of the MVC Architecture implemented in J2EE. It facilitates the division of work units and labor to create standard multitiered enterprise applications that deliver information to a diverse set of clients. This is what makes J2EE a preferred development platform for scalable, robust, flexible, and secure Internet applications.

Figure 1
Figure 1. MVC variation.

Children of the Flowers
My last name is Flowers, and my wife and I have two little flowers in bloom. My youngest girl is a little more than a year old. She's more than cute; she's adorable and is one of the happiest babies I've ever seen. My nine-year-old daughter is not only pretty; she's smart and has a tender heart for everyone. I could tell you about my precious girls and even show you photos, but you would say I'm biased and you wouldn't really appreciate them much until you spent some time with them.

The same can be said for JSP as a child of J2EE. I can tell you about it, but until you use it on a project, you probably won't appreciate what it can do for you. I encourage you to use JSP on your next Internet development application. In time, you may become the proud parent of a successful JSP project and, more importantly, get to spend additional time with your biological children.

Helpful Links
Main Sun Links Comments URL
JavaServer Pages main Sun JSP page
J2EE Download download J2EE SDK
Other Sun Links    
Sun BluePrints J2EE examples
Compatibility Tests compatibility discussion
Comparing JSP & ASP from Sun's point of view
Enterprise JavaBeans main EJB page
EJB News Archive search for EJB help
J2EE News Archive search for J2EE help
J2EE Tutorial by Monica Pawlan
JSP Developer's Guide looks stale
JSP Syntax Card quick PDF reference
JSP Tags tag syntax reference
Servlets main servlets page
XML and Java Sun's Java XML page
Java Pet Store Demo
(Sample Application)
must login to Java Developer ConnectionSM
Non-Sun Links    
Intro to JSP IBM's tutorial
JSP FAQ not sure it's current
JSP for ASP Developers even-handed approach
*"The Problems with JSP" Jason Hunter's comments
"Application Programming in Smalltalk-80" orginally described the MVC in Smalltalk
"Apache Tomcat Servlet and JSP Development with VisualAge for Java" by IBM's Sheldon Wosnick
Helpful Hints
As you code and test JSPs with Sun's servlet engine, you'll find that you have to restart the server every time you change your code. Some commercial products don't require this. VisualAge for Java offers a more productive way to develop servlets and JSP files. When you change a method in the servlet, VisualAge for Java incrementally compiles only that modified method of the class, not the entire class, and hot-links it into the running program. You can modify your code and you don't even have to stop the program, much less the server, to see your changes take place because VisualAge for Java uses incremental compilation. IBM's Sheldon Wosnick says that this has been tested using Tomcat with VisualAge for Java, Entry Edition Version 3.0.


The marriage of RMI and CORBA technologies?

David Reilly

LARGE-SCALE ENTERPRISE systems frequently call for a distribution of system services across corporate networks. The cost of one central server that could run all of your business processes, legacy systems, and databases would be prohibitive—not to mention risky if the server died. A distributed approach shares the load across many systems, and also the risk; if access to one system is not available, your Web portal or online superstore doesn't need to shutdown for repairs. The Java programming language gives developers the luxury of choice by providing two distributed systems technologies to choose from: RMI and CORBA.

Choosing the Right Distributed Architecture
The choice of which distributed systems technology to employ in Java is a controversial one. Many developers are die-hard fans of Java's Remote Method Invocation (RMI) technology, which is used to make method calls on objects running under a foreign JVM hosted on a different machine. RMI certainly has its advantages, but also has an Achilles heel—lack of interoperability with non-Java applications. The competing system to RMI is the popular CORBA, developed by the OMG and later adopted by a huge range of software vendors and organizations, including Sun Microsystems, Rational Software, Microsoft, and America Online/Netscape. Billed by the OMG as "The middleware that's everywhere," CORBA offers much the same functionality as remote method invocation, but with a difference. CORBA acts as middleware, allowing software to call on the services of other systems by making remote object method calls. The big advantage with CORBA is that it can be invoked not only from a JVM, but also from any other language for which a CORBA implementation exists (including legacy C++ or Ada applications).

How Does the CORBA Distributed Object Architecture Work?
CORBA uses a fairly simple mechanism for communication between software applications. It creates an interoperable system that abstracts away all the details of implementation, such as the operating system and language in which a service is written. Services written in CORBA, and clients that need to use a service, communicate through an Object Request Broker (ORB), which acts as an intermediary and uses the Internet Inter-ORB Protocol (IIOP) as a communications medium (see Figure 1). Services are specified using an object schema, which describes the various remote methods an object may provide. The schema is written in a special language, the Interface Definition Language (IDL). IDL schemas can be mapped to any target implementation language, so a service may be implemented in one or more languages. IDL is a little tricky to learn initially and takes a couple of days to get used to. Once you've mastered it though, or have found an object design tool that maps UML to IDL, designing CORBA services is extremely simple.

Figure 1
Figure 1. ORBs talk using IIOP.

When it comes to implementing CORBA services and/or clients, you have plenty of choices (including, but not limited to Java). Any language can support CORBA if an appropriate class library exists that can map object calls to an ORB. As support in the programming community for CORBA has grown over the years, the number of languages and vendors who use CORBA technology has grown as well. CORBA has reached the stage of maturity where it is a powerful technology for object communication that most major commercial languages support in one form or another (even if a third-party library needs to be used).

CORBA Support in J2EE
While CORBA is critical for enterprise development, its usefulness is not limited to that domain, as many applications can benefit from the application of CORBA. In addition, it is likely that client systems running J2SE will need to talk to enterprise servers running the J2EE. Fortunately, CORBA support has been around in Java for some time now and was included in the standard J2SE runtime. This means that existing Java 2 JVMs can connect to services running on the J2EE platform. If the Java Plug-in is installed, even an applet can communicate with a CORBA service, subject to the network and security limitations imposed on applets. (An applet can only connect to the server that it was loaded from, so placing a CORBA service on a different machine to your Web server will eliminate applets from the equation.) With the range of server-side choices provided by the J2EE, however, a servlet or JSP can often be used to eliminate the need for an applet-to-CORBA interface. Where applets are still required, though, CORBA remains a viable solution provided that the applet is digitally signed or the applet is loaded from the same machine as the service.

J2EE takes CORBA support even further than J2SE, by improving compatibility with RMI. Previously, it had been a choice between a RMI system and a CORBA one—now the need to select one or the other is removed, with support for RMI-IIOP (see the sidebar "RMI over IIOP").

Pros and Cons of CORBA
The advantages of CORBA are fairly self-evident. It allows developers to split services across many systems and to create systems that can be invoked from a variety of languages. That's a fairly simple statement, but its effect is astounding—not only do you have portability across operating systems, but also across languages! Aside from a steep initial learning curve, CORBA is fairly simple to use in everyday programming, and there are plenty of tools now that include CORBA support, ranging from object design through to implementation and testing. Where portability and efficiency are concerned, CORBA really stands out from the crowd.

The Java implementation of CORBA is not, however, without its flaws. When creating an implementation of a CORBA service, the IDL schema for an object must be mapped to an implementation. There's a tool, idltojava, which performs this mapping, but it doesn't ship with either J2SE or J2EE. While it may seem like nitpicking, I believe that a SDK should include all the necessary tools to construct software using the technology to which it is devoted. Sure, you can download the idltojava tool from Sun, but you need to register with the Java Developer Connection, and install it. Most developers are probably members already, and if they're not, it's a fairly straightforward process to register and download the tool. However, future versions of the J2EE SDK really should include the tool, as creating CORBA services in IDL is a common operation that most developers will perform at some point or another.

Another issue that developers will need to evaluate before using CORBA is performance (though in fairness, the same applies to any other distributed systems technology—RMI, DCOM, and others). As the number of clients using CORBA services grows, performance may become an issue. Bandwidth consumption will not be an overriding concern within a corporate intranet, but network latency may. Network latency can drastically affect performance; if it takes more than a few seconds to connect to a service and receive a response, the speed at which operations can be performed will be delayed. Local connections between closely grouped computers shouldn't be a problem, but if you expect an applet to connect to an Internet CORBA service, you should be prepared for some delay, particularly if your users connect through slow network connections (such as a dial-up ISP). Where possible, operations should be grouped together in batches to minimize the number of object calls made. Particularly when writing applet code, remember that CORBA operations will block just like any other network operation—so be sure to execute such code in a separate thread from your AWT event dispatcher, or you'll lock up the user-interface! Minimizing the number of calls made to CORBA services can also have a big effect on performance; care should be taken in design not to introduce unnecessary method calls later in implementation.

None of the issues raised by performance, or the extra download of a tool to map IDL to Java code, outweigh the clear business advantages of CORBA. Performance issues will affect any distributed system, and from my experience with using CORBA and RMI there isn't any clear winner in the speed game. However, the ability to access non-Java systems with CORBA, in my mind, puts it ahead of other technologies.

When and Where to Use CORBA
Wherever one component relies on the services of another, CORBA technology can be applied. CORBA can be used to provide a controlled interface to databases and other systems, to perform data processing, or to perform other tasks such as looking up information or recording orders; the uses of CORBA are virtually limitless. There is, however, an overlap between EJBs and CORBA. The decision whether to provide a business service as a CORBA object or as an EJB is largely up to the developer and business needs. Remember that (for the moment), EJBs are locked into the Java platform, whereas CORBA objects can be accessed from any language. This argument has an element of déjà vu about it; the same argument will be familiar to CORBA and RMI developers over portability. If management has issues with portability and future proofing services, they may advocate a CORBA approach, whereas Java purists may prefer to take the EJB approach. Such decisions are not always made on technical merit either. Business issues such as staff familiarity with a certain technology or the tools and servers currently being used may also sway the decision.

The CORBA support offered by Java 2 is extremely simple to use, and offers a good alternative to RMI systems. With the inclusion of RMI-IIOP to Java 2, however, the possibility exists to create RMI systems that are "CORBA compatible," though many developers will prefer to create straight CORBA implementations. For the J2EE, CORBA is an important technology, as it allows software to access legacy systems for which a CORBA wrapper is provided. This lets all systems within the enterprise operate together and create Java and Web-based interfaces to CORBA services.

The marriage of RMI and CORBA technologies means that developers who are already familiar with Java can continue to create service in RMI but maintain interoperability with other languages that support CORBA mappings. J2EE ships with support for RMI-IIOP, but you can update J2SE platforms to support it as well simply by downloading a free add-on from Sun Microsystems. This add-on includes bonuses such as sample code, as well as an enhanced version of the standard rmic compiler, which includes support for a new parameter (-iiop) for CORBA. Personally, I prefer a pure CORBA system without mixing in RMI, but many developers express a preference for RMI, and may have legacy systems (as hard as it is to think of Java RMI as a legacy technology!) that need to be converted to CORBA.

For more information on RMI over IIOP, the best place to start is at the Sun Microsystems Web site for the new product, at You'll find the RMI-IIOP download for J2SE, as well as additional information for J2EE users who want to create RMI/CORBA services.