Hi there,

I'm having trouble understand part of the Java module, which is causing me issues in my application. What I am trying to do is convert between two types of a class on the C++ and Java sides (for good, but complicated, reasons there are native implementations on both sides). This is done by serializing the type into a byte array, and de-serializing it on the other side, all in Swig. My original setup for converting parameters was as follows:

%define CLASS_DIRECTOR_INPUT(CppClassType, JavaClassType, 
                             JavaClassNameWithSlashes, param_name)
%typemap(javadirectorin) CLASS_TYPE* INPUT,
"$jniinput == null ? null : convertToJavaClassType($jniinput)"
%typemap(directorin,descriptor="L"JavaClassNameWithSlashes";") CLASS_TYPE* INPUT %{
...
%}

%typemap(jni) CLASS_TYPE* INPUT "jbyteArray"
%typemap(jtype) CLASS_TYPE* INPUT "byte[]"
%typemap(jstype) CLASS_TYPE* INPUT "JavaClassType"

%typemap(javain, pre="
// Create byte[] called array$javainput here.
") CLASS_TYPE* INPUT "array$javainput"
%typemap(in) CLASS_TYPE* INPUT (CppClassType tmp) {
}
%enddef

This worked ok. However, I decided to update my approach and use JNI byte buffers. So my setup is now:

%define CLASS_DIRECTOR_INPUT(CppClassType, JavaClassType, 
                             JavaClassNameWithSlashes, param_name)
%typemap(javadirectorin) CLASS_TYPE* INPUT,
"$jniinput == null ? null : convertToJavaClassType($jniinput)"
%typemap(directorin,descriptor="L"JavaClassNameWithSlashes";") CLASS_TYPE* INPUT %{
...
%}

%typemap(jni) CLASS_TYPE* INPUT "jobject"
%typemap(jtype) CLASS_TYPE* INPUT "java.nio.ByteBuffer"
%typemap(jstype) CLASS_TYPE* INPUT "JavaClassType"

%typemap(javain, pre="
// Create ByteBuffer called byteBuffer$javainput here.
") CLASS_TYPE* INPUT "byteBuffer$javainput"
%typemap(in) CLASS_TYPE* INPUT (CppClassType tmp) {
}
%enddef


This is almost fine, except that for some reason the Swig code that generates the swig_module_init now produces broken code. For a method call that takes a CppClassType as a parameter, 'swig_1module_1init' used to generate a signature for the method like:

{
      "SwigDirector_MyClassJni_getSomething", "(Lcom/example/MyClassJni;[B)J" 
}

This was good, as SwigDirector_MyClassJni_getSomething would then convert this to the proper call to getSomething, converting the byte[] to a JavaClassType in order to do so. *However*, with the above change swig_1module_1init now has a signature like:

{
      "SwigDirector_MyClassJni_getSomething", "(Lcom/example/MyClassJni;Lcom/example/JavaClassType;)J" 
}

This method of course does not exist! For some reason, Swig is taking the descriptor (JavaClassNameWithSlashes) and using that for this method signature! At first I tried changing the descriptor to java/nio/ByteBuffer, but of course the descriptor is actually needed, in order to generate the true call to getSomething in the connect_director method.

So, why is Swig doing this strange thing? Is it something I have done, or is it a bug? I found someone else who had a similar case and was using a String[], which in JNI is a jobjectArray, and their stuff generated ok, as Swig just created a SWIGTYPE_jObjectArray class for it.

Having had a look in the source, the logic that seems to cause this is contained in java.cxx, line 3796 or so. 'jdesc' is obtained by grabbing the directorin descriptor, but is then used to generate the JNI method signature for a method that used the jtype for it's generation!

Basically it seems to be like Swig is either doing funny things to jobjects, or is expecting jtype and jstype to be the same here, which (as far as I'm aware) doesn't have to be true...

Any help appreciated.

Thanks,
Stephen