# Friday, 15 August 2003
« Workarounds | Main | More discussion on netexp and Class.forN... »
More on interaction with .NET types

In yesterday's item I didn't do a good job of explaining the issue, so today I'll try again and respond to the comments as well.

First, let me start by explaining the current situation. There are two ways to get access to a .NET type:

  • netexp
    When you run netexp on a .NET assembly it generates Java classes for all public .NET types in the assembly. The Java classes contain no code, they're just stubs so that you can use a regular Java compiler to code against .NET types. When IKVM.NET loads such a stub, it notices that the class file contains a special attribute that says "this is a netexp stub class, please redirect to .NET type such-and-such". Note that the attribute contains an assembly qualified type name, because in general you can only load a type in .NET when you have its assembly qualified name.
  • Class.forName()
    Calling Class.forName() with an assembly qualified name will cause a .NET type to be loaded. The name of the class that is returned is the full name (i.e. not including the assembly part).

There are several problems with the current approach:

  • The name of a class loaded doesn't match with the name it was loaded with.
  • A type can be loaded under different names.
  • The class literal (which is compiled using Class.forName()) for netexp generated classes only works if the netexp generated class is in the classpath (even if the code was statically compiled).

Stuart commented:

Have you considered only lowercasing the "system" namespace and no others? Or perhaps (to be really safe) only lowercasing top-level namespaces that match the name of a class in java.lang?

Also, would it be possible for the implementation of Class.forName to do remapping of classnames from normal java ones to assembly qualified ones? If so, would that solve the problem? (I'm not entirely sure I understand what the problem is, so I'm not sure)

Only lowercasing the system namespace isn't really a generic solution, because any .NET namespace that is the same as a Java class in the java.lang package would cause problems. Treating all names in the java.lang package specially feels like a kludge. Using a special prefix like Brian suggets would be a better idea.

In regards to the second point, in .NET you really need to have an assembly qualified name for a type. Searching all available assemblies isn't feasible.

I responded to Stuart:

One of the problems is that all .NET types are loaded by the bootstrap class loader, so they have to have distinct names.

I just had an another idea. It might be a good idea to encode the assembly qualified name in the package. For example for the System.String type:

assembly.mscorlib.1.0.5000.0.neutral.b77a5c561934e089.System.String

This has the advantage that you can use "import" in most cases (although not for String) to use the short name.

I have to think about it, but I think I like it.

After thinking about it some more, I still really like this idea. It has three huge advantages: 1) There is a natural bi-directional mapping between the class name and the .NET type name, 2) Both netexp and Class.forName can use the same naming scheme and 3) The netexp generated classes aren't needed at runtime (or ikvmc compile time).

In response to my response Stuart commented:

Hmmm... how fundamental a rearchitecting would it take to have a classloader per assembly? Then there would be a trivial isomorphism between Java's "names are unique within a classloader" and .NET's "names are unique within a strongly-named assembly", if I'm understanding correctly.

Having a class loader per assembly is tempting, but it doesn't solve the issue of finding the .NET type (you still need to know in what assembly a type lives). This would be solvable by introducing a new API to get a class loader corresponding to an assembly, but that obviously has the downside that it doesn't interoperate very well with existing Java code. For example, the IKVM.NET AWT implementation lives in a .NET assembly (written in C#) and is loaded by GNU Classpath using Class.forName(). This only works if Class.forName() has enough information about the assembly.

Brian Sullivan commented:

I don't care for the occasional lowercasing ideas.

It could be that all .NET classes would begin with NET. from the Java perspective.

NET.System.String
NET.Some.Other.Class

import NET.*; // import all of .NET

This makes it clear where the class is defined and clearly separates all of .NET into its own package.

The prefixing is a good idea to get around the System name clash. BTW, import NET.* doesn't hierarchically import all packages, but only the classes in the NET package.

Does anyone have anything against the newly proposed name mangling scheme? Obviously the details need to be worked out (my proposed package name above doesn't actually compile), but what about the general idea?

Friday, 15 August 2003 15:09:27 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3] Tracked by:
"Poker online for free" (Poker online for free) [Trackback]