autodeployai / pmml4s

PMML scoring library for Scala
https://www.pmml4s.org/
Apache License 2.0
58 stars 9 forks source link

Error: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException when trying to open pmml file. #11

Closed Aleksej97 closed 3 years ago

Aleksej97 commented 3 years ago

I am trying to open externally trained model on sci-kit learn as a pmml file in an android app, however when the app tries to open the file it crashes. Here is the code of the app: `public class MainActivity extends AppCompatActivity {

EditText text1,text2,text3,text4;
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button)findViewById(R.id.showInput);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            text1 = (EditText)findViewById(R.id.sepal_length);
            text2 = (EditText)findViewById(R.id.sepal_width);
            text3 = (EditText)findViewById(R.id.petal_length);
            text4 = (EditText)findViewById(R.id.petal_width);

            final double sl = Double.parseDouble(text1.getText().toString());
            final double sw = Double.parseDouble(text2.getText().toString());
            final double pl = Double.parseDouble(text3.getText().toString());
            final double pw = Double.parseDouble(text4.getText().toString());

        Model model = Model.fromFile("DecisionTreeIris.xml");

        String[] input = model.inputNames();
        Object result = model.predict(new Double[]{sl,sw,pl,pw});

        Log.d("tag", result.toString());
        }
    });
}

}`

This is the errors I am getting:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.iris_pmml, PID: 12845 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)  Caused by: java.io.FileNotFoundException: DecisionTreeIris.xml: open failed: ENOENT (No such file or directory) at libcore.io.IoBridge.open(IoBridge.java:492) at java.io.FileInputStream.<init>(FileInputStream.java:160) at scala.io.Source$.fromFile(Source.scala:94) at scala.io.Source$.fromFile(Source.scala:79) at scala.io.Source$.fromFile(Source.scala:57) at org.pmml4s.model.Model$.fromFile(Model.scala:695) at org.pmml4s.model.Model.fromFile(Unknown Source:2) at com.example.iris_pmml.MainActivity$1.onClick(MainActivity.java:45) at android.view.View.performClick(View.java:7448) at android.view.View.performClickInternal(View.java:7425) at android.view.View.access$3600(View.java:810) at android.view.View$PerformClick.run(View.java:28305) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)  Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) at libcore.io.Linux.open(Native Method) at libcore.io.ForwardingOs.open(ForwardingOs.java:166) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254) at libcore.io.ForwardingOs.open(ForwardingOs.java:166) at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542) at libcore.io.IoBridge.open(IoBridge.java:478) at java.io.FileInputStream.<init>(FileInputStream.java:160)  at scala.io.Source$.fromFile(Source.scala:94)  at scala.io.Source$.fromFile(Source.scala:79)  at scala.io.Source$.fromFile(Source.scala:57)  at org.pmml4s.model.Model$.fromFile(Model.scala:695)  at org.pmml4s.model.Model.fromFile(Unknown Source:2)  at com.example.iris_pmml.MainActivity$1.onClick(MainActivity.java:45)  at android.view.View.performClick(View.java:7448)  at android.view.View.performClickInternal(View.java:7425)  at android.view.View.access$3600(View.java:810)  at android.view.View$PerformClick.run(View.java:28305)  at android.os.Handler.handleCallback(Handler.java:938)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.

My file is in the assets folder and I am able to open it "conventionally" with assetManager, but when calling it like this it says it does not exist. Is there a workaround?

I am new to Android, so additionally I will leave here the build.gradle files in case the problem is there.

buildscript { repositories { google() jcenter() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:4.0.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }


apply plugin: 'com.android.application'

android { compileSdkVersion 30 buildToolsVersion "30.0.2" defaultConfig { applicationId "com.example.iris_pmml" minSdkVersion 26 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

}

dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation "org.pmml4s:pmml4s_2.12:0.9.7" implementation 'org.scala-lang:scala-library:2.12.11' implementation 'com.google.android.material:material:1.2.1' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

Thank you in advance.

scorebot commented 3 years ago

@Aleksej97 Maybe you could use the absolute path instead of the relative path DecisionTreeIris.xml, or you can use other methods to load the model: Model.fromInputStream(is) or Model.fromBytes(bytes)

Aleksej97 commented 3 years ago

Thanks, I used the input stream and it read successfully, however now I am having much more serious issue.

` E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.iris_sklearn, PID: 5602 java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/ClassValue; at org.pmml4s.xml.ModelBuilder.makeDataDictionary(ModelBuilder.scala:107) at org.pmml4s.xml.ModelBuilder.makeModel(ModelBuilder.scala:57) at org.pmml4s.xml.ModelBuilder.build(ModelBuilder.scala:44) at org.pmml4s.xml.ModelBuilder.build(ModelBuilder.scala:34) at org.pmml4s.xml.XmlUtils.makeElem(XmlUtils.scala:71) at org.pmml4s.xml.XmlUtils.makeElem$(XmlUtils.scala:71) at org.pmml4s.xml.ModelBuilder$.makeElem(ModelBuilder.scala:143) at org.pmml4s.xml.XmlUtils.makeElem(XmlUtils.scala:73) at org.pmml4s.xml.XmlUtils.makeElem$(XmlUtils.scala:73) at org.pmml4s.xml.ModelBuilder$.makeElem(ModelBuilder.scala:143) at org.pmml4s.xml.ModelBuilder$.fromXml(ModelBuilder.scala:154) at org.pmml4s.model.Model$.apply(Model.scala:711) at org.pmml4s.model.Model$.fromInputStream(Model.scala:707) at org.pmml4s.model.Model.fromInputStream(Unknown Source:2) at com.example.iris_sklearn.MainActivity$1.onClick(MainActivity.java:53) at android.view.View.performClick(View.java:7448) at android.view.View.performClickInternal(View.java:7425) at android.view.View.access$3600(View.java:810) at android.view.View$PerformClick.run(View.java:28305) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.ClassValue" on path: DexPathList[[zip file "/data/app/vuV7W5-fzdx-RXhZURSGxw==/com.example.iris_sklearn-5gv1xeJDPz38Any1oBgSnQ==/base.apk"],nativeLibraryDirectories=[/data/app/vuV7W5-fzdx-RXhZURSGxw==/com.example.iris_sklearn-5gv1xeJDPz38Any1oBgSnQ==/lib/x86, /system/lib, /system_ext/lib, /product/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at org.pmml4s.xml.ModelBuilder.makeDataDictionary(ModelBuilder.scala:107)  at org.pmml4s.xml.ModelBuilder.makeModel(ModelBuilder.scala:57)  at org.pmml4s.xml.ModelBuilder.build(ModelBuilder.scala:44)  at org.pmml4s.xml.ModelBuilder.build(ModelBuilder.scala:34)  at org.pmml4s.xml.XmlUtils.makeElem(XmlUtils.scala:71)  at org.pmml4s.xml.XmlUtils.makeElem$(XmlUtils.scala:71)  at org.pmml4s.xml.ModelBuilder$.makeElem(ModelBuilder.scala:143)  at org.pmml4s.xml.XmlUtils.makeElem(XmlUtils.scala:73)  at org.pmml4s.xml.XmlUtils.makeElem$(XmlUtils.scala:73)  at org.pmml4s.xml.ModelBuilder$.makeElem(ModelBuilder.scala:143)  at org.pmml4s.xml.ModelBuilder$.fromXml(ModelBuilder.scala:154)  at org.pmml4s.model.Model$.apply(Model.scala:711)  at org.pmml4s.model.Model$.fromInputStream(Model.scala:707)  at org.pmml4s.model.Model.fromInputStream(Unknown Source:2)  at com.example.iris_sklearn.MainActivity$1.onClick(MainActivity.java:53)  at android.view.View.performClick(View.java:7448)  at android.view.View.performClickInternal(View.java:7425)  at android.view.View.access$3600(View.java:810)  at android.view.View$PerformClick.run(View.java:28305)  at android.os.Handler.handleCallback(Handler.java:938)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:223)  at android.app.ActivityThread.main(ActivityThread.java:7656)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

`

scorebot commented 3 years ago

@Aleksej97 The issue is caused by the scala-library 2.12 reflect depends on the java.lang.ClassValue. On Android, the java.lang.ClassValue type does not exist in the java.lang package. Could you try to use the scala 2.11? for example pmml4s_2.11:0.9.7

Aleksej97 commented 3 years ago

@scorebot Yup, it worked! Thank you, appreciate it.

scorebot commented 3 years ago

Cool