Metagnostic
home

JNIPort for Dolphin Smalltalk

Overview

Contents

Players

Layers

Examples

Configuration

InFAQ

Changes

Licence


Back to Goodies

Infrequently Asked Questions

This section is a miscellany of observations and explanations that don't seem to fit anywhere else.

Why is JNIPort so complicated ?

I hope that most of the complication is on the inside; in the implementation rather than the in API for users.

However, JNIPort is certainly bigger and more complicated than I thought it was going to be when I started it (in fact I wouldn't have started if I'd known how big it was going to grow).

I think that a lot of the complexity is a reflection of the complexity of Java's semantic model, and a great deal of the complexity of the implementation is caused by the shear clunkyness of Java and the JVM at the low level. Don't get me wrong; I like Java as a programming language (though I much prefer Smalltalk) but when you get into the details of the model, and the details of the JVM and JNI, then there are a great many rough edges — sometimes it has seemed that there's nothing but rough edges.

Why isn't the JVM object a proper Singleton ?

Mainly because the JNI API is structured to allow multiple JVMs, either together or one after another. Also I suspect that I'm going to want additional JVM-like objects in future, and while it's not hard to add a Singleton facade to an non-Singleton API, unpicking an early design decision to use Singletons can be much more work.

Why have class statics instead of putting the “static” methods on the Smalltalk class-side ?

That would be using long-lived Smalltalk objects (classes) to stand for short-lived Java “objects” — the representation of a Java class in a Java runtime. I don't like the idea; the semantics don't match and the implementation would be unnatural. At minimum it would require a Singleton JVM, since the Smalltalk class would have to be able to find a JVM in order to call the Java methods.

In fact the ghost class concept does tie the life of the class to the life of the Java session, and so would allow me to put the static methods onto the class-side of the ghost instance classes. I keep being tempted to follow that route. I don't think it would work, though; it'd be adding a great deal of behaviour to Smalltalk classes that has nothing to do with their normal role. (And there'd be practical problems too, for instance would #name answer the name of the Smalltalk class or the Java class ?)

Class statics are always paired with class objects, so why have class statics as separate objects at all ?

Early versions of JNIPort didn't separate the roles of class statics and class objects, but I found that it wasn't working. The dual role — acting as a proxy for both the instance of java.lang.Class and the Java class — was confusing. It also lead to massive overcomplication of JavaLangClass; amongst other things, requiring it to have different subclasses for the different kinds of type (class, interface, array, primitive).

Why use Ghost Classes rather than DNU handling ?

One reason is just that I don't like using DNU to implement special message handling. It's fragile (you can't use DNU to override the implementation of an existing inherited method) and it is potentially slow (depending on the complexity of the runtime lookup/handling you want to do). In the context of JNIPort, both of these potential problems are real issues:

  • In Java, constructors aren't inherited; so the wrapper for a subclass should not inherit factory methods from the wrapper for the superclass.
  • Translating from the Smalltalk selector to the corresponding Java method name and signature would either be slow or complex (possibly both). Using ghost classes, the lookup is done once, as the class is created, and thereafter is entirely inline. Calling a Ghost method is, in fact, usefully faster than calling a non-ghost method; and that in turn is probably faster than DNU handling would be.

Why doesn't JNIPort automatically convert returned Java Strings into Smalltalk Strings in the same way as it coerces String parameters from Smalltalk to Java ?

Efficiency, mostly. Converting a Java string to Smalltalk is relatively expensive, especially if the String is big. JNIPort doesn't know what you are going to do with the String, quite possibly just pass it back to another Java method, so it doesn't convert it until you tell it to.

There's also the issue that converting the Java string into Smalltalk would drop the reference to the Java string, and possibly loose its identity, resulting in a copy being made when a duplicate reference was intended.

And lastly, there's the point that not all legal Java Strings can be represented in Dolphin; not until it gets real Unicode strings. (But when it does, they presumably will be real Unicode, and support characters outside the 16-bit range, so the same problem will exist, but in reverse. Sigh…)

Why doesn't JNIPort automatically convert Smalltalk ByteArrays into Java byte[] arrays in the same way as it converts Smalltalk Strings into Java ?

Because arrays are mutable; if Java Strings were mutable then JNIPort wouldn't be able to coerce those either.

JNIPort has no way of knowing what the array is gong to be used for. If the Java method only read from the array, then it'd be safe to create a Java byte[] from the Smalltalk ByteArray. However if the Java method was going to write to the array, then the call would seem to work, but the method would be updating a temporary array that would be discarded as soon as it returned. Thus causing puzzlement…

By the way, at one point JNIPort did do this kind of conversion, but when I started using java.io.OutputStream.read(byte[]) I realised that it was just too confusing, and removed the feature.

Arguably, JNIPort could convert Smalltalk Integers into java.lang.Integers, and so on, but it hasn't seemed worth it so far. Similarly we could recognise the new “varadic” methods and automatically create Java java.lang.Object[] arrays to hold their parameters.


Copyright © Chris Uppal, 2003-2005

Java, JNI (probably), JVM (possibly), and God knows what else, are trademarks of Sun Microsystems, Inc.