Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7018607

javah generates incorrect C header (.h)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 6u23
    • tools
    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.6.0_23"
      Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
      Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux filao24.intra.cea.fr 2.6.18-238.1.1.el5 #1 SMP Tue Jan 4 13:32:19 EST 2011 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      When generating a C header using javah for a class (let us call it MyClass) containing native methods, I have problem in the following case:
      - two native methods have the same name with different signatures in such a way that the associated C functions have "long" names containing the method signature in order to obtain two different names.
      - one of the argument of these methods is an inner enum (let us call it MyEnum) of the class containing these native methods in such a way that in the methods signature one have MyClass$MyEnum. Following JNI specs (http://download.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp615), this should be translated into MyClass_00024MyEnum in the C header but it is not, I have only MyClass_MyEnum in such a way that when trying to use these native methods in a java context, I obtain a java.lang.UnsatisfiedLinkError Exception. When manually renaming the C functions with MyClass_00024MyEnum, everything works fine.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      - create two native methods in a class with the same name but different signatures. One of the argument should be an enum embedded in the class.
      - generate the C header using javah

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      the C header generated by javah should contain C functions with correct (according to the JNI specs) names (MyClass_00024MyEnum)

      /* DO NOT EDIT THIS FILE - it is machine generated */
      #include <jni.h>
      /* Header for class mypackage_MyClass */

      #ifndef _Included_mypackage_MyClass
      #define _Included_mypackage_MyClass
      #ifdef __cplusplus
      extern "C" {
      #endif
      /*
       * Class: mypackage_MyClass
       * Method: method
       * Signature: ([ILmypackage/MyClass/MyEnum;)V
       */
      JNIEXPORT void JNICALL Java_mypackage_MyClass_method___3ILmypackage_MyClass_00024MyEnum_2
        (JNIEnv *, jobject, jintArray, jobject);

      /*
       * Class: mypackage_MyClass
       * Method: method
       * Signature: ([DLmypackage/MyClass/MyEnum;)V
       */
      JNIEXPORT void JNICALL Java_mypackage_MyClass_method___3DLmypackage_MyClass_00024MyEnum_2
        (JNIEnv *, jobject, jdoubleArray, jobject);

      #ifdef __cplusplus
      }
      #endif
      #endif
      /* Header for class mypackage_MyClass_MyEnum */

      #ifndef _Included_mypackage_MyClass_MyEnum
      #define _Included_mypackage_MyClass_MyEnum
      #ifdef __cplusplus
      extern "C" {
      #endif
      #ifdef __cplusplus
      }
      #endif
      #endif

      ACTUAL -
      the C header generated by javah contain C functions with incorrect names (MyClass_MyEnum instead of MyClass_00024MyEnum):

      /* DO NOT EDIT THIS FILE - it is machine generated */
      #include <jni.h>
      /* Header for class mypackage_MyClass */

      #ifndef _Included_mypackage_MyClass
      #define _Included_mypackage_MyClass
      #ifdef __cplusplus
      extern "C" {
      #endif
      /*
       * Class: mypackage_MyClass
       * Method: method
       * Signature: ([ILmypackage/MyClass/MyEnum;)V
       */
      JNIEXPORT void JNICALL Java_mypackage_MyClass_method___3ILmypackage_MyClass_MyEnum_2
        (JNIEnv *, jobject, jintArray, jobject);

      /*
       * Class: mypackage_MyClass
       * Method: method
       * Signature: ([DLmypackage/MyClass/MyEnum;)V
       */
      JNIEXPORT void JNICALL Java_mypackage_MyClass_method___3DLmypackage_MyClass_MyEnum_2
        (JNIEnv *, jobject, jdoubleArray, jobject);

      #ifdef __cplusplus
      }
      #endif
      #endif
      /* Header for class mypackage_MyClass_MyEnum */

      #ifndef _Included_mypackage_MyClass_MyEnum
      #define _Included_mypackage_MyClass_MyEnum
      #ifdef __cplusplus
      extern "C" {
      #endif
      #ifdef __cplusplus
      }
      #endif
      #endif


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class MyClass {

          public enum MyEnum {
              MyEnum1,
              MyEnum2
          }

          public MyClass() {
          }

          public native void method(int[] array, MyEnum myEnum);
          public native void method(double[] array, MyEnum myEnum);

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      manually renaming the C method or moving MyEnum out of MyClass

            jjg Jonathan Gibbons
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: