jpmml/jpmml-evaluator

LoadingModelEvaluatorBuilder not usable on Android due to "java.lang.NoClassDefFoundError: Failed resolution of: Ljava/awt/Image"

jye0829 opened this issue · 2 comments

InputStream inputStream3 = getResources().getAssets().open("X_test_verify.csv");

Evaluator evaluator = new LoadingModelEvaluatorBuilder()
    .load(inputStream2)
    .build();

E FATAL EXCEPTION: OpenCVCameraBackground
Process: com.zhenzhe.javacv, PID: 12163

 java.lang.NoClassDefFoundError: Failed resolution of: Ljava/awt/Image;
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeBuiltinLeafInfoImpl.<clinit>(RuntimeBuiltinLeafInfoImpl.java:337)
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeTypeInfoSetImpl.<init>(RuntimeTypeInfoSetImpl.java:31)
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:91)
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:46)
   at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.<init>(ModelBuilder.java:119)
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:55)
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:403)
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:251)
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:77)
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1111)
   at org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:140)
   at java.lang.reflect.Method.invoke(Native Method)
   at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:274)
   at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:263)
   at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:395)
   at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
   at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
   at org.jpmml.model.JAXBUtil.getContext(JAXBUtil.java:106)
   at org.jpmml.evaluator.LoadingModelEvaluatorBuilder.load(LoadingModelEvaluatorBuilder.java:151)
   at org.jpmml.evaluator.LoadingModelEvaluatorBuilder.load(LoadingModelEvaluatorBuilder.java:138)
   at com.zhenzhe.javacv.JavaCamera2FocusEnabledApp$ImageSaver.run(JavaCamera2FocusEnabledApp.java:556)
   at com.zhenzhe.javacv.JavaCamera2FocusEnabledApp$1.onImageAvailable(JavaCamera2FocusEnabledApp.java:240)
   at android.media.ImageReader$1.run(ImageReader.java:947)
   at android.os.Handler.handleCallback(Handler.java:958)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loopOnce(Looper.java:230)
   at android.os.Looper.loop(Looper.java:319)
   at android.os.HandlerThread.run(HandlerThread.java:67)
  Caused by: java.lang.ClassNotFoundException: Didn't find class "java.awt.Image" on path: DexPathList[[dex file "/data/data/com.zhenzhe.javacv/code_cache/.overlay/base.apk/classes14.dex", zip file "/data/app/~~NYD5IBEMJQXxXIf2bAwOOw==/com.zhenzhe.javacv-oIrH3gRpKt2wcVh1BVGusw==/base.apk"],nativeLibraryDirectories=[/data/app/~~NYD5IBEMJQXxXIf2bAwOOw==/com.zhenzhe.javacv-oIrH3gRpKt2wcVh1BVGusw==/lib/arm64, /data/app/~~NYD5IBEMJQXxXIf2bAwOOw==/com.zhenzhe.javacv-oIrH3gRpKt2wcVh1BVGusw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
   at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeBuiltinLeafInfoImpl.<clinit>(RuntimeBuiltinLeafInfoImpl.java:337) 
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeTypeInfoSetImpl.<init>(RuntimeTypeInfoSetImpl.java:31) 
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:91) 
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.createTypeInfoSet(RuntimeModelBuilder.java:46) 
   at org.glassfish.jaxb.runtime.v2.model.impl.ModelBuilder.<init>(ModelBuilder.java:119) 
   at org.glassfish.jaxb.runtime.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:55) 
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:403) 
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:251) 
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:77) 
   at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1111) 
   at org.glassfish.jaxb.runtime.v2.ContextFactory.createContext(ContextFactory.java:140) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:274) 
   at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:263) 
   at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:395) 
   at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:691) 
   at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:632) 
   at org.jpmml.model.JAXBUtil.getContext(JAXBUtil.java:106) 
   at org.jpmml.evaluator.LoadingModelEvaluatorBuilder.load(LoadingModelEvaluatorBuilder.java:151) 
   at org.jpmml.evaluator.LoadingModelEvaluatorBuilder.load(LoadingModelEvaluatorBuilder.java:138) 
   at com.zhenzhe.javacv.JavaCamera2FocusEnabledApp$ImageSaver.run(JavaCamera2FocusEnabledApp.java:556) 
   at com.zhenzhe.javacv.JavaCamera2FocusEnabledApp$1.onImageAvailable(JavaCamera2FocusEnabledApp.java:240) 
   at android.media.ImageReader$1.run(ImageReader.java:947) 
   at android.os.Handler.handleCallback(Handler.java:958) 
   at android.os.Handler.dispatchMessage(Handler.java:99) 
   at android.os.Looper.loopOnce(Looper.java:230) 
   at android.os.Looper.loop(Looper.java:319) 
   at android.os.HandlerThread.run(HandlerThread.java:67)

In the meanwhile, I use jpmml-model to run the json format of pmml. But I failed all the time. So I wonder can I use the evaluator to run the xgboost classifier model.jar on the evaluator without using jaxb

The LoadingModelEvaluatorBuilder cannot be used on Android, because it attempts to load the PMML XML document using Jakarta XML Binding (JAXB) technology.

You should be using its superclass ModelEvaluatorBuilder instead. It is your choice then how you deliver the org.dmg.pmml.PMML object to its constructor.

So I wonder can I use the evaluator to run the xgboost classifier model.jar on the evaluator without using jaxb

I would personally recommend you to transpile the PMML XML document into a Java class using the JPMML-Transpiler library. Then instantiate this class, and pass this instance to ModelEvaluatorBuilder constructor.

In pseudocode:

# The PMML$12345 class was generated from PMML XML document by JPMML-Transpiler
PMML pmml = new PMML$12345();

Evaluator evaluator = new ModelEvaluatorBuilder(pmml)
  .build();