Using Ja.NET for Interoperability

This section shows how you can use Ja.NET to perform bridging between a Java (JSP) Web tier and a .NET Framework Business tier. It describes the data format choices, how to create the service interface, and how to build the interoperability adapters.

Deciding on a Data Format

Ja.NET implements pure .NET Remoting, allowing you to expose any .NET Framework data type to Java. However, you are advised not to expose datasets to .NET Remoting clients directly for the following reasons:

  • The current implementation of the .NET Framework DataSet class does not offer optimum performance for serialization and deserialization. This is a known issue, and Microsoft plans to address this in future releases of the .NET Framework.

  • Typed datasets include inner classes, but the current version of Ja.NET does not support serialization of inner classes. This will be supported soon in a service release of the Ja.NET runtime.

If your .NET Framework application uses typed datasets, the recommended approach for exchanging data is to generate a set of simple custom data classes from the same XML Schema (XSD file) as the typed datasets. This can be done using the technique shown earlier in the chapter for generating a regular class from an XSD file.

These simple classes contain the data within the dataset classes, but their design improves serialization performance. Also, you can pass the simple classes using Ja.NET because they do not contain any inner-classes.

Building the Service Interface for Ja.NET

Ja.NET is a pure Java implementation of the .NET Remoting protocol, so you do not have to write any special code or runtime libraries when you expose .NET Remoting objects to Java applications.

As the previous section covers, the XBikes developers could not return dataset objects from the .NET Framework service interface. So the developers took the following steps to overcome the difficulties with datasets:

  1. They created a set of simple custom data classes for the .NET Framework dataset classes. The simple classes contain the data within the dataset classes but are optimized for performance (for more information, see Ja.NET best practices in Chapter 4, “Interoperability Technologies: Point to Point”).

  2. The developers created a wrapper interface around the .NET Framework business service fa ade to return the simple classes instead of the dataset classes.

Figure 8.3 shows how Ja.NET uses pure .NET Remoting to achieve interoperability between the J2EE Presentation tier and the .NET Framework Business tier.

click to expand
Figure 8.3: Implementing a custom .NET Framework service interface for the .NET Framework business service fa ade

The following steps describe how the XBikes developers defined a custom service interface to expose the .NET Framework business service fa ade to Ja.NET:

  1. The developers created a new Web project in Visual Studio .NET named XBikes BLL-JaNetServiceInterface.

  2. The developers created a series of .NET Framework simple custom data classes, such as the CustomerData class shown in the next step; these classes are similar to the corresponding data classes in Java. The developers placed these classes in a folder named JaNetWireDataTypes.

     using System; namespace XBikes.BLL.ServiceInterface.Net.JaNet {     /// <summary>     /// Wrapper class for DataSet CustomerData class     /// Merely contains the intrinsic values of the DataSet     /// It is sent over the wire by value, and is more efficient than     /// sending the whole DataSet     /// </summary>     ///     [Serializable()]     public class CustomerData     {         /// <summary>         /// Constructor         /// </summary>         public CustomerData()         {         }         private int customerID;         private string name;         private string address;         private string password;         private string zip;         /// <summary>         /// Gets Customer ID         /// </summary>         /// <returns>Customer ID</returns>         public int getCustomerID()         {             return customerID;         }         /// <summary>         /// Gets Customer ID         /// </summary>         /// <param name="customerID">Customer ID</param>         public void setCustomerID(int customerID)         {             this.customerID = customerID;         }         /// <summary>         /// Gets Name         /// </summary>         /// <returns>Name</returns>         public string getName()         {             return name;         }         /// <summary>         /// Sets Name         /// </summary>         /// <param name="name">Name</param>         public void setName(string name)         {    = name;         }         /// <summary>         /// Gets Address         /// </summary>         /// <returns>Address</returns>         public string getAddress()         {             return address;         }         /// <summary>         /// Sets Address         /// </summary>         /// <param name="address">Address</param>         public void setAddress(string address)         {             this.address = address;         }         /// <summary>         /// Gets Password         /// </summary>         /// <returns>Password</returns>         public string getPassword()         {             return password;         }         /// <summary>         /// Sets Password         /// </summary>         /// <param name="password">Password</param>         public void setPassword(string password)         {             this.password = password;         }         /// <summary>         /// Gets Zip         /// </summary>         /// <returns>Zip</returns>         public string getZip()         {             return zip;         }         /// <summary>         /// Sets Zip         /// </summary>         /// <param name="zip">Zip</param>         public void setZip(string zip)         {    = zip;         }     } } 

  3. Next the developers created a .NET Framework class named BLLJaNetServiceInterface to perform the conversion between .NET Framework dataset classes and the simple classes. BLLJaNetServiceInterface inherits from System.MarshalByRefObject because it is a marshal-by-reference data type. The following code listing shows the AuthenticateCustomer method for BLLJaNetServiceInterface class.

     using System; using XBikes.BLL.Facade; using XBikes.Common.Exceptions; using XBikes.Common.Schemas; using System.Collections; using System.EnterpriseServices; namespace XBikes.BLL.ServiceInterface.Net.JaNet {     /// <summary>     /// Class that wraps the BLL Business Service Facade.     /// This class is a custom wrapper and does NOT implement the     /// IBLLServiceFacade interface, as that interface deals directly with     /// the DataSet classes.     /// The DataSet classes currently have performance issues when being     /// serialized over the wire. As well the current version of Ja.NET (1.5.0)     /// does not handle the serialization of inner classes. The future version     /// of the DataSet classes will have greatly improved performance. As well,     /// Ja.NET will support inner class serialization in the new future.     /// </summary>     public class BLLJaNetServiceInterface : System.MarshalByRefObject     {         /// <summary>         /// Constructor - No Action         /// </summary>         public BLLJaNetServiceInterface()         {         }         /// <summary>         /// This is the wrapped version of the AuthenticateCustomer         /// method in the         /// standard IBLLServiceFacade method. Converts the DataSet         /// CustomerData object         /// the more remoting friendly wrapper version.         /// </summary>         /// <param name="email">The email of the user</param>         /// <param name="password">Password of the User</param>         /// <returns>Wrapped Version of Customer Data</returns>         public XBikes.BLL.ServiceInterface.Net.JaNet.CustomerData 
    AuthenticateCustomer(string email, string password) { try { // Create a return type object XBikes.BLL.ServiceInterface.Net.JaNet.CustomerData ejbCustData =
    new XBikes.BLL.ServiceInterface.Net.JaNet.CustomerData(); // Use the .Net Business Service Facade and // get a Data Set customer object BusinessServiceFacade bsf = new BusinessServiceFacade(); XBikes.Common.Schemas.CustomerData custData =
    bsf.AuthenticateCustomer(email, password); //Check if authentication failed by looking for //an empty CustomerData dataset. if (custData.Customers.Count != 0) { // Fill in the wrapper object with values // from the DataSet object ejbCustData.setCustomerID(custData.Customers[0].CustomerID); ejbCustData.setName(custData.Customers[0].FullName); ejbCustData.setAddress(custData.Customers[0].EmailAddress); ejbCustData.setZip(custData.Customers[0].ZipCode); } else { //do nothing - leave ejbCustData empty } return ejbCustData; } catch (XBikesApplicationException ae) { throw ae; } catch (XBikesInteropException ae) { throw ae; } catch (System.Runtime.Remoting.RemotingException sre) { // Is it a problem with the network? string message = sre.Message; if (message.IndexOf("com.intrinsyc.janet") >= 0) { throw new XBikesInteropException(sre.Message, sre); } else { // or is it an application error? throw new XBikesApplicationException(sre.Message, sre); } } catch (Exception eX) { // generic catch/rethrow throw new XBikesApplicationException(eX.Message, eX); } } }

  4. Finally the XBikes developers modified the Web.config file to expose the service for .NET Remoting. The developers chose to host the .NET Remoting component in IIS, using HTTP as the transport but with binary formatting for performance. The <system.runtime.remoting> section of the Web.config file is shown in the following code sample.

     <system.runtime.remoting>   <application>     <service>       <activated          type="XBikes.BLL.ServiceInterface.Net.JaNet.BLLJaNetServiceInterface,                XBikes-BLL-JaNetServiceInterface" />     </service>     <channels>       <!--  <channel port="<JaNet Port From Janetor>" ref="tcp"/>       -->       <!--  IMPORTANT:  COMMENT OUT THE FOLLOWING IF UNDER .NET 1.0!!!  -->       <!--  and uncomment the statement above                           -->       <channel ref="http">           <serverProviders>             <formatter ref="binary" typeFilterLevel="Full"/>           </serverProviders>         </channel>       <!--  END .NET 1.1 SPECIFIC  -->       </channels>     </application>   </system.runtime.remoting> 

Creating the Interoperability Adapters using Ja.NET

After you construct and expose the service interface, the next step is to create the interoperability adapters in J2EE.

Because Ja.NET implements pure .NET Remoting, you must define a Java proxy class that the J2EE application can call to consume the exposed .NET Framework service interface. You can use graphical tools provided by Ja.NET to create this proxy class. After you have created the proxy class, it is a simple task to define the Java interoperability adapters.

The following steps describe how the XBikes developers created the interoperability adapters using Ja.NET:

  1. The developers used the GenNet tool to create Java proxy classes for selected .NET Framework assemblies. GenNet generated a set of Java source files, which the developers compiled and added to JanetNetBllProxies.jar. The developers also added Janet.jar to the same folder as JanetNetBllProxies.jar.

  2. The developers used the Janetor tool to configure the location of the .NET Framework client. This is the Java equivalent of defining .NET Remoting configuration files.

  3. The developers created a new package named in the XBikesWeb project, and they added the use case adapter classes. Each adapter class makes a call into the proxy JAR file to communicate with a particular .NET Framework service. The code for the AuthenticateCustomerCommandAdapter adapter class is shown in the following code sample.

     package; import; import; import xbikes.common.interfaces.architecture.IUseCaseCommand; import XBikes.BLL.ServiceInterface.Net.JaNet.*; public class AuthenticateCustomerCommandAdapter implements IUseCaseCommand {   // Values required when the command is executed   private String email;   private String password;   // Constructor   public AuthenticateCustomerCommandAdapter() throws Exception   {     email = "";     password = "";   }   // Set up the use case adapter and assign parameters for the upcoming action   public void initialise(Object[] params)   { = params[0].toString();     this.password = params[1].toString();   }   // Execute the command, using the email and password instance variables   public ValueObject execute() throws Exception   {     // Invoke the AuthenticateCustomer method on the remote object     BLLJaNetServiceInterface rf = new BLLJaNetServiceInterface();     XBikes.BLL.ServiceInterface.Net.JaNet.CustomerData cdr =                                    rf.AuthenticateCustomer(email, password);     System.out.println("AuthenticateCustomerCommandAdapter: " +                        ".NET Framework remoting object returned details " +                        "for Customer: " + cdr.getname() + ".");     // Return a Java CustomerData object     return new CustomerData(cdr.getcustomerID(),                             cdr.getname(),                             cdr.getaddress(),                             password,                             cdr.getzip());   }   // Execute the command, using specific email and password values   public ValueObject execute(String pEmail, String pPassword) throws Exception   { = pEmail;     this.password = pPassword;     return this.execute();   } } 

The AuthenticateCustomerCommandAdapter adapter class provides a bridge from the J2EE Presentation tier and the .NET Framework Business tier.

Application Interoperability. Microsoft. NET and J2EE
Application Interoperability: Microsoft .NET and J2EE: Microsoft(r) .Net and J2ee (Patterns & Practices)
ISBN: 073561847X
EAN: 2147483647
Year: 2003
Pages: 104 © 2008-2017.
If you may any questions please contact us: