1



1. Overview

Microsoft has generated a great deal of interest with its newly developed “.NET” products. With the .NET initiative, Microsoft aims at providing developers the ability to capture the power of the Internet. .NET is a general purpose platform that allows users to design, develop, deploy and use web based applications in a uniform and efficient manner. According to Microsoft, .NET will “transcend device boundaries and fully harness the connectivity of the Internet”. The obvious competitor to .NET is Sun Microsystems’s J2EE development platform. There are some obvious similarities between the two platforms as well as incredible differences in some areas. Our objective here is to research and analyze a few functionalities and modules of .NET and J2EE. The areas we will specifically discuss include programming language capabilities and interactions, data access abilities, security issues, and middleware connectivity and interoperability.

2. Introduction

.NET has an interesting history:

1993: In the beginning, there was COM.

1996: Along came Java

1997: COM continued to evolve: MTS, COM+

1998: XML enters the picture

2000: .NET, the latest evolution of COM

Microsoft’ .NET initiative brings so many great changes that the software developers, architects and the managers are all experiencing a fundamental tectonic shift. It has created difficulties to adapt to in the short run, but aims at enabling the windows developers to build more powerful, more useful software more efficiently in the long run. .NET brings a language agnostic model, a managed execution environment, JIT compilation, and rich library support. Microsoft’s .NET can be summarized as a “brand applied to a wide range of technologies”. These technologies include:

The .NET Framework:

For developers, this framework is the most important part of .NET. Though it can be described as a successor to the Windows DNA (Distributed interNet applications Architecture), the process of windows development is greatly simplified because of the presence of the Common Language Runtime (CLR) and the .NET Framework class library.

The CLR defines a common set of semantics that is used by multiple languages. Visual which is Microsoft’s primary tool for building .NET framework applications supports four CLR-based languages: Visual , C#, Managed C++ and . There is also some third party demonstrated support for other languages built on CLR like Perl, Python and COBOL. CLR also provides other common services such as Garbage Collection and standard format for Metadata (the managed code is compiled into MSIL, i.e. Microsoft Intermediate Language), and Assemblies (conceptually similar to JAR files) for organizing compiled codes (DLLs or EXEs).

The .NET Framework class library provides the standard code for the common functions. The .NET framework written in any language can use and access system services in a same way. Among the most important technologies that this framework provides include (key feature for building applications that use web services), (next generation ActiveX Data Objects for accessing data stored in relational DBMSs and other formats), Windows Forms (a standard set of classes for building windows GUI in any .NET Framework programming languages), Enterprise Services (standard classes for accessing COM+ services such as transactions and object pooling).

Web Services:

The .NET Framework is the programming model for developing, deploying, and running XML Web services and applications that all underlies .NET. XML Web services are units of code that allow developers to write programs in different languages and use different platforms to communicate through standard Internet protocols like XML, WSDL (Web Services Description Language to define the interfaces to web services), SOAP (Simple Object Access Protocol to invoke the operations in those interfaces) and UDDI (Universal Description, Discovery and Integration to let clients find compatible servers).

3.0 .NET Languages and Java

J2EE offers only Java as the only language for the platform, while .NET platform offers a number of languages for programmers to write code in, namely, C#, , Jscript and Managed C++. To state in their words, it is a Language-Agnostic Model. Though the environments take radically different views considering the languages in general, they coalesce nicely when it comes to C# and Java.

The C# language is an object-oriented language that lets the programmers to quickly build a wide range of applications for the Microsoft .NET platform. The goal of C# and the .NET platform is to shorten development time by freeing the developer from worrying about several low level plumbing issues such as memory management, type safety issues, building low level libraries, array bounds checking, etc. thus allowing developers to actually spend their time and energy working on their application and business logic instead. As a Java developer the previous sentence could be described as "a short description of the Java language and platform" if the words C# and the .NET platform were replaced with words Java and the Java platform.

Background

In June 2000, Microsoft announced a new programming language called C# along with the .NET platform. C# is a strongly typed object-oriented language designed to give the optimum blend of simplicity, expressiveness, and performance. As stated earlier, the .NET platform is centered on a Common Language Runtime (similar to the JVM) and a set of libraries, used, by a wide variety of languages, which are able to work together by all compiling to an intermediate language (IL). The C# language was built with the hindsight of many languages, but most notably Java and C++. It was co-authored by Anders Hejlsberg (who is famous for the design of the Delphi language), and Scott Wiltamuth. The most popular tool for creating C# code is Microsoft’s Visual , though Microsoft also provides a command-line complier with the .NET Framework called csc.exe and there is also another C# complier developed by the open source world.

3.1 Differences and Similarities (C# vs. Java)

A major part of our effort was concentrated on understanding the C# language, its various features and comparing it to java with fallacies and benefits of each. Java and C# are two big languages, and though programmers from both camps find understanding the other easy, there are some subtle differences between the two. As far as the languages are concerned the differences can be divided into 4 parts informally:

There are some features, which are exactly similar in both languages like Runtime environments, Garbage Collection, Interfaces, Strings and Unextendable classes. While some features differ only in small ways or a syntax like Inheritance, Access Modifiers, Reflection. Some features have some major conceptual differences like Nested Classes, Threads, Operator Overloading, Serialization, and Documentation generation. A few features of C# with no counterparts in Java are Deterministic Object Cleanup, Delegates, Boxing, Pointers and Unsafe Code, Pass by Reference. While, there are certain Java features having no look-alikes in C#, like Extensions, Checked Exceptions, Dynamic Class Loading, Anonymous Inner Classes and above all Cross Platform Portability.

We have tried to look into a few areas out of those cited above, and analyzed how C# shape up in those areas, and compare the approaches of both languages when they both provide those features, and analyze the reasons why certain features don’t have their counterparts.

3.1.1 Class hierarchy

Both Java and C# have a single rooted class hierarchy where all the classes in C# are subclasses of System.Object and all Java classes are subclasses of java.lang.Object. In both the languages the methods of the Object classes share some similarities (e.g. System.Object's ToString() to java.lang.Object's toString()) and differences (System.Object does not have analogs to wait(), notify() or notifyAll() in java.lang.Object).

3.1.2 Execution environment

Just like Java is typically compiled to Java byte code which then runs in managed execution environment (the Java Virtual Machine) so also is C# code compiled to an Intermediate Language (IL) which then runs in the Common Language Runtime (CLR). Both platforms support native compilation via Just In Time compilers. However, one of the key differences between C#’s IL design and Java byte code is that C# code is never interpreted; it is always natively complied, unlike Java where code is interpreted first and then natively compiled. This was just a design decision made to make the translation of IL into native code easier. It changes which instructions are included, what type information is included, and how it is conveyed. Thus the two ILs are different, the IL in C# is more type-neutral. There's no information in the instructions that specifies the type of the arguments. Rather, that is inferred by what's been pushed on the stack. This approach makes the IL more compact because a JIT compiler has that information anyways, so there's no reason to carry it along in the instructions.

3.1.3 Object creation

In Java objects are created on the heap using the new keyword. Most classes in C# are created on the heap by using the new keyword. Also, just as the JVM manages the destruction of objects, so also does the CLR via a Mark and Compact garbage collection algorithm. Additionally, C# also supports stack-based classes called Value-types. In Java, only the primitives are created on the stack. Thus, objects that are used similarly to primitives in a program hang around and wait for garbage collection thus adding overhead to the program, especially if the objects were used briefly and in a single location. To avoid the problem of allocating heap space for such classes and then having to garbage collect them, C# has a mechanism that allows one to specify that objects of a certain class should be stack based (In fact, C#'s built-in types such as int are actually implemented as structs in the runtime library). Unlike classes, value types are always passed by value and are not garbage collected. And arrays of value types contain the actual value type objects, not references to dynamically allocated objects, which yield a savings of both memory and time.

3.1.4 Namespaces

A C# namespace is a way to group a collection of classes similar to Java's package construct. Though both are conceptually same, they are implemented differently. In Java, the package names dictate the directory structure of source files in an application whereas in C# namespaces do not dictate the physical layout of source files in directories only their logical structure. This complete separation between physical packaging and logical naming gives more flexibility to package things together in physical distribution units without forcing the use of a bunch of directories. In the language itself, there are clearly some differences. In Java, the packaging is also the physical structure, and because of this a Java source file has to be in the right directory and can only contain one public type or one public class. In C#, source files can be given any names, can contribute to multiple namespaces and can take multiple public classes. Further, one can write all of the sources in one big file, or can spread them across smaller files. Conceptually, what happens with C# at compilation is that one gives the compiler all of the source files that make up one’s project and then it just goes off and figures out what to do.

3.1.5 Access modifiers

|C# access modifier |Java access modifier |

|Private |Private |

|Public |public |

|Internal |protected |

|protected |N/A |

|internal protected |N/A |

The table below shows the mapping between C# access modifiers to that of Java. C#’s protected keyword has the same semantics as the C++ version, different than the semantics of the protected keyword in Java. This means that a protected member can only be accessed by member methods in that class or member methods in derived classes but is inaccessible to any other classes. The internal modifier means that the member can be accessed from other classes in the same assembly as the class. The internal protected modifier means that a member can be accessed from classes that are in the same assembly or from derived classes. The default accessibility of a C# field or method when no access modifier is specified is private while in Java it is protected (except that derived classes from outside the package cannot inherit the field).

3.1.6 Reflection

The ability to discover the methods and fields in a class as well as invoke methods in a class at runtime, typically called reflection, is a feature of both Java and C#. The primary difference between reflection in Java versus reflection in C# is that reflection in C# is done at the assembly level while reflection in Java is done at the class level. Since assemblies are typically stored in DLLs, one needs the DLL containing the targeted class to be available in C# while in Java one needs to be able to load the class file for the targeted class. The examples below which enumerate the methods in a specified class should show the difference between reflection in C# and Java.

C#

using System;

using System.Xml;

using System.Reflection;

using System.IO;

class ReflectionSample {

public static void Main( string[] args){

Assembly assembly=null;

Type type=null;

XmlDocument doc=null;

try{

// Load the requested assembly and get the requested type

assembly=Assembly.LoadFrom("C:\\WINNT\\\\Framework\\v1.0.2914\\System.XML.dll");

type = assembly.GetType("System.Xml.XmlDocument", true);

//Unfortunately one cannot dynamically instantiate types via the Type object in C#.

doc = Activator.CreateInstance("System.Xml","System.Xml.XmlDocument").Unwrap() as XmlDocument;

if(doc != null)

Console.WriteLine(doc.GetType() + " was created at runtime");

else

Console.WriteLine("Could not dynamically create object at runtime");

}catch(FileNotFoundException){

Console.WriteLine("Could not load Assembly: system.xml.dll");

return;

}catch(TypeLoadException){

Console.WriteLine("Could not load Type: System.Xml.XmlDocument from assembly: system.xml.dll");

return;

}catch(MissingMethodException){

Console.WriteLine("Cannot find default constructor of " + type);

}catch(MemberAccessException){

Console.WriteLine("Could not create new XmlDocument instance");

}

// Get the methods from the type

MethodInfo[] methods = type.GetMethods();

//print the method signatures and parameters

for(int i=0; i < methods.Length; i++){

Console.WriteLine ("{0}", methods[i]);

ParameterInfo[] parameters = methods[i].GetParameters();

for(int j=0; j < parameters.Length; j++){

Console.WriteLine("Parameter:{0}{1}",parameters[j].ParameterType, parameters[j].Name);

}

}//for (int i...)

}

}

Java

import java.lang.reflect.*;

import org.w3c.dom.*;

import javax.xml.parsers.*;

class ReflectionTest {

public static void main(String[] args) {

Class c=null;

Document d;

try{ c=DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().getClass();

d = (Document) c.newInstance();

System.out.println(d + " was created at runtime from its Class object");

}catch(ParserConfigurationException pce){

System.out.println("No document builder exists that can satisfy the requested configuration");

}catch(InstantiationException ie){

System.out.println("Could not create new Document instance");

}catch(IllegalAccessException iae){

System.out.println("Cannot access default constructor of " + c);

}

// Get the methods from the class

Method[] methods = c.getMethods();

//print the method signatures and parameters

for (int i = 0; i < methods.length; i++) {

System.out.println( methods[i]);

Class[] parameters = methods[i].getParameterTypes();

for (int j = 0; j < parameters.length; j++) {

System.out.println("Parameters: " + parameters[j].getName());

}

}

}

}

The above code samples demonstrate that there is slightly more granularity in the C# Reflection API than the Java Reflection API because C# has a ParameterInfo class which contains metadata about the parameters of a Method while Java uses Class objects for that purpose which lose some information such as the name of the parameter. Sometimes there is a need to obtain the metadata of a specific class encapsulated as an object. This object is the java.lang.Class object in Java and the System.Type object in C#. To retrieve this metadata class from an instance of the target class, the getClass() method is used in Java while the GetType() method is used in C#. If the name of the class is known at compile time then one can avoid creating an instance of the class just to obtain the metadata class by doing the following.

C#

Type t = typeof(ArrayList);

Java

Class c = java.util.Arraylist.class; /* Must append ".class" to fullname of class */

3.1.7 Serialization and documentation

Object Persistence also known, as Serialization is the ability to read and write objects via a stream such as a file or network socket. Object Persistence is useful in situations where the state of an object must be retained across invocations of a program. Usually in such cases simply storing data in a flat file is insufficient and using a Database Management System (DBMS) is overkill. Serialization is also useful as a means of transferring the representation of a class in an automatic and fairly seamless manner. Serializable objects in C# are annotated with the Serializable attribute. The NonSerialized attribute is used to annote members of a C# class that should not be serialized by the runtime. Such fields are usually calculated as temporary values that have no meaning when saved. C# provides two formats for serializing classes; either as XML or in a binary format, the former is more readable for users and applications while the latter is more efficient. One can also define custom ways an object is serialized if the standard ways are insufficient by implementing the ISerializable interface. In Java, serializable objects are those that implement the Serializable interface while the transient keyword is used to mark members of a Java class as ones not to be serialized. By default Java supports serializing objects to a binary format but does provide a way of overriding the standard serialization process. Objects that plan to override default serializations can implement methods with the following signatures

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;

private void writeObject(java.io.ObjectOutputStream stream) throws IOException

Since the above methods are private there is no interface that can be implemented to indicate that a Java class supports custom serialization using readObject and writeObject. For classes that need publicly accessible methods for custom serialization there exists the java.io.Externalizable interface which specifies the readExternal() and writeExternal() for use in customizing how an object is read and written to a stream.

C#

using System;

using System.IO;

using System.Reflection;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

using System.Runtime.Serialization.Formatters.Soap;

[Serializable]

class SerializeTest{

[NonSerialized]

private int x;

private int y;

public SerializeTest(int a, int b){

x = a;

y = b;

}

public override String ToString(){

return "{x=" + x + ", y=" + y + "}";

}

public static void Main(String[] args){

SerializeTest st = new SerializeTest(66, 61);

Console.WriteLine("Before Binary Write := " + st);

Console.WriteLine("\n Writing SerializeTest object to disk");

Stream output = File.Create("serialized.bin");

BinaryFormatter bwrite = new BinaryFormatter();

bwrite.Serialize(output, st);

output.Close();

Console.WriteLine("\n Reading SerializeTest object from disk\n");

Stream input = File.OpenRead("serialized.bin");

BinaryFormatter bread = new BinaryFormatter();

SerializeTest fromdisk = (SerializeTest)bread.Deserialize(input);

input.Close();

/* x will be 0 because it won't be read from disk since non-serialized */

Console.WriteLine("After Binary Read := " + fromdisk);

st = new SerializeTest(19, 99);

Console.WriteLine("\n\nBefore SOAP(XML) Serialization := " + st);

Console.WriteLine("\n Writing SerializeTest object to disk");

output = File.Create("serialized.xml");

SoapFormatter swrite = new SoapFormatter();

swrite.Serialize(output, st);

output.Close();

Console.WriteLine("\n Reading SerializeTest object from disk\n");

input = File.OpenRead("serialized.xml");

SoapFormatter sread = new SoapFormatter();

fromdisk = (SerializeTest)sread.Deserialize(input);

input.Close();

/* x will be 0 because it won't be read from disk since non-serialized */

Console.WriteLine("After SOAP(XML) Serialization := " + fromdisk);

Console.WriteLine("\n\nPrinting XML Representation of Object");

XmlDocument doc = new XmlDocument();

doc.Load("serialized.xml");

Console.WriteLine(doc.OuterXml);

}

}

Java

import java.io.*;

class SerializeTest implements Serializable{

transient int x;

private int y;

public SerializeTest(int a, int b){

x = a;

y = b;

}

public String toString(){

return "{x=" + x + ", y=" + y + "}";

}

public static void main(String[] args) throws Exception{

SerializeTest st = new SerializeTest(66, 61);

System.out.println("Before Write := " + st);

System.out.println("\n Writing SerializeTest object to disk");

FileOutputStream out = new FileOutputStream("serialized.txt");

ObjectOutputStream so = new ObjectOutputStream(out);

so.writeObject(st);

so.flush();

System.out.println("\n Reading SerializeTest object from disk\n");

FileInputStream in = new FileInputStream("serialized.txt");

ObjectInputStream si = new ObjectInputStream(in);

SerializeTest fromdisk = (SerializeTest)si.readObject();

/* x will be 0 because it won't be read from disk since transient */

System.out.println("After Read := " + fromdisk);

}

}

Both C# and Java provide a mechanism for extracting specially formatted comments from source code and placing them in an alternate document. These comments are typically API specifications and are very useful way to provide API documentation to the users of a library. The generated documentation is also useful to share the specifications for an API between designers, developers and QA.

Javadoc is the tool used by Java to extract API documentation from source code. Javadoc generates HTML documentation from the source code comment, an example of which is the Java 2 Platform, Standard Edition API Documentation25 which was all generated using Javadoc. Javadoc can be used to describe information at the package, class, and member and method level. Descriptions of classes and member variables can be provided with the options to add references to other classes, class members and methods. With Javadoc one can document Description of the method, Exceptions thrown by the method, Parameters the method accepts, Return type of the method, Associated methods and members, Indication as to whether the API has been deprecated or not, Version of the API the method was first added. The deprecated information is also used by the compiler, which issues a warning if a call to a method marked with the deprecated tag is encountered during compilation. Javadoc also provides the following information automatically: Inherited API, List of derived classes, List of implementing classes for interfaces, Serialized form of the class, Alphabetical class listing, Package hierarchy in a tree format. Since Javadoc generates HTML documentation, it is valid to use HTML in Javadoc comments. There is support for linking the generated documentation with other generated documentation available over the web. Such linking is useful when one wants readers of the documentation to be able to read the API documentation from the related sources. Below is an example of how Javadoc comments are used.

Java

/**

* Calculates the square of a number.

* @param num the number to calculate.

* @return the square of the number.

* @exception NumberTooBigException this occurs if the square of the number

* is too big to be stored in an int.

*/

public static int square(int num) throws NumberTooBigException{}

C# uses XML as the format for the documentation. The generated documentation is an XML file that contains the metadata specified by the user with very little additional information generated automatically. The entire C# XML documentation tags have an analogous Javadoc construct while the same cannot be said for the Javadoc tags having C# XML documentation analogs. For instance, the default C# XML documentation does not have analogs to Javadoc's @author, @version, or @deprecated tags although such metadata can be generated by reflecting on the assembly, as Microsoft's documentation build process does. One could also create custom tags that are analogous to the Javadoc tags and more but they would be ignored by standard tools used for handling C# XML documentation including Visual . Also of note is that C#'s XML documentation when generated does not contain metadata about the class such as listings of inherited API, derived classes or implementing interfaces.

The primary benefit of an XML format is that the documentation specification can now be used in many different ways. XSLT stylesheets can then be used to convert the generated documentation to ASCII text, HTML, or Postscript files. Also of note is that the generated documentation can be fed to tools that use it for spec verification or other similar tasks. Below is an example of how C# XML documentation is used.

C#

///Calculates the square of a number.

///The number to calculate.

///The square of the number.

///NumberTooBigException - this occurs if the square of the number is too big to be stored in an int.

public static int square(int num){}

3.1.8 Deterministic object cleanup

To provide total control of releasing resources used by classes, C# provides the System.IDisposable interface which contains the Dispose() method that can be called by users of the class to release resources (like database or file handles) on completion of whatever task is at hand. Classes that manage resources such as database or file handles benefit from being disposable. Being disposable provides a deterministic way to release these resources when the class is no longer in use, which is not the case with finalizers in Java or C#. It is typical to call the SupressFinalize method of the GC class in the implementation of the Dispose method since it is likely that finalization by the runtime won't be needed since it will be provided explicitly via the Dispose method. C# also provides that via the using keyword releasing the resources used by classes occur in a more deterministic manner via the Dispose method. If a class is disposable, it is best to make usage of the Dispose() method idempotent (i.e. multiple calls to Dispose() have no ill effects) which can be done by providing a flag that is checked within the Dispose() method to see if the class has already been disposed or not. The example below shows a program where a class keeps a file open up until the Dispose() method is called which indicates that the file no longer needs to be open.

C#

using System;

using System.IO;

public class MyClass : IDisposable {

bool disposed = false;

FileStream f;

StreamWriter sw;

private String name;

private int numShowNameCalls = 0;

MyClass(string name){

f = new FileStream("logfile.txt", FileMode.OpenOrCreate);

sw = new StreamWriter(f);

this.name = name;

Console.WriteLine("Created " + name);

}

~MyClass(){

Dispose(false);

}

public void Dispose(){

if(!disposed){

Dispose(true);

}

}

private void Dispose(bool disposing){

lock(this){ /* prevents multiple threads from disposing simultaneously */

/* disposing variable is used to indicate if this method was called from a

* Dispose() call or during finalization. Since finalization order is not

* deterministic, the StreamWriter may be finalized before this object in

* which case, calling Close() on it would be inappropriate so we try to

* avoid that.

*/

if(disposing){

Console.WriteLine("Finalizing " + name);

sw.Close(); /* close file since object is done with */

GC.SuppressFinalize(this);

disposed = true;

}

}

}

public string ShowName(){

if(disposed)

throw new ObjectDisposedException("MyClass");

numShowNameCalls++;

sw.Write("ShowName() Call #" + numShowNameCalls.ToString() + "\n");

return "I am " + name;

}

public static void Main(string[] args){

using (MyClass mc = new MyClass("A MyClass Object")){

for(int i = 0; i < 10; i++){

Console.WriteLine(mc.ShowName());

} //for

}/* runtime calls Dispose on MyClass object once "using" code block is exited, even if exception thrown */

}//Main

}

The above idiom is practically the same as having C++ style destructors without the worry of having to deal with memory allocation woes, making it the best of both worlds. The non-deterministic nature of finalization has long been a hindrance for Java developers. This cleanup is practically the same as having C++ style destructors without the worry of having to deal with memory allocation woes, making it the best of both worlds. Calling the Dispose() method does not request that the object is garbage collected, although it does speed up collection by eliminating the need for finalization.

3.1.9 Delegates

Delegates are a mechanism for providing callback functions. Delegates are similar to the function pointers in C or functions in C++ and are useful in the same kinds of situation. One use of delegates is passing operations to a generic algorithm based on the types being used in the algorithm. Another use of delegates is as a means to register handlers for a particular event (i.e. the publish-subscribe model). To get the same functionality as C# delegates in Java, one can create interfaces that specify the signature of the callback method such as is done with the Comparable interface although this has the drawback of forcing the method to be an instance method when it most likely should be static. To use delegates, one first declares a delegate that has the return type and accepts the same number of parameters as the methods one will want to invoke as callback functions. Secondly one needs to define a method that accepts an instance of the delegate as a parameter. Once this is done, a method that has the same signature as the delegate (i.e. accepts same parameters and returns the same type) can be created and used to initialize an instance of the delegate, which can then be passed to the method that accepts that delegate as a parameter. Note that the same delegate can refer to static and instance methods, even at the same time, since delegates are multicast. The example below shows the process of creating and using an instance delegates.

C#

using System;

//delegate base

public class HasDelegates

{

// delegate declaration, similar to a function pointer declaration

public delegate bool CallbackFunction(string a, int b);

//method that uses the delegate

public bool execCallback(CallbackFunction doCallback, string x, int y)

{

Console.WriteLine("Executing Callback function...");

if (doCallback == null)

throw ArgumentException("Callback can't be null!");

return doCallback(x, y);

}

}

public class FunctionDelegates

{

public static bool FunctionFoo(string a, int b)

{

Console.WriteLine("Foo: {0} {1}", a, b);

return true;

}

}

public class DelegateTest {

public static void Main(string[] args){

HasDelegates MyDel = new HasDelegates();

//create delegate

HasDelegates.CallbackFunction myCallback =

new HasDelegates.CallbackFunction(FunctionDelegates.FunctionFoo);

//pass delegate to delegate function

MyDel.execCallback(myCallback, "Twenty", 20);

}

} // DelegateTest

In the example above the use of a static delegate shields the client programmers from having to know how to instantiate the delegate object.

3.1.10 Boxing

C# contains some pretty interesting innovations that make component development easier, such as its notions of boxing and unboxing. In situations where value types need to be treated as objects, the .NET runtime automatically converts value types to objects by wrapping them within a heap-allocated reference type in a process called boxing, while unboxing allows the value of an object to be converted to a simple value type.

3.1.11 Pointers and unsafe code

Although core C# is like Java in that there is no access to a pointer type that is analogous to pointer types in C and C++, it is possible to have pointer types if the C# code is executing in an unsafe context, with a lot of runtime checking disabled which means that the program must have full trust (granted earlier) on the machine it is running on. This is necessary particularly in situations like interfacing with the underlying operating system, during interactions with COM objects that take structures that contain pointers, when accessing a memory-mapped device or in situations where performance is critical. The syntax and semantics for writing unsafe code is similar to the syntax and semantics for using pointers in C and C++. To write unsafe code, the unsafe keyword must be used to specify the code block as unsafe and the program must be compiled with the /unsafe compiler switch.

While writing unsafe code in C#, one has the ability to do things that aren't typesafe, like operate with pointers. The code, of course, gets marked unsafe, and will absolutely not execute in an untrusted environment. To get it to execute, one has to grant a trust, and if one doesn't, the code just won't run. In that respect, it's no different than other kinds of native code. The real difference is that it's still running within the managed space. The methods one writes still have descriptive tables that tell you which objects are live, so one doesn't have to go across a marshalling boundary whenever one goes into this code. Otherwise, when one goes out to undescriptive, unmanaged code (like through the Java Native Interface, for example), one has to set a watermark or erect a barrier on the stack. One has to remarshall all the arguments out of the box. Also using objects, extra care has to be taken about which ones one touches because the GC (Garbage Collector) is still running on a different thread. It might move the object if one haven't pinned it down correctly by using some obscure method to lock the object.

C# has taken a different approach. It has integrated this into the language. Since garbage collection may relocate managed (i.e. safe) variables during the execution of a program, the fixed keyword is provided so that the address of a managed variable is pinned during the execution of the parts of the program within the fixed block. Without the fixed keyword there would be little purpose in being able to assign a pointer to the address of a managed variable since the runtime may move the variable from that address as part of the mark & compact garbage collection process.

3.2 C# and Interoperability

Apart from the language differences that C# has with Java we also looked into the issues of interoperability in C#. These we have classified into three separate sections namely, Language Interoperability, Platform Interoperability and Standards Interoperability. Since all the languages on the .NET platform have a striking resemblance, we have given Language Interoperability its own separated section where we compare .NET with Java. A part of our studies indicate that while C# scales better in terms of Language interoperability, and Java in Platform Interoperability, they both fail in terms of Standards Interoperability.

3.2.1 Platform Interoperability

Java runs on any platform that has Java VM installed on it. Java code runs as Java Virtual Machine (VT) byte codes that are either interpreted in the VM or JIT compiled, or can be compiled entirely into native code. J2EE works on any platform that has a compliant set of required platform services (EJB container, JMS service, etc.,). All of the specifications that define the J2EE platform are published and reviewed publicly, and numerous vendors offer compliant products and development environments. But J2EE is a single-language platform. Calls from/to objects in other languages are possible through CORBA, but CORBA support is not a ubiquitous part of the platform

C# presently runs only on the Windows platform. C# is implicitly tied into the IL common language runtime, and is run as just in time (JIT) compiled byte codes or compiled entirely into native code. Though the .NET core works on Windows only but theoretically supports development in many languages (once sub-/supersets of these languages have been defined and IL compilers have been created for them). .NET applications, where the code with references to the base class library, and other libraries, are loaded at runtime into the .NET execution engine, are mostly just-in-time (JIT) compiled by the .NET JIT compiler. This compiles the platform independent intermediate language opcodes to native code used by the processor where the JIT compiler is running. Using intermediate code and JIT compilation means that Microsoft has built into the framework the facility to allow .NET applications to be runnable on any operating system that supports the .NET runtime. Moreover, the remoting architecture of .NET assumes that by default objects are passed by value, that is, when an object is passed to another machine, the actual data in the object is passed and a copy of the object is initialized on the remote machine and run there. If the assembly, i.e. the package that contains the object’s code, is not present on the remote machine, that machine will download it. This passing around of assemblies works because the code in each assembly is platform independent.

A major selling point of Java technologies is that applications written in Java are portable across a number of operating systems and platforms. Sun officially supports Linux, Windows and Solaris but other vendors have implemented Java on a large range of platforms including OS/2, AIX and MacOS. Binary compatibility across platforms using similar Java versions is common except for situations involving bugs in various VM implementations.

On the contrary, presently, C# is only available on Windows. Hence some of the .NET libraries, particularly the WinForms library that depend on the minute details of the Windows API don’t run on other platforms. Efforts are being made to port it to other platforms, including Linux and FreeBSD. Linux porting is being done as part of the Mono project29 developed by Ximian while the FreeBSD implementation is a Microsoft project codenamed rotor.

A majority of the world's desktop computers, and a significant proportion of the world's mobile devices, will, however, support the .NET runtime because these computers and devices run Windows of one flavor or another. Microsoft is committed to providing .NET for all of its 32-bit operating systems as well as its 64-bit operating systems of the future. This reduces the problems that were experienced going from 16-bit Windows to 32-bit Windows, or developing CE Win32 applications when one is used to developing NT Win32 applications. However, portability between the mobile devices and the computers, both running .NET architecture is still limited. A developer still has to pay attention to facilities of the target device (e.g. the limited screen real estate on Windows CE devices makes MDI (multiple document interfaces) applications unusable), but the .NET namespace for Windowing, System.WinForms, makes developing such applications simple. As a part of the solution to this problem .NET makes componentization a requirement: separating business logic into objects separate to the UI 'presentation' code.

However, Microsoft hasn't ignored platform interoperability. The .NET libraries provide extensive capabilities to write HTML/DHTML solutions. For solutions that can be implemented with a HTML/DHTML client, C#/ .NET is a good choice. For cross-platform projects, which require a more complex client interface, Java is a good choice. .NET is Platform Independent to a limited extend.  But the platform independence of .NET is different from that of Java. Java programmers who have developed enterprise applications for open distribution have had to use some code of C/C++. Distribution of the programs is one of the major problems that one faces. Though Java claims, "You write once and Run everywhere", that is true but the hidden part of ease of use is totally ignored. Since Java does not produce PE (Portable Exectuable) files; one has to use the Command-Line JITer (java.exe urclass.class) to start-up the program. So there is the option of either creating ugly batch files or interoperate the start-up code into C/C++ to make PE files. So the option one is left with is to interoperate the start-up code into C/C++. This has 2 impacts; firstly one has to still learn C/C++ and secondly using C/C++ makes your code Platform Dependent!

On the .NET Platform files are compiled into PE files (i.e. Dll's and Exe's). These are the formats that one is already used to using. Using the .NET code is no different than using the normal machine specific code and it doesn’t require learning any new language to perform certain operations. This makes the files truly Platform Independent at least on the windows platforms. 

3.2.2 Standards interoperability

By standards interoperability we mean all the standards like databases systems, graphics libraries, Internet protocols, and object communication standards like COM and CORBA, that the language can access. C# and Java both have restricted interoperability in this respect. Because of Microsoft’s business motivations and its own role in defining many of these standards, they support some and provide less support for others which compete with their own - for instance - CORBA, competes with COM and OpenGL competes with DirectX. Similarly, Sun's Java doesn't provide as good support for Microsoft standards as it could.

C# objects, since they are implemented as .NET objects, are automatically exposed as COM objects. C# thus has the ability to expose COM objects as well as to use COM objects. This will allow the huge base of COM code to be integrated with C# projects, since NET is a framework, which can eventually replace COM.

However, Microsoft has submitted C# to ECMA with an objective to present C# to the industry as a possible standard and hence gain support in ECMA for a process that will lead to a commonly designed language, which has a common language infrastructure. By a common infrastructure it means, “the core set of class libraries that this specification entails, such that if other companies using other platforms implement it, they could reasonably expect to find those classes available to their programs”. When and if ECMA actually arrives at a standard for C# and a common language infrastructure, the result will be available under ECMA's copyright and licensing policies, which are truly open. Any customer will be able to license the ECMA C# standard, subset it, superset it without paying royalties. They'll be able take it and implement it on any platform or any device. That is something fundamentally different from SUN and other competitors who approached the standards bodies, with an intention to monopolize their proprietary languages.

Thus the .NET platform is sort of an open platform; any vendor can create a compiler for it. All languages can be ported to .NET, (someday someone might even write a Java(tm) compiler for the .NET). On the contrary in Java, one has to depend on Sun to provide the compilers. This limits the chance of open competition between third-party developers. Just like on the native platform, there are compilers for C/ C++ from many vendors like MS, Borland etc., and the choice of choosing the compiler will be in the hands of the developer as the .NET Platform also invites vendors to develop their own compilers. Since third party vendors can create compilers, they are also free to develop third-party tools, so now the Developer will get a better choice of tools to suit his needs.

4.0 J2EE and .NET database connectivity and support

Database connectivity has been a prime area of competition among the two major developers of integrated development environments. Sun Microsystems and Microsoft both have spent great deal of resources in researching ideal way to let developers connect to databases. Today, almost all applications have database backend. These backend are not necessarily compatible with the platform that the application is developed for. It is important for users to get applications that work across various platforms in a unified and flawless manner. In order to achieve this kind of connectivity, Java came up with JDBC and Microsoft has developed ODBC and ADO/. Both, JDBC and ODBC/ADO has a great and long (in terms of Software years) history. Java does not have one extensive system to do perform all data related tasks. It performs different tasks using different modules. Relational database connectivity is done using JDBC, Offline data access and Persistent objects are provided by EJB Entity Beans and there is no support provided for Hierarchical data access. On the other hand, Microsoft has included all of the above usage in one single API called .

Microsoft introduced ODBC as its first database connectivity API in 1992. ADO was introduced later on as an ActiveX Data Object. Microsoft also includes interfaces such as RDO and DAO. ADO was created as a more abstract layer of OLE-DB API. It included connection interfaces, commands and recordsets. The new .NET framework empowers ADO with connection ability to a data source that is in relational, XML or tabular form. The new ADO API is called . acts upon a “disconnected” database fashion. Since is just an interface, it needs to have an implementation. There are two implementations available.

SQL Server .NET data provider:

This implementation is specific for .NET and only interacts with SQL Server 7.0 and higher. This implementation provides very efficient data access because of its close tie to the operating system and framework.

OLE DB .NET data provider:

This implementation acts on OLE DB concept and thus contains drivers to connect to almost any database. Often, for unfavorable databases, this implementation shows low performance.

JDBC was introduced by Sun Microsystems in 1996. Java was designed to work on various operating systems and JDBC was also designed to work with many different relational databases. JDBC is an interface that needs to have a specific implementation for each database.

1) JDBC uses existing ODBC drivers for connecting to certain databases by using a JDBC-ODBC Bridge. This allows Java to use ODBC’s powerful grip on client-server application, but at the same time defeats the goal of having 100% Java applications.

2) There is a similar implementation of JDBC that only provides a wrapper around a C/C++ driver provided by the database. In other words, this implementation provides a Java class that interacts with the existing C/C++ code and uses all C++ methods. This system provides performance such as that of a C/C++ program and at the same time provides interoperability among various databases. For a 3-tiered implementation, this means that only the second tier server has to be properly configured to interact with the C/C++ driver properly.

3) JDBC also provides a 100% Java implemented implementation. This implementation is easy to use, but lacks high performance of a C/C++ driver.

The later version of JDBC also focuses on “disconnected” database activities. It provides Rowsets, which work similar to ’s datasets. It has also made changes in the way it executes SQL query. Instead of querying each SQL statement separately, it can send a block of SQL code to the server, analyze it and return several sets of tuples.

1. Differences and Similarities

There are many Differences and Similarities between Database access using J2EE or .NET. Our focus in this project is going to concentrate on three major issues relating to database access. Architecture issues are mostly related to the original design of Java vs. Microsoft’s ability to tie .NET platform with its operating systems closely. Optimization is something that the SQL code writer has to focus on more than and JDBC users. In promoting .NET, Microsoft has given a lot of focus to its new offline database utility called DataSets. DataSets are smaller version of a relational database that lie in developer’s local machine and can be easily manipulated. Java does not provide a similar functionality through JDBC. This point is going to be beneficial to Microsoft and going to appeal to a lot of developers.

4.1.1 Architecture

follows the architecture shown below:

[pic]

Figure 4.1 Architecture

has streamlined database connectivity issues by putting a middle tier of XML to interact with Web, Windows Apps or B2B applications. XML layer can in turn easily interact with Datasets and Data Adapter to gather data from the actual database. This architecture removes the requirements of needing to use different implementation for different databases, because XML can interact with any data tier.

JDBC follows the architecture shown below:

[pic]

Figure 4.2 JDBC Architecture

JDBC architecture is a little more complicated than that of . It works on the same fundamental design paradigm. It has an application layer which contains separate ResultSets and interacts with the Data tier through a middle level of Data Management. JDBC architecture does not deal with XML for its tier connections. Because of this reason, a special Connection and DriverManger objects have to be involved in making a connection. DriverManager module chooses which driver to use depending on the underlying database. DriverManager will choose an Oracle Driver if the database that the application wants to connect to is an Oracle database. If ODBC has an existing driver for a particular database, DriverManager uses that driver by passing the query through JDBC-ODBC Bridge. It is important to note that JDBC does not provide the same amount of functionality as provides. In order to achieve similar functionality, we have to also analyze and include a separate architecture for EJB with JDBC.

4.1.2 Optimization

JDBC lets you use “prepared statements” to optimize the code. Prepared statements are regular SQL statements that accept input parameters. In other words, prepared statements prevent from having to recreate and rerun each SQL statement multiple times. Prepared Statement follows a basic template of code shown below:

// Only the execution of the request changes.

PreparedStatement stmt = cnx. Preparedstatement (“Select name, first_name from gurus aged WHERE ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download