Search code examples
androidactionscript-3airjavacvane

Air ANE - linking native so libraries


I'm trying to use JavaCV on a AIR project. I built a native extension and it compile well but at runtime i get the following error:

W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
I/dalvikvm(16234): Could not find method java.awt.image.BufferedImage.getSampleModel, referenced from method org.bytedeco.javacpp.helper.opencv_core$AbstractIplImage.createFrom
W/dalvikvm(16234): VFY: unable to resolve virtual method 8824: Ljava/awt/image/BufferedImage;.getSampleModel ()Ljava/awt/image/SampleModel;
D/dalvikvm(16234): VFY: replacing opcode 0x6e at 0x0004
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
W/dalvikvm(16234): VFY: unable to find class referenced in signature (Ljava/awt/image/BufferedImage;)
D/dalvikvm(16234): GC_CONCURRENT freed 612K, 7% free 9380K/10028K, paused 3ms+4ms, total 35ms

Looks like I'm not linking the library resource properly and the doc on the topics seems really limited.

Any idea or gotcha when linking .jar and armeabi/_.so libraries to an ANE?

Updated error log after upgrading to latest javacv source:

W/dalvikvm(14799): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/bytedeco/javacpp/avutil;
W/dalvikvm(14799): Exception Ljava/lang/NoClassDefFoundError; thrown while initializing Lorg/bytedeco/javacpp/avformat;
W/dalvikvm(14799): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lorg/bytedeco/javacpp/opencv_core;

Solution

  • Linking .so dependencies:

    You should make sure that your folder structure is correct. See "This link" under Android native libraries section. Simply placing your .so native dependencies inside the "libs/target_platform/" folder makes sure that ADT puts them in the correct place inside the final APK.

    Example: YOUR_ANE_ROOT_FOLDER/android/libs/armeabi-v7a/libYourLibrary.so

    If you support multiple architectures your might also have a YOUR_ANE_ROOT_FOLDER/android/libs/armeabi/libYourLibrary.so

    and so on..

    Also make sure that your shared object is named with the "lib" prefix. Example: libYourLibrary.so

    Linking JAR dependencies:

    If specifying your JAR dependencies in the platform.xml under the "packagedDependencies" tags doesn't work, you can try to extract all external JARs and include them inside your final jar.

    Example:

            <javac source="1.6" srcdir="../android/src" destdir="../android/temp/classes" includeantruntime="false">
            <classpath>
              <pathelement location="${android.sdk}/android.jar"/>
              <pathelement location="../android/libs/FlashRuntimeExtensions.jar"/>
              <pathelement location="../android/libs/android-support-v4.jar"/>
              <pathelement location="../android/libs/opencv.jar"/>
              ....
              ....
            </classpath>
          </javac>
    
          <mkdir dir="../android/temp/zip"/>
          <unzip src="../android/libs/opencv.jar" dest="../android/temp/zip"/>
          <unzip src="../android/libs/android-support-v4.jar" dest="../android/temp/zip"/>
          ...
          ...
    
          <copydir src="../android/temp/zip/com" dest="../android/temp/classes/com"/>
          <copydir src="../android/temp/zip/android" dest="../android/temp/classes/android"/>
    
          <mkdir dir="../temp/android/"/>
          <copy todir="../temp/android/res/">
            <fileset dir="../android/res"/>
          </copy>
          <jar destfile="../temp/android/lib${name}.jar">
            <fileset dir="../android/temp/classes"/>
          </jar>
          <delete dir="../android/temp"/>
    

    If these classes still don't make it to your final APK then see THIS!