Microsoft Visual J# .NET (Core Reference) (Pro-Developer)
I l @ ve RuBoard |
The J2EE specification defines a framework for building and deploying distributed applications using Java. Many vendors implement J2EE in their server products ”BEA WebLogic Server, IBM WebSphere, Sun Microsystems iPlanet Application Server, and Oracle Application Server are four popular examples. Java components that execute in a J2EE environment communicate using Java's own RMI protocol. J2EE specifies a core set of services, and it should be possible to build applications that are independent of any particular vendor's implementation. Many vendors have adopted the tried and true strategy of "adding value" to the J2EE specification by implementing proprietary extensions with their products, leading to inconsistencies between implementations . However, it is worth reviewing the individual elements that comprise J2EE so you can see where the equivalent functionality lies in .NET. The upcoming material is not intended to be a detailed treatise on J2EE. If you want more information about the elements that comprise J2EE, you should study one of the many other books available, such as Teach Yourself J2EE in 21 Days by Dan Haywood, Martin Bond, and Peter Roxburgh (Sams Publishing, 2002). The Elements of J2EE
J2EE is used for building n - tier applications. The elements that comprise the J2EE specification are generally aimed at individual tiers. Figure 3-10 depicts the general structure of J2EE and its components, broken down by tier. The following sections discuss each of these areas in turn . Figure 3-10. The structure of J2EE
Data Services in J2EE
J2EE provides Java Database Connectivity (JDBC) and the Java Connector Architecture for manipulating data retrieved from a data store and saving it again. We'll cover the Java Messaging Service (JMS) shortly. JDBC actually predates J2EE but has become an integral part of it. JDBC is used to interface with relational databases, and it allows a developer to submit SQL requests and retrieve tabular data. Batch optimizations allow a developer to submit blocks of requests to a database to try to reduce the network bandwidth used by an application. One enhancement of JDBC that appeared as part of the J2EE specification is the RowSet interface. A RowSet is basically a JavaBean that allows a developer to package a set of rows into an abstract object that hides the details of the underlying database and tables. JDBC also allows connection pooling (depending on the functionality implemented by the JDBC driver), permitting database connections to be shared among multiple components. The Java Connector Architecture defines a mechanism that allows a developer to integrate Enterprise Information Systems (EIS) into the J2EE framework. The Java Connector Architecture is based on adapters (another one of Gamma's patterns) that convert J2EE server requests into those understood by the EIS. The adapter also has to implement a number of system contracts for handling connection, transaction, and security management in a standard way, as directed by the J2EE server. This allows a degree of pluggability between EISs and J2EE servers ”in theory, an EIS that implements a particular service can be replaced by an alternative, and the same applies to the J2EE server! A J2EE application can call upon an EIS as if it were part of the J2EE server and treat it as an integral piece of the system. You should notice that neither XML nor Web services feature in J2EE. This is intentional. Although they can both play an active part in building solutions that integrate third-party services into J2EE, both have much broader appeal than just Java applications. To tie them to J2EE at this stage in their development would be severely limiting ”remember that J2EE is a specification, and if Java-based support for XML and/or Web services were to form part of the same specification, they would be updatable only when a new version of J2EE was released. Instead, you'll find a host of separate Java APIs for handling different aspects of XML and implementing Web services. They currently include
Web service toolkits for building Web services in Java are available from several sources. These toolkits generally track the various XML APIs listed above. Business Services in J2EE
Perhaps the best-known part of the J2EE specification concerns Enterprise Java Beans (EJBs). These are components designed to run on the server side to implement business logic, potentially for multiple clients . EJBs come in two flavors, Session and Entity. A Session EJB implements a service, such as submitting an order in a sales application, and can be either stateful (maintaining state between method calls) or stateless (no state is maintained ). Entity EJBs are used to model persistent objects ”often rows from a database. Entity EJBs are highly stateful! Both kinds of EJBs are managed by containers , which are provided by the J2EE server. When the J2EE server starts, it creates containers for the various EJBs it supports, and each container can create a pool of EJB instances that are ready for use. When a J2EE application requests the use of an EJB, the J2EE server will respond by passing back a reference to an appropriate EJB. When the application has finished with the EJB, the J2EE server can return it to the pool for recycling. All of this is often hidden from the client application, which only sees EJBs being "manufactured" (or so it thinks) on demand. The container manages the lifetime of an EJB. An EJB developer defines an EJB using a pair of interfaces: the Remote interface, which contains the business methods exposed by the EJB that the J2EE application can use, and the Home interface, which defines the methods used by the J2EE client to create, find, or delete EJBs. Session EJBs tend to be short-lived, often executing a single method on behalf of a client application before being returned to the pool. Entity EJBs model business or data entities. Entities are expected to outlive the J2EE application processes that use them. The Entity EJB model defines a mechanism for saving the contents of an EJB back to a database and for re-creating the EJB from data held in a database. To actually load and unload data to or from persistent storage, Entity EJBs can use Bean-Managed Persistence (BMP) or Container-Managed Persistence (CMP). In BMP, the Entity EJB contains the code necessary to populate or save the entity's data using life-cycle methods defined as part of the contract between the EJB and the container. With CMP, the container itself populates the EJB using configuration information supplied when the EJB is deployed. User Services in J2EE
J2EE is largely intended for building Web-oriented applications, so the infrastructure it specifies for presenting user interfaces comprises technologies for generating XML and HTML. These technologies are servlets and JavaServer Pages (JSP). A servlet is a Java class that executes in a JVM running in a supporting Web server. (Many common Web servers that support servlets are descended from Tomcat, which is the servlet container that forms part of the Apache Web server.) Most servlets are designed to handle and process HTTP requests originating from a Web browser, although servlets can handle other protocols as well. When a Web server receives a request for a particular HTML page (or set of pages), it can redirect that request to an HTTP servlet, passing it any HTTP parameters that were submitted by the client. The servlet can examine these parameters and generate an HTML (or XML) response, which is sent back, via the Web server, to the client. The same JVM can run multiple servlets, and it is possible to share data between servlets servicing different clients. The Servlet API contains the abstract class HttpServlet , which you can extend and add your own functionality to. Most implementations override the init method (which executes when the servlet is first loaded) and the doGet and doPost methods (which run when the servlet receives an HTTP Get or HTTP Post request, respectively). The servlet sends its HTML reply to an output stream ”the Web server captures this stream and converts it into an HTTP response. The model used by servlets is similar to the compile-and-cache technique implemented by ASP.NET. When the Web server runs a servlet, it looks to see whether a compiled class file already exists for that servlet. If the file exists, the Web server loads it; if not, the Web server compiles the source code to produce the class file. Multiple clients can run the same servlet concurrently. Having said that, we must concede that you can simply deploy precompiled .class files with the Web server, packaged up as Web Archive (WAR) files. This is the approach most commonly adopted by J2EE servers that are integrated with Web servers these days. Much of the code in a servlet is concerned with parsing input parameters and formatting an HTML or XML response. JSPs simplify this task by abstracting the mechanics of these tasks out to automatically generated code, allowing the developer to concentrate on the layout and any associated user interface logic. A JSP contains ordinary HTML markup along with Java statements embedded between special tags that perform any additional processing required. Conceptually, the model is similar to that used by Microsoft for ASP, although Microsoft adapted it for languages other than Java. Behind the scenes, a JSP is converted into a servlet by the JSP engine in the Web server. The servlet is then compiled into a Java .class file that can be loaded and run as described earlier. Hence, as with servlets, multiple clients can execute the same JSP simultaneously and share data. JSP is tightly integrated with Java, so it has a close association with JavaBeans. JSP defines shorthand syntax for instantiating a JavaBean and accessing its properties. A common approach is to limit a JSP to performing tasks associated with the layout of an HTML page and to use a JavaBean to encapsulate any business logic or other processing. JSP also lets a developer define custom tags (by creating tag libraries) and embed them in pages. The J2EE Infrastructure
J2EE makes heavy use of the Java Naming and Directory Interface (JNDI) for providing access to directory services. JNDI provides a uniform API to the different directory services that are available. For example, J2EE servers implement a directory service that makes EJBs available through JNDI names . Other resources, such as databases, connection pools, and even the file system, can be accessed through JNDI using a suitable JNDI service provider. (A JNDI service provider is an adapter that converts JNDI requests into a format understood by the underlying technology.) The list of JNDI providers is continually growing and includes providers for DNS, LDAP, and CORBA. The Java Messaging Service (JMS) is the J2EE API for integrating message-oriented middleware into a Java application. As is so often the case in J2EE, JMS essentially defines a series of interfaces and adapters that messaging systems vendors should implement to make their products available to J2EE. JMS implementations are available for many of the widely used messaging systems, including IBM MQ Series and MSMQ. The current release of the J2EE specification allows EJBs to be combined with JMS to provide asynchronous activation of middle-tier services through messaging. An EJB client can post a message to a queue and have that message processed asynchronously by an EJB. This is useful for mostly-disconnected clients; requests can be sent to a local message queue on the client machine and posted by the message queuing software as a batch the next time the client connects to the network. Transaction Management
Transactions have always been important but difficult to implement correctly, especially in a distributed environment. The problem is that the participants might be spread over the network (possibly the Internet), where speed and reliability become challenging issues. Transactions also determine when a J2EE server can discard, save, or recycle an EJB. Managing distributed transactions is best left to specialist transaction servers. J2EE defines the Java Transaction API (JTA) to help in this situation. The JTA is an interface used for initiating, committing, and rolling back transactions. The JTA can be used directly by J2EE component developers, but it is more commonly employed by EJB containers. EJB containers allow developers to specify declarative transactions as EJB method attributes, and the container will start and control any transactions required using the JTA. The JTA relies on a transaction service provider that implements the JTA to actually create and manage transactions as directed by the application or the J2EE container. Many application servers that implement J2EE also double as transaction servers. Comparing .NET to J2EE
It's always risky to compare one technology to another. Inevitably, interest groups on one side or the other will claim that the comparison was unfair or that it omitted details to show one product in a favorable light over another or was otherwise prejudicial. This is especially true in the "J2EE vs. .NET" debate, which can degenerate into "Sun vs. Microsoft" if one is not careful. So, before we continue, let us state something that might disappoint or surprise you: We like J2EE. We've used it to build applications and will probably continue to use it in the future. If you're building or designing a solution that's based on Windows, you should probably use .NET. If, however, the system is heavily based on UNIX, for example, you'd be crazy not to go for J2EE. The challenge is to know what to use in hybrid UNIX/Windows systems, but the integration features of .NET make it ideal for building components that run on Windows but need to interface with J2EE, particularly with the advent of Web services. Another point is worth making: Comparing .NET to J2EE is a little like comparing apples to oranges. The most important difference is that J2EE is a specification, whereas .NET is an actual product suite. There are many implementations of J2EE; some are great, some are not, so we'll refrain from even attempting to compare the performance of J2EE and .NET and will instead stick to the functionality exposed by each. Data Services in .NET
In the Data Services Tier, .NET provides ADO.NET as an alternative to JDBC. You can still use JDBC from J# if you want. JDBC is used primarily to access relational databases, whereas ADO.NET uses a more generalized model and can access many different types of data stores. That being said, the most common use for ADO.NET is as an interface to SQL Server, and Microsoft supplies an optimized implementation (packaged in the System.Data.SqlClient namespace) just for SQL Server. The System.Data.OleDb namespace contains the generic OLE DB data provider that you can use to query other data sources. It is anticipated that third-party database vendors will supply their own ADO.NET libraries for accessing their products. We'll cover ADO.NET in detail in Chapter 7. As far as integration with EISs is concerned, .NET provides a wealth of features and tools that you can use, depending on the circumstances, ranging from low-level solutions involving COM and J/Direct to highly functional schemes such as building Web service facades. Chapter 13 describes how to integrate with legacy systems. .NET has good support for common XML features such as schemas, namespaces, XPath, and XSL/T. The System.Xml namespace and its child namespaces in the .NET Framework class contain classes and methods for creating and manipulating XML documents. However, XML is not just an add-in appended to .NET for the convenience of developers. It is a fundamental part of .NET. Much of the .NET Framework relies on XML for its own use. For example, configuration information is held in XML files, the Remoting architecture can use XML as a format for serializing data, ADO.NET uses XML internally to represent data in a portable manner, and SOAP relies on XML as the format for sending and receiving requests. The implementation of SOAP underpins Web services, which are also an integral feature of .NET. Chapter 5 and Chapter 6 cover XML in detail. Chapter 17 and Chapter 18 describe Web services under .NET. Business Services in .NET
Microsoft has had a middle-tier technology available for some time. It was originally called Microsoft Transaction Server, but it has matured over the last few years into COM+. Strictly speaking, COM+ is part of the Windows operating system rather than .NET, but you should expect to see Windows and .NET become increasingly intertwined, in much the same way that COM+ and Windows have. COM+ components are the closest that .NET gets to Java EJBs (although it does not currently supply an equivalent to CMP). You cannot create EJBs with J#, but you can create COM+ components. COM+ components can be stateful or stateless, and the integration with other operating-system-level features such as events and messaging allows you to build asynchronous components. In .NET, COM+ components are called serviced components . A nice touch is the just-in-time deployment feature ”you don't have to manually deploy a serviced component because it will be automatically installed into the Component Services framework when it is first used. Serviced components are described in detail in Chapter 14. User Services in .NET
J2EE has JSP, and .NET has ASP.NET. Actually, there is considerably more in ASP.NET than the functionality of JSP. For one thing, ASP.NET supplies intelligent server controls. A server control is an ASP.NET component, embedded in a Web Form, that can programmatically respond to events generated by the user interacting with the form ”clicking a button, for example. The code that responds to the event will execute on the Web server and can generate a new page or update the contents of the current one. (It does this using sleight of hand ”it actually creates a new page that looks like the old one, but with any values typed in by the user preserved, and possibly new data added as a result of the processing performed by the event handler. All of this is performed automatically by the ASP.NET runtime so you don't have to write any intricate code!) Because the event-handling code that you add to a Web Form is ordinary J# code (or C# code, or Microsoft Visual Basic .NET code, or code in any other language supported by the runtime), you can do anything that you can from an ordinary application, security permitting, including invoking a serviced component, calling a remote object, or querying a database. You'll see a lot more of ASP.NET in Chapter 16. The .NET Infrastructure
J2EE uses JNDI as a naming service that allows an application to locate and activate components and resources. This practice gives the application a high level of configurability that allows individual components to be replaced without a programmer having to rebuild and redeploy an entire application. .NET also has this capability. But instead of using a naming service, the common language runtime uses the mechanisms described in Chapter 2 for locating and loading assemblies. This mechanism depends on individual application configuration files and publisher policy files, or a specific search sequence if no configuration files are present. Some configuration information can also be held centrally in the machine and enterprise configuration files. The .NET Framework class library provides the System.DirectoryServices namespace. The classes in this namespace can be used to access any of the Active Directory service providers. In this respect, it fulfills a role similar to that of JNDI. Microsoft currently supplies providers for Microsoft Internet Information Services (IIS), Novell Netware Directory Service (NDS), Lightweight Directory Access Protocol (LDAP), and WinNT. Windows uses Active Directory as a repository for system information, and it is possible to store details about almost any type of resource using it. MSMQ is another example of a technology that started out as an add-on (the original version was part of the Windows NT Option Pack) but is now a critical part of the operating system. The COM+ runtime relies on MSMQ to support its asynchronous operations. You can create applications based on MSMQ using the classes in the System.Messaging namespace. Message queuing is covered in Chapter 12. Transaction Management
.NET makes use of the transaction services exposed by the COM+ runtime and the Distributed Transaction Coordinator. What this means in practical terms is that you don't have to learn any new tricks to use transactions with .NET ”you just have to learn how to apply all the old ones! Classes and methods can be tagged with TransactionAttribute (found in System.EnterpriseServices ) to indicate any transactional requirements, and the common language runtime in conjunction with COM+ does the rest: importSystem.EnterpriseServices.*; /**@attributeTransactionAttribute(TransactionOption.Required)*/ publicclassCakeOrderComponentextendsServicedComponent { } Individual methods can also be tagged with AutoCompleteAttribute (also in System.EnterpriseServices ), indicating that the runtime should determine whether to commit or roll back the current transaction automatically at the end of the method, depending on whether the method was successful (whether it raised an exception). /**@attributeAutoCompleteAttribute()*/ publicvoidCancelOrder(intorderId) { } COM+ applications can also take charge of their own transactions in a similar manner to the JTA, if they really need to. Transactions are also covered in Chapter 14. The Java Pet Store
Having a comprehensive set of tools for building applications is one thing, and actually using them to successfully implement a complex distributed system is another. More often than not, it helps to have an example system that you can take apart so you can see how things should be done. For this purpose, we'll take a look at the Java Pet Store example. The Java Pet Store is an e-commerce application that allows customers to browse the animals stocked by a pet shop, place orders, pay for goods, and so on ”all the usual e-commerce type of stuff. The original application was designed and documented by consultants working at Sun Microsystems, and it shows best practices (referred to as the J2EE Blueprints) for building Web-based applications using J2EE. You can download the Java Pet Store source code and documentation from http://www.java.sun.com/blueprints/code/index.html#java_pet_store_demo. For comparison purposes, an implementation of a similar application called the Microsoft .NET Pet Shop (shown in Figure 3-11 on page 144) is available from the .NET Framework Community Web site at http://www.gotdotnet.com/team/compare/petshop.aspx. This version uses .NET and is written in C# because J# was not available when the .NET Pet Shop was developed. Ignoring any relative performance benchmarks (which are always subjective ), one interesting statistic concerning the two applications is the amount of code that was written: The Java Pet Store contains over 14,000 lines of Java, but the equivalent parts of the .NET Pet Shop comprise under 3500 lines of C#. There are some differences between C# and J#, but we would expect a J# version to be a similar size . As with any implementation based on a set of requirements, each of these applications makes use of the strengths of the particular technologies on which it is based. It also makes its own trade-offs when mapping the required functionality into components. As developers who are fluent in both Java/J2EE and J#/.NET, we would encourage you to examine the two implementations and form your own opinion about which is the best tool for your purposes. When you examine the .NET Pet Shop (or any equivalent Microsoft examples, such as Duwamish Books), bear in mind that even though the examples are meant to show the best way of applying particular technologies, there's also the tendency to show off as many technologies as possible, which is not always the best way to design an application!
Note The Java Pet Store and the .NET Pet Shop do have some functional differences. For example, the Java Pet Store defines mailing and administrative operations, and the .NET Pet Shop does not. Similarly, the .NET Pet Shop contains features that handle mobile devices and a Web service not found in the Java version. Our comparison of the lines of code includes only the areas that are common to both applications, so it is a fair comparison.
Figure 3-11. The .NET Pet Shop
|
I l @ ve RuBoard |