Closed shuaga closed 1 year ago
@shuaga Thanks for the feedback.
However, in the AssemblyBrowser, I see the static method Create is present.
Try adding prouguard rules.
I think you need to add proguard rules. Seems like methods were removed by shrinker/optimizer (r8/proguard).
in api.xml
there are 2 create
methods
<interface abstract="true" deprecated="not deprecated" final="false" name="InterpreterApi" static="false" visibility="public" jni-signature="Lorg/tensorflow/lite/InterpreterApi;">
<implements name="java.lang.AutoCloseable" name-generic-aware="java.lang.AutoCloseable" jni-type="Ljava/lang/AutoCloseable;" />
<method abstract="true" deprecated="not deprecated" final="false" name="allocateTensors" jni-signature="()V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="true" deprecated="not deprecated" final="false" name="close" jni-signature="()V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="false" deprecated="not deprecated" final="false" name="create" jni-signature="(Ljava/io/File;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;" bridge="false" native="false" return="org.tensorflow.lite.InterpreterApi" jni-return="Lorg/tensorflow/lite/InterpreterApi;" static="true" synchronized="false" synthetic="false" visibility="public">
<parameter name="modelFile" type="java.io.File" jni-type="Ljava/io/File;" />
<parameter name="options" type="org.tensorflow.lite.InterpreterApi.Options" jni-type="Lorg/tensorflow/lite/InterpreterApi$Options;" />
</method>
<method abstract="false" deprecated="not deprecated" final="false" name="create" jni-signature="(Ljava/nio/ByteBuffer;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;" bridge="false" native="false" return="org.tensorflow.lite.InterpreterApi" jni-return="Lorg/tensorflow/lite/InterpreterApi;" static="true" synchronized="false" synthetic="false" visibility="public">
<parameter name="byteBuffer" type="java.nio.ByteBuffer" jni-type="Ljava/nio/ByteBuffer;" />
<parameter name="options" type="org.tensorflow.lite.InterpreterApi.Options" jni-type="Lorg/tensorflow/lite/InterpreterApi$Options;" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="getInputIndex" jni-signature="(Ljava/lang/String;)I" bridge="false" native="false" return="int" jni-return="I" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="opName" type="java.lang.String" jni-type="Ljava/lang/String;" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="getInputTensor" jni-signature="(I)Lorg/tensorflow/lite/Tensor;" bridge="false" native="false" return="org.tensorflow.lite.Tensor" jni-return="Lorg/tensorflow/lite/Tensor;" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="inputIndex" type="int" jni-type="I" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="getInputTensorCount" jni-signature="()I" bridge="false" native="false" return="int" jni-return="I" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="true" deprecated="not deprecated" final="false" name="getLastNativeInferenceDurationNanoseconds" jni-signature="()Ljava/lang/Long;" bridge="false" native="false" return="java.lang.Long" jni-return="Ljava/lang/Long;" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="true" deprecated="not deprecated" final="false" name="getOutputIndex" jni-signature="(Ljava/lang/String;)I" bridge="false" native="false" return="int" jni-return="I" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="opName" type="java.lang.String" jni-type="Ljava/lang/String;" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="getOutputTensor" jni-signature="(I)Lorg/tensorflow/lite/Tensor;" bridge="false" native="false" return="org.tensorflow.lite.Tensor" jni-return="Lorg/tensorflow/lite/Tensor;" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="outputIndex" type="int" jni-type="I" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="getOutputTensorCount" jni-signature="()I" bridge="false" native="false" return="int" jni-return="I" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="true" deprecated="not deprecated" final="false" name="resizeInput" jni-signature="(I[I)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="idx" type="int" jni-type="I" />
<parameter name="dims" type="int[]" jni-type="[I" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="resizeInput" jni-signature="(I[IZ)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="idx" type="int" jni-type="I" />
<parameter name="dims" type="int[]" jni-type="[I" />
<parameter name="strict" type="boolean" jni-type="Z" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="run" jni-signature="(Ljava/lang/Object;Ljava/lang/Object;)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="input" type="java.lang.Object" jni-type="Ljava/lang/Object;" />
<parameter name="output" type="java.lang.Object" jni-type="Ljava/lang/Object;" />
</method>
<method abstract="true" deprecated="not deprecated" final="false" name="runForMultipleInputsOutputs" jni-signature="([Ljava/lang/Object;Ljava/util/Map;)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="inputs" type="java.lang.Object[]" jni-type="[Ljava/lang/Object;" />
<parameter name="outputs" type="java.util.Map<java.lang.Integer, java.lang.Object>" jni-type="Ljava/util/Map<Ljava/lang/Integer;Ljava/lang/Object;>;" />
</method>
</interface>
and in MCWs
./generated/org.tensorflow.tensorflow-lite-api/obj/Release/monoandroid12.0/generated/src/Xamarin.TensorFlow.Lite.IInterpreterApi.cs
both create
methods were bound:
// Metadata.xml XPath method reference: path="/api/package[@name='org.tensorflow.lite']/interface[@name='InterpreterApi']/method[@name='create' and count(parameter)=2 and parameter[1][@type='java.io.File'] and parameter[2][@type='org.tensorflow.lite.InterpreterApi.Options']]"
[Register ("create", "(Ljava/io/File;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;", "")]
public static unsafe global::Xamarin.TensorFlow.Lite.IInterpreterApi Create (global::Java.IO.File modelFile, global::Xamarin.TensorFlow.Lite.InterpreterApiOptions options)
{
const string __id = "create.(Ljava/io/File;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;";
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [2];
__args [0] = new JniArgumentValue ((modelFile == null) ? IntPtr.Zero : ((global::Java.Lang.Object) modelFile).Handle);
__args [1] = new JniArgumentValue ((options == null) ? IntPtr.Zero : ((global::Java.Lang.Object) options).Handle);
var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
return global::Java.Lang.Object.GetObject<global::Xamarin.TensorFlow.Lite.IInterpreterApi> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
} finally {
global::System.GC.KeepAlive (modelFile);
global::System.GC.KeepAlive (options);
}
}
// Metadata.xml XPath method reference: path="/api/package[@name='org.tensorflow.lite']/interface[@name='InterpreterApi']/method[@name='create' and count(parameter)=2 and parameter[1][@type='java.nio.ByteBuffer'] and parameter[2][@type='org.tensorflow.lite.InterpreterApi.Options']]"
[Register ("create", "(Ljava/nio/ByteBuffer;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;", "")]
public static unsafe global::Xamarin.TensorFlow.Lite.IInterpreterApi Create (global::Java.Nio.ByteBuffer byteBuffer, global::Xamarin.TensorFlow.Lite.InterpreterApiOptions options)
{
const string __id = "create.(Ljava/nio/ByteBuffer;Lorg/tensorflow/lite/InterpreterApi$Options;)Lorg/tensorflow/lite/InterpreterApi;";
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [2];
__args [0] = new JniArgumentValue ((byteBuffer == null) ? IntPtr.Zero : ((global::Java.Lang.Object) byteBuffer).Handle);
__args [1] = new JniArgumentValue ((options == null) ? IntPtr.Zero : ((global::Java.Lang.Object) options).Handle);
var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
return global::Java.Lang.Object.GetObject<global::Xamarin.TensorFlow.Lite.IInterpreterApi> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
} finally {
global::System.GC.KeepAlive (byteBuffer);
global::System.GC.KeepAlive (options);
}
}
I have tried this in our DEBUG version of the app and it doesn't have 'Code Shrinker' enabled. Verified the Code-Shrinker configuration under Android -> Build -> Enable Multi-Dex -> Code Shrinker; neither Proguard nor r8 is selected.
In any case, we have moved to dotnet 7 and the above error doesn't repro in dotnet 7. The error is changed to
Abort message: 'JNI DETECTED ERROR IN APPLICATION: can't call static org.tensorflow.lite.InterpreterApi org.tensorflow.lite.InterpreterApi$-CC.create(java.nio.ByteBuffer, org.tensorflow.lite.InterpreterApi$Options) with class java.lang.Class<org.tensorflow.lite.InterpreterApi> in call to CallStaticObjectMethodA'
This new error indicates that the Create method was found. So, this current issue can be closed. I might end up creating another issue for the new error.
@shuaga
OK. I will close it and you can open new issue. And please if you can add some repro sample. I know sometimes it is not that easy, but it would help us a lot.
Xamarin.Android Version (eg: 6.0):
13.2.0.0
Operating System & Version (eg: Mac OSX 10.11):
Mac OS 13.3.1
Describe your Issue
The app crashes after launch with the following error -
However, in the AssemblyBrowser, I see the static method Create is present.
Relevant information
The model works with the API InterpreterFactory. But it is deprecated and its replacement is throwing the above error. Sample code that works using the deprecated API -
Packages used:
Minimal Repro Code Sample