Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Port Microsoft�s Commerce Starter Kit to Apache Tomcat

19 Jul 2005 2  
Using Mainsoft�s Grasshopper, you can take this reference application from Microsoft� and, in just a few minutes run it on a J2EE� application server such as Apache Tomcat under Linux�.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

If you know your way around the Visual Studio .NET development environment, you can roll up your sleeves and within a matter of minutes create and debug your first J2EE application using Grasshopper - the Developer edition of Visual MainWin for J2EE�.

But, what about taking an existing .NET application such as Microsoft�s Commerce Starter Kit and porting it to J2EE?

Is it possible to preserve the original application functionality when porting it to J2EE? How will you manage the source code bases between the J2EE-based and the .NET framework-based implementations? How much effort is involved? Is Grasshopper up to the challenge?

These questions and a whole lot more will be answered as you take the Microsoft Commerce Starter Kit and port it to Apache Tomcat using Grasshopper. You will explore the various issues that you might encounter when porting from applications based on the .NET framework to J2EE. Along the way you�ll gain an understanding for how Grasshopper addresses these issues and have a glimpse under the hood of some of the Grasshopper modules that make such a port possible.

About the Commerce Starter Kit application

 

 

Figure 1. The Commerce Starter Kit web interface.

The Commerce Starter Kit (previously known as IBuySpy) is considered a reference application to show off the features of ASP.NET technology, and as such is a great representative test case for porting a real life ASP.NET application to J2EE.

This application implements basic online shopping tasks including: a product catalog, user authentication and personalization, shopping baskets, and order checkout.

Designed after traditional distributed web applications, the Commerce Starter Kit is built across three logical tiers:

These are:

  • The Data Tier: Generally a relational database that supports the application and encapsulates functionality such as transactions, record locking and user security. In this case, SQL Server 2000 is used.
  • The Middle Tier: This is where the data is retrieved and enriched with business logic, and where updates to the database are processed and prepared. Typically it is the realm of .NET framework-based applications, Web Services, Java Beans� or Enterprise Java Beans (EJBs), depending on the application.
  • The Presentation Tier: This is where the data is rendered to the screen, and navigation and workflow are encapsulated. Typically ASP.NET web forms or JSP are used here.

 

 

Figure 2. The Commerce Starter Kit architecture.

You can see these tiers and how they are used in the Commerce Starter Kit in Figure 2


Crossing the border to the J2EE land

If you�ve never used J2EE, Java or Tomcat before, you may feel a bit apprehensive, thinking about the mysteries of EJBs, properties files and deployment descriptors that your Java buddies tend to talk about! Fear not! You don�t have to worry about any of these when using Grasshopper, and once you�ve completed this port you�ll have excellent, first-hand, experience in using J2EE technologies, and you�ll see just how easy it is.

Step 1. Preparing for the port using the online documentation

 

 

Figure 3. The Commerce Starter Kit Porting Tutorial.

After you have installed Grasshopper, take a look at the Visual Studio .NET online help, and you�ll find the Visual MainWin books. Open up the Tutorials book and look for the ASP.NET Commerce Starter Kit tutorial [Figure 3]:

The tutorial will walk you through the step-by-step procedure required to port the Commerce Starter Kit to J2EE with Grasshopper. While the tutorial shows you the how-to, this paper provides additional, in-depth observations.


Step 2. Generating a J2EE project for the Commerce Starter Kit Application

 

 

Figure 4. Side By Side J2EE and .NET framework projects.

After you install the Commerce Starter Kit application and verify that it builds and runs on the .NET framework in your environment, the next step is to use the Grasshopper �Generate J2EE Project� wizard to create a J2EE project for it. The wizard creates a new project along side your original project, within your original Solution.

Take a moment to look at the CommerceCSVS.J2EE project References [Figure 4]. See anything interesting?

The existence of a reference to the 'j2ee' assembly is probably your first clue that this is not an ordinary C# project. This assembly exposes the entire J2EE runtime collection of classes as if they were simply an extension of the .NET framework! You will not be using it for the port of the Commerce Starter Kit, but keep a mental note to yourself - if you want to directly use any of the J2EE classes, here is where you�ll find them.

If you look further, you will notice that the new project includes all the files that are found in the original project for the .NET framework. All files in the newly created J2EE project are links to the original files in the original project. As a result, all modifications done to any of the files in either project will be updated in both. The wizard leaves the original project intact, and you can continue to use it to build a .NET target. This way, you can maintain a single source code base to build your applications for both platforms!

With the new J2EE project, you can do things you cannot normally do in a regular C# project, like building a J2EE target from your C# source code, adding references to Java Archive (JAR) files, debugging mixed Java and C# code and deploying the application directly to Tomcat, as you will see as you progress with the port.

Step 3. Building the J2EE project

 

 

Figure 5. Debug_Java configuration automatically created by the wizard.

There is nothing special about building the J2EE project, and that�s what makes it so appealing -- if you know how to build a C# project in Visual Studio .NET then you know how to build the J2EE version of it. All you have to do is to set the active configuration to be the Debug_Java configuration (this configuration was automatically created by the wizard) and start the build. When the build completes, you�ll end up with a J2EE version of the Commerce Starter Kit application! You can see how to do this using the Configuration Manager in Figure 5.

But how does it work? What happens behind the scenes after you hit the build button?

To understand this you should consider how Grasshopper integrates with Visual Studio.NET. Taking advantage of the Visual Studio extensibility framework, Grasshopper monitors your build requests. When identifying that you wish to build a J2EE release, it launches its J2EE build agent, which orchestrates the J2EE build process:

At first, your code is compiled to a standard .NET assembly. In this phase, the compilation is carried out by the .NET framework�s C# compiler. If your code compiles cleanly to MSIL, the build advances to the next phase � generating Java bytecode. This is where the interesting stuff starts to happen.

Take for example the �Security.cs� file:

using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
 
namespace ASPNET.StarterKit.Commerce.Components
{
   /// 

   /// Summary description for Security.

   /// 

   public class Security
   {
   //*********************************************************************

   //

   // Security.Encrypt() Method

   //

   // The Encrypt method encrypts a clean string into a hashed string

   //

   //*********************************************************************

      public static string Encrypt(string cleanString)
      {
         Byte[] clearBytes = new UnicodeEncoding().GetBytes(cleanString);
         Byte[] hashedBytes =   
   (HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes);
                    
         return BitConverter.ToString(hashedBytes);
      }
   }
}  

All it does is implement a very simple class � Security, which contains a single static method named Encrypt. This method accepts a string and returns it encrypted. As simple as it is, you can see that it opens up a few questions.

The first and most obvious observation is that this is C# code. How does it end up as Java byte code? The answer to this challenge lies with the Grasshopper MSIL to Java binary compiler. It reads the .NET assembly that was created by the .NET framework C# compiler and translates its code to standard Java Byte code - while preserving the original semantics of the ported code! This patent-pending technology is what enables you to keep on developing the original application in C# and run it as a pure Java application inside standard J2EE servers!

This takes care of the C# to Java translation, but what about the .NET framework classes? As you can see, the Encrypt method creates and uses a new instance of the System.Text.UnicodeEncoding class to extract bytes from the input string. It then uses the System.Security.Cryptography.HashAlgorithm class to encrypt the data and finally, the System.BitConverter class to translate the bits back to a string. How can such code execute in the J2EE environment? These are .NET framework class libraries that aren�t part of your source code!

Here is how - utilizing Grasshopper�s ability to compile C# code to Java bytecode, the Grasshopper .NET framework implementation is based on the open source Mono� class libraries, rehosted to J2EE. The result is that these classes and many more are implemented in Java and are available to your ported application in the J2EE environment! Therefore your Java implementation will recognize the Java versions of these class libraries and use them when executing in the J2EE environment.

Furthermore, during the build, Grasshopper parses your code and searches for potential porting problems, such as the use of .NET framework runtime classes that are not supported or are partially supported in the J2EE environment. If it finds any, you�ll be given warning messages that contain the details of the potential problem. There are several ways you can handle such issues. For example, you can use conditional compilation to exclude the unsupported code from the J2EE build (some features are simply irrelevant to the J2EE version), or you can rewrite the code to use an alternative which is supported on both environments. In our case, the Commerce Starter kit build completes successfully with the following warnings:

Compiling Java...
Processing C:\Program Files\ASP.NET Starter Kits\ASP.NET Commerce 
  (CSVS)\CommerceCSVS\bin_Java\ASPNETCommerce.dll...
Validating classes...
Packing files...
C:\Program Files\ASP.NET Starter Kits\ASP.NET Commerce (CSVS)\CommerceCSVS\
     Web.config(16) :warning JC8000: Not Implemented Element 'customErrors'.
C:\Program Files\ASP.NET Starter Kits\ASP.NET Commerce (CSVS)\CommerceCSVS\
     Web.config(10) :warning JC8000: Not Implemented Element 'pages'.
C:\Program Files\ASP.NET Starter Kits\ASP.NET Commerce (CSVS)\CommerceCSVS\
     Web.config(18) :warning JC8000: Not Implemented Element 'sessionState'.
Processing ASP.NET pages...
Converting Global.asax..

These warnings will not affect the port; however, it is worth explaining them. All three warnings are about unsupported elements in the Web.config file. In the .NET environment, you use this file to configure your application. In the J2EE world, such configuration is done differently. Because the ported application is a standard J2EE application, Grasshopper leaves the J2EE application configuration to the person who will be managing the J2EE server, using the standard J2EE means to configure it.

 

 

Figure 6. Grasshopper�s Class Library reference

As a side note, another valuable source of information you can use when porting with Grasshopper is its integrated help [Figure 6]:

If you�ve ever used the Microsoft Developers Network (MSDN), you�ll find that the Grasshopper Class Library Reference is laid out in a very familiar order. You can use it to quickly find out all there is to know about the J2EE implementation for any .NET framework class you are using in your application.

The complete Grasshopper documentation set is also available on-line in the Grasshopper web site.


Step 4. Deploying the Commerce Starter Kit Application to the Tomcat server.

Upon a successful Java build, Grasshopper packs the Commerce Starter Kit executable J2EE application into a Java Web Archive (WAR) file � the standard J2EE format for deploying applications, and uploads it into your local instance of Tomcat.

 

 

Figure 7. Using the Solution Explorer to find your WAR file.

Now a WAR file may sound like a complicated, proprietary binary file, but it is nothing more than a ZIP file that is built with a specific hierarchy. If you want to view it, you can do it right now. From Visual Studio .NET, take a look at the Solution explorer, click on the �Show All Files� icons and locate the �CommerceCSVS.J2EE.war� file. You�ll find it in the bin_java folder [Figure 7]:


 

 

Figure 8. Exploring a WAR file with WinZip.

If you open this file with WinZip, you�ll get to see its contents [Figure 8]:

Notice the web.xml file? This file was created for you by Grasshopper. In the J2EE world, it is known as the Servlet Deployment Descriptor. It tells the Tomcat server all it needs to know about your application. Every standard J2EE application is packaged in this way, and yours is no different.

The next step is to get the WAR file onto your application server. As a developer, you�ll need to test your application on your local application server and be able to deploy it again and again, until you have something that is production-ready. Grasshopper knows which application server your project is associated with. With the required knowledge already built into it, Grasshopper uses the deployment method specific to this server whenever your WAR build completes successfully, saving you all the trouble!

Now, go back and look at Figure 1 again. This is the Commerce Starter kit, but it is actually running on Tomcat, which resides on HTTP port 8080! You are running your application in J2EE!

Building and running your application are only part of the story. None of us are perfect coders, and there will always be bugs in our code. So, in order to make a proper production application, you also need to debug and inspect your code at runtime. In the next section you will see how Grasshopper lets you do this. In fact you can debug your Java code while it is executing, using the Visual Studio .NET debugger!

Debugging your J2EE Commerce Starter Kit from Visual Studio

 

 

Figure 9. Debugging a Java Application using the Visual Studio.NET IDE.

You�ve now got a true J2EE application, packaged and deployed on Tomcat. It might sound like debugging it from the Visual Studio .NET debugger isn�t possible � but in fact it is easy! If you went through the porting tutorial, most chances are you did not even stop to think about it. You probably just placed break points in the code and stepped through them, like you are used to with the Visual Studio.NET editor [Figure 9].


 

 

Figure 10. Integrated Java debugging using the Visual Studio.NET debugger.

Here is how it works - Grasshopper replaces the underlying .NET debugger with its own debugger agent, leaving the Visual Studio.NET debugger interface intact:

When you place a breakpoint in your J2EE project C# code, the Grasshopper debugger agent kicks in. It knows how to translate your breakpoint request into the right breakpoint in the generated Java code and how to �ask� the Java debugger to set up the break point. Furthermore, because the Grasshopper debugger agent uses the standard Java Debugger Wire Protocol (JDWP) to drive the Java debugger [Figure 10], you can debug your J2EE application even when it is running remotely on a different machine!

The result - you continue to use the familiar Visual Studio debugger interface while Grasshopper worries about interacting with the Java debugger on your behalf. This arrangement allows you to utilize your knowledge of the Visual Studio.NET debugger to directly debug true Java code, without the need to learn how to use a Java debugger!

Where can you go from here?

Since the application you build with Grasshopper is a standard J2EE application, you can deploy it anywhere you have a J2EE application server. With Grasshopper, your target J2EE application server can even be a Linux system. We have already seen that Grasshopper supports remote debugging. This means that you can debug your Grasshopper J2EE application while it is executing on a Linux machine, from within the Visual Studio .NET IDE on your development machine!

Take note that if you want your database tier to also run on Linux, you must use a database application that runs on Linux. So, if like in the Commerce Starter Kit application, your data layer resides on Microsoft SQL Server, which isn�t available for Linux, you will have to migrate your data to a different database such as PostgreSQL (which comes bundled with Grasshopper for your convenience). You can see how the database migration was done with the Commerce Starter Kit here. Of course, if you prefer your database tier to remain on Windows, while your database access, enrichment logic and presentation tier move to J2EE on Linux, you can still do this using Grasshopper.

Conclusions

In this paper you took the Commerce Starter kit application from Microsoft and, using Grasshopper, ported it from an application that runs on .NET to one that works with the J2EE specification. You didn�t have to write a line of custom Java code to do it, and the source code for your Java version is the same as the source code for your .NET -based version. This was done despite the challenges that stand in the way of porting an existing application that runs on the .NET framework to the J2EE environment.

Some of these challenges are:

  • C# and VB.NET to Java language gap � While on the surface the languages can look syntactically similar, the Java compiler cannot compile C# or VB.NET into Java bytecode that runs on the JVM. Therefore you are stuck with a gap between languages that needs to be translated!
  • .NET framework dependencies in the J2EE environment - Your application is more than just your source code � it is also the dependencies that the source code uses. .NET Applications use classes from the .NET framework. These aren�t available on the J2EE environment, so you have a major gap here that needs to be bridged.
  • The single source challenge - If you have to support your application on two different frameworks � and you translate from one language and one set of dependencies to the other, you end up with two sets of source code that have to be consistently maintained.
  • Lowering the learning curve - Ideally, you would want to invest less in learning how to port and more in doing the real work of developing and porting your application. If you have to port your application to another environment, it would be very useful if you could minimize the learning curve to get there.

At first glance, it might seem very difficult and expensive to accomplish any port with these challenges. As shown by this example, Grasshopper hops past these problems, and makes it easy to port without worrying about language gaps, dependencies, or forking sets of source code.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here