|
JNIPort for Dolphin Smalltalk |
||||||||||||||||||||||||||||||||
Back to Goodies |
Names of Generated Wrapper MethodsThe topmost level of JNIPort is capable of generating wrapper Smalltalk classes for existing Java classes. The wrapper class has automatically-generated methods that allow you to use the Java object as if it were a Smalltalk object. The generated methods are of two kinds:
In both cases, the name of the Smalltalk method is determined by following a set pattern. The rest of this section describes the pattern in detail, but first, here are a few examples:
Field access is via generated “getter” and “setter” methods:
Constructors are methods on the class static, here are some examples from java.lang.String:
Names for Forwarding MethodsGiven a Java class, each of its methods is fully identified by a combination of its name and its signature — the name alone is not enough (since method names can be overloaded). Hence, to identify a specific method, we need:
In practice, the method's return type can be ignored since Java does not allow overloading on return type (although the JVM itself does). So, we can think of a Java method's “full” name as being somehow composed of its normal name and the types of any arguments. The names of generated Smalltalk methods follow this thinking. (By the way, if you are using a version of Java that supports so-called “generics” then you will need to know that generics are invisble to the Java runtime (they are merely a hack implemented entirely in the Java compiler), and so they are invisible to JNPort too. The types seen by the Java runtime are what determine the correct names to use, and they are the names of the generic types after “erasure”. If you think that's messy or awkward, then I agree with you, but it's not my fault — Sun have done everyone a disservice by introducing the underpowered, overcomplicated, and largely pointless hack into the language.) The general pattern is that a Java method called, say, “aMethod()”, with arguments of types “Type1”, “Type2”, and “Type3”,
will be represented by a Smalltalk method with selector
In more detail:
If the Java method is called If the Java method, called 'aMethod', has one or more arguments, then the Smalltalk method's selector will be formed by starting with 'aMethod_' and then appending a segment for each of the arguments. Each segment will be the name of that argument's type, simplified by following the rules below. If the type is a primitive, then the segment will just be the name of that primitive. Note: the case is not changed, so a Java method like:
would be represented by a Smalltalk method called
If the type is a class or interface, then the segment is the short name of that class or interface (i.e. not fully qualified). E.g. a Java method like:
would be represented by a Smalltalk method called
If the type is an array type, then the segment is formed by appending 'Array' to the base-type name as many times as necessary. E.g: a Java method like:
would be represented by a Smalltalk method called:
Names for Accessor Methods
Access to fields of Java objects is via generated Smalltalk accessor methods.
Given a variable called 'aField', the generated getter and setter methods in
Smalltalk are called Names for Static MembersUsing static members (class side fields and methods) follows exactly the same pattern as instance-side members. The difference is that the Smalltalk methods are defined on a “class static” object that stands for the Java class. See Class Statics for more detail. It's worth mentioning that, because of this, there is never any ambiguity between class-side and instance-side members. Names for ConstructorsThese are treated like static methods called “new”. E.g. the Java constructor for a java.lang.String from an array of chars:
is represented by a method on the String class static called
Handling AmbiguityIt is possible for more than one Java method to map onto the same Smalltalk selector. It is impossible to fix the problem in general (without making the scheme too verbose or complicated to use), but the most common cases can be fixed. One way ambiguity occurs is when there are two versions of a class or interface with the same name in different packages. If a method is overloaded to handle both of these cases (a not unreasonable situation) then JNIPort will try to generate two corresponding Smalltalk wrapper methods with the same selector. (Since the two argument types have the same short name). Other ways of getting ambiguity can also be invented; I leave it as an exercise for the reader… If JNIPort finds that it is generating two methods with the same selector, then it attempts to get around the problem as follows. Firstly it tries using the long forms of all the type names. So if the Java class had two methods like:
then JNIPort would generate a method called If that does not resolve the ambiguity then JNIPort will generate even longer selectors that also include the return type of the method, so that:
would be wrapped as This is already getting to the point of being unusable, so if even that doesn't work then JNIPort just gives up. In the current implementation, it will generate both wrapper methods in the longest form, and so one of them (arbitrarily chosen) will overwrite the other. It would probably be better if it didn't generate either of them in this case, so the current behaviour should be considered to be a bug. Rather surprisingly, the JVM allows classes to have multiple fields with the same name, provided that they are of different declared types. The Java compiler won't let you do it, but it is perfectly legal for JVM classfiles. In this case JNIPort will use the same kinds of techniques as it does for avoiding ambiguous selectors for forwarding methods (arguably, this is overkill). So if the Java class had fields like (this is not legal Java):
then JNIPort will generate two getter methods with names:
If this sort of thing happens to you in practice, then you can always fall back to the Java Base and write your own wrapper methods with whatever names you want. |
Copyright © Chris Uppal, 2003-2005
Java, JNI (probably), JVM (possibly), and God knows what else, are trademarks of Sun Microsystems, Inc.