Migrating Java applications to .Net

How to convert existing Java or Visual J++ applications to J# or C#

Two paths are available for migrating Java applications to .Net: upgrade them to Visual J# .Net or convert them to Visual C# .Net. Upgrading Java applications to J# is the quickest and easiest way to port Java applications to the .Net Framework. Java developers are instantly productive on Visual J# .Net because they are already familiar with the syntax and set of class libraries.

Java applications can convert to C# using the Microsoft Java Language Conversion Assistant (JLCA). Code that calls Java APIs can convert to comparable C# code that uses the .Net Framework. The JLCA converts 90 percent of JDK-level 1.1.4 calls and emits issues in code for the other 10 percent. Each issue is linked to a topic with guidelines for modifications needed to finish the conversion.

Though converting to C# is slower than upgrading to J#, it offers more opportunities because converted applications use native .Net Framework APIs.

Download the source code that accompanies this article from Resources.

Sample Visual J++ application

As a demonstration, we have developed a sample Visual J++ (VJ++) application named CustomerDemo to port to .Net. The CustomerDemo application is modeled after a typical Java business application and uses some Java SDK APIs as well as Microsoft Java packages. CustomerDemo employs standard Java Database Connectivity (JDBC) APIs to access the SQL server to retrieve customer data. This data then transforms into hierarchical and flat views using the Java Collections API. The views are constructed by employing Microsoft Windows Foundation Classes (WFC). The following CustomerDemo parts will be detailed:

  • User interface
  • Database access
  • Common Java APIs used

User interface

CustomerDemo is a Windows application that has a Windows Form, ViewCustomer, shown in Figure 1:

Figure 1. CustomerDemo application

ViewCustomer is a com.ms.wfc.ui.Form hosting a typical set of Windows controls such as Panel, TreeView, Splitter, Edit, and Labels. It shows customers in a left-pane, hierarchical view. Countries are shown at the first level and customers at the leaf level. Clicking on each customer retrieves the detailed record of that customer data. These details include Contact and Address, shown in respective edit controls in the right pane.

Commercial applications generally have resources like icons and bitmaps stored in resource files. So, we also have an icon resource embedded in ViewCustomer Form and stored in the associated resource file ViewCustomer.resource.

Database access

We have provided the SQLData class that retrieves customer data from the Northwind database (sample database that comes with MS SQL server). SQLData accesses the database server by employing standard JDBC APIs. It connects to the database using the following code:

dbCon_ = DriverManager.getConnection(conInfo_,"","");

Country and customer data is retrieved using the following code:

stmt = dbCon_.createStatement();
rs = stmt.executeQuery(sqlQuery);
while(rs.next()){
      String countryId = rs.getString("Country");
      String companyName = rs.getString("CompanyName");
      //Package data into a Hashtable
      ...
}

Common Java APIs used

The CustomerDemo application uses common Java classes from java.util and java.lang packages. For example, it uses java.util.Hashtable to store the relationship between customers and countries. The java.util.Hashtable key is country name, and values are customers stored in a java.util.Vector. We use java.util.Enumerator to iterate the country keys and then get the associated list of customers. The relevant code is below:

Enumeration countryEnum = htCountryCompanyMap.keys();
while(countryEnum.hasMoreElements()){
String countryId = (String)countryEnum.nextElement();
      Vector companyList = (Vector)htCountryCompanyMap.get(countryId);
      ...
}

The SQLData class uses the java.lang.String and java.lang.StringBuffer classes to manipulate SQL queries. java.lang.Exception handles exceptions.

Migration to the .Net Framework

As previously mentioned, two good approaches are available to migrate existing Java applications to .Net:

  • Upgrade to J#
  • Convert to C#

Each migration path generates a different result. Table 1 shows what happens to the composition of Java projects when they migrate to .Net.

Table 1. Migration path

Java technologyUpgrade to J#Upgrade to C#
Java languageJava languageC# language
AppletNot convertedWindows Form control
JavaBeanJavaBeanC# class
Abstract Windowing Toolkit (AWT) frameAWT frameWindows Form
WFC FormWFC FormWindows Form
Compiled libraryCompiled libraryNot converted
Resource fileResX fileResX file

Upgrade to J#

Visual J# .Net consists of a Java language compiler, JDK-level 1.1.4 class libraries, and a tool to upgrade compiled Java byte code to Microsoft Intermediate Language (MSIL), which is useful for upgrading libraries to a form that can be used from .Net applications. In addition to JDK-level 1.1.4 class libraries, like other .Net-compliant languages, J# has full access to the .Net Framework and includes designers for Windows Form and Web Form development. J# offers familiar Java language syntax to build applications and services on .Net. We will now upgrade the Visual J++ CustomerDemo application to J#. We cover the following upgrade steps:

  • Visual J# Upgrade Wizard
  • Upgraded J# code
  • Upgrade issues

Visual J# Upgrade Wizard

The Visual J# Upgrade Wizard is included in the Visual J# installation with Visual Studio .Net. The Visual J# Upgrade Wizard can be invoked by opening the VJ++ project file (.vjp) in Visual Studio. We open CustomerDemo.vjp in Visual Studio to start the Visual J# Upgrade Wizard. The Upgrade Wizard asks for the type of application we want to convert as shown in Figure 2:

Figure 2. Visual J# Upgrade Wizard

We choose Windows Application and continue. We get an upgraded J# application named CustomerDemo_Net.vsproj containing the upgraded project files.

As we see in this wizard, the migration path exists for Java applications developed using JDK-level 1.1.4 class libraries. Java applications developed using JDK-level 1.1.4 class libraries can first be made part of a temporary VJ++ project. Subsequently, we can start the Upgrade Wizard from the temporary VJ++ project file and select either Console Application or Class Library.

Java applications that use higher JDK versions can also use the Upgrade Wizard to migrate the greater part of the application (business logic, JDK-level 1.1.4 classes, and most of the JDK 1.2 java.util package) automatically. The remaining Java technology can be replaced with comparable .Net APIs. Java applications using Swing should be migrated manually to Windows Forms. By copying the event-handling code in Swing Forms to the relevant Windows event handlers, most of the code can be reused.

The Upgrade Wizard also produces an upgrade report, _UpgradeReport.htm, listing relevant information and any problematic migration issues.

Upgraded J# code

J# provides a set of independently developed class libraries in .Net that offer the functionality of most JDK-level 1.1.4 class libraries and many classes in the JDK 1.2 java.util package. Therefore, the java.sql, java.util, java.lang, and com.ms.wfc packages used in our Java application upgrade to the same names in J#. Consequently, upgraded J# project CustomerDemo_Net.vsproj contains SQLData.java and ViewCustomer.java, and they look exactly like the former Java code shown in the example code snippets above. The ViewCustomer.resource file automatically converts to ViewCustomer.resX, a .Net-compatible resource file. Now we just build the upgraded J# code, run it, and see the same output as in Figure 1.

Upgrade issues

The original VJ++ form derived from com.ms.wfc.ui.Form migrates to the corresponding com.ms.wfc.ui.Form in J#. This imposes a limitation with using Windows Forms Designer for the upgraded form in Visual Studio because Windows Forms Designer cannot design forms derived from com.ms.wfc.ui.Form. So, any change in the upgraded form's user interface layout must be done manually. Alternatively, a backward approach can also work for altering upgraded, but very complex, user interfaces to meet the new requirements. We can use original VJ++ application code and the VJ++ editor to alter a form's layout. The changed form can be upgraded separately and then included in the migrated application again.

Convert to C#

C# is a native .Net language designed specifically for developing new generation .Net applications. Java applications can be migrated to C# to take advantage of the .Net Framework. In this section, we examine the process of converting the VJ++ CustomerDemo application to C#. We cover the following topics in this section:

  • Java Language Conversion Assistant
  • Converted C# code
  • Conversion issues and manual steps

Java Language Conversion Assistant

Visual Studio provides the Java Language Conversion Assistant (JLCA) to convert Java applications to C#. We launch JLCA from the File->Convert menu in Visual Studio. We choose VJ++ 6.0 Project as the conversion option shown in Figure 3:

Figure 3. JLCA wizard

We then select CustomerDemo.vjp as the source VJ++ project to convert to C#. We also choose CustomerDemo.NET as the newly converted C# project's name. We then go through the JLCA wizard's remaining steps to complete the C# conversion. We get a converted C# project CustomerDemo.csproj at the end of the conversion.

We can also convert a set of Java classes by choosing the second option in Figure 3.

Converted C# code

JLCA converts the VJ++ project and gives us a converted CustomerDemo.csproj. The project's Java classes and other files like resources in the CustomerDemo application convert to:

Table 2. Class-level VJ++ to C# conversion

JavaC#
ViewCustomer.javaViewCustomer.cs
SQLData.javaSQLData.cs
ViewCustomer.resourcesViewCustomer.resX
 

New class introduced:

SupportClass.cs

The JDK and Microsoft packages and classes used in CustomerDemo convert to:

Table 3. API-level VJ++ to C# conversion

JavaC#
java.sqlSystem.Data.Oledb
java.utilSystem.Collections
com.ms.wfc.ui.FormsSystem.Windows.Forms

java.lang.String

java.lang.StringBuffer

java.lang.Exception

System.String

System.Text.StringBuilder

System.Exception

The application's main() method converts to Main():

[STAThread]
public static void  Main(System.String[] args){
      System.Windows.Forms.Application.Run(new ViewCustomer());
}

The converted code in the data access class SQLData.java now uses ADO.Net (ActiveX Data Objects) instead of JDBC. The connectToDB() method establishes connection to the database using System.Data.OleDb.OleDbConnection():

dbCon_  = new System.Data.OleDb.OleDbConnection(conString);
dbCon_.Open();

The code for getting the record from the database is converted and uses System.Data.OleDb.OleDbCommand in place of java.sql.Statement, and System.Data.OleDb.OleDbDataReader in place of java.sql.ResultSet. The OleDbDataReader is accessed with the [] operator to get data from a column, which is similar to any normal array access. JLCA also introduces a new SupportClass to provide wrapper methods for controlling database transactions, which can be removed if not required. The converted code is below:

System.Data.OleDb.OleDbCommand stmt = SupportClass.TransactionManager.manager.CreateStatement(dbCon_);
stmt.CommandText = sqlQuery;
System.Data.OleDb.OleDbDataReader rs = stmt.ExecuteReader();
while (rs.Read()){
System.String countryId = 
      System.Convert.ToString(rs[("Country")]);
Syste.String companyId = 
      System.Convert.ToString(rs[("CompanyName")]);
...
}

Interestingly, JLCA converts the original getCountryCompany() method to a property CountryCompany of the SQLData class in C#. CountryCompany property's code is shown below:

public virtual System.Collections.Hashtable CountryCompany{
      get{
            ...
      }
}

The code to iterate java.util.Hashtable converts to System.Collections.Hashtable. Hashtable is accessed with the [] operator now. However, the converted code for iterating Hashtable does have a problem that we will manually correct in the next section. The converted code for Hashtable is:

System.Collections.IEnumerator countryEnum = (System.Collections.IEnumerator) htCountryCompanyMap.Keys;
while (countryEnum.MoveNext())
{
      System.String countryId = (System.String) countryEnum.Current;
System.Collections.ArrayList companyList = (System.Collections.ArrayList) htCountryCompanyMap[countryId];
...
}

The ViewCustomer user interface easily converts to C#. ViewCustomer Form now derives from System.Windows.Forms. The controls like TreeView, Edit, Label, and TextBox contained in ViewCustomer automatically convert. Also note that the Windows Forms Designer in C# can open ViewCustomer Form and make changes unlike the upgraded form in J#.

Conversion issues and manual steps

JLCA automatically converts much of the Java code into C# code. However, it still leaves certain issues that must be manually resolved before the converted CustomerDemo.csproj project can be compiled and run in .Net. Figure 4 shows the conversion report produced by JLCA, listing all these issues:

Figure 4. C# conversion report. Click on thumbnail to view full-size image.

Let's go through these issues and see how we can resolve them.

1 2 Page 1
Page 1 of 2