Facilities for Building Quality Servers
Server-side applications are standalone entities providing services to remote client applications. The prevailing wisdom is that server applications have special requirements that distinguish servers from other types of software and define a different measure of quality.
Judging Java as a server-development platform requires evaluating the available APIs and services for realizing scalability
, and code-base maintainability
Scalability: A high-quality server must handle high volumes of client sessions and/or individual client interactions (requests). The quality of a server is connected to its capacity for simultaneous sessions and requests.
J2EE is all about scalability. The J2EE platform defines component models (servlets and Enterprise Java Beans, specifically) with very high scalability potential. The session and request models in J2EE have activation/passivation and resource-pooling mechanisms that imbue servlet, EJB, and Java Messaging Service (JMS) solutions with a similarly high capacity for simultaneous sessions and requests.
The J2EE model is more or less equivalent to those provided by equivalent platforms: COM+/MTS and "pure" CORBA application servers. With respect to scalability, a good server design on the J2EE platform is limited only by the underlying hardware and O/S layers.
Entity Enterprise Java Beans have specifically come under fire for not being as scalable as, for example, MTS components, which are inherently stateless. I don't agree with this argument, but a concerned designer could specifically omit the use of entity beans. Sticking to stateless session beans and handling all database interactions programmatically (through pooled JDBC connections) in bean code would be equivalent to the stateless server component model preferred by those who argue for MTS.
Extensibility: Business rules and vertical market logic must be able to be plugged into existing servers without recompilation or serious reconfiguration of the server. Component standards are also important; without them, code reuse is impossible.
On a basic level, the J2SE platform is very extensible. Java uses late-linking and a binary standard for classes that allow you to include new component implementations usually just by adding them to the Java classpath (or placing them in a similarly distinguished location available to the VM's class loaders). J2SE thus provides a portable, simple extension mechanism for classes.
There are lots of extensible servers implemented on J2SE, from small open-source projects to very large proprietary ones. The very volume of generic server types and frameworks (Jini, ObjectSpace Voyager and other agent-based systems, Apache and other non-J2EE servlet containers, to name just a few) implemented using J2SE attest to J2SE's inherent extensibility.
J2EE, built on top of J2SE, defines its own reusable component types: servlets and EJBs. These generic component models are designed with specific classes of server solutions in mind. Where a project's goals and servlet or EJB designs coincide, it is obviously easier to extend off-the-shelf servers than build your own servers from scratch.
It's important to note, however, that not all server solutions will be optimally implemented using servlets or EJBs, or even on the J2EE platform. For example, I was involved in a project with explicitly low scalability requirements; no more than 40 client sessions would be attached to a server. A prototype implementation using EJBs performed significantly slower than an alternative built using just J2SE. That's because the EJB design sacrifices some per-client performance to guarantee high scalability. Again, J2SE's late-linking and binary code compatibility are the foundations for building very extensible servers without J2EE.