jpmml/jpmml-transpiler

ClassNotFoundException when loading transpiled model

ahmed-shariff opened this issue · 2 comments

I get the following error when I try to load the transpiled models:

java.lang.NoClassDefFoundError: org/dmg/pmml/PMML
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:757)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100 (URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:419)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:352)
    at java.lang.Class.forName0 (Native Method)
    at java.lang.Class.forName (Class.java:348)
    at java.util.ServiceLoader$LazyIterator.nextService (ServiceLoader.java:370)
    at java.util.ServiceLoader$LazyIterator.next (ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next (ServiceLoader.java:480)
    at org.jpmml.model.ServiceLoaderUtil.load (ServiceLoaderUtil.java:30)
    at org.jpmml.model.PMMLUtil.load (PMMLUtil.java:46)
    at com.umanitoba.hci.washinghands.App.main (App.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282)
    at java.lang.Thread.run (Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.dmg.pmml.PMML
    at java.net.URLClassLoader.findClass (URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:419)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:352)
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:757)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100 (URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:419)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:352)
    at java.lang.Class.forName0 (Native Method)
    at java.lang.Class.forName (Class.java:348)
    at java.util.ServiceLoader$LazyIterator.nextService (ServiceLoader.java:370)
    at java.util.ServiceLoader$LazyIterator.next (ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next (ServiceLoader.java:480)
    at org.jpmml.model.ServiceLoaderUtil.load (ServiceLoaderUtil.java:30)
    at org.jpmml.model.PMMLUtil.load (PMMLUtil.java:46)
    at com.umanitoba.hci.washinghands.App.main (App.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282)
    at java.lang.Thread.run (Thread.java:748)

I tried the following:

              // ============approach 1===============
               Evaluator evaluator = new ServiceLoadingModelEvaluatorBuilder()
			.loadService((f.toURI()).toURL())
			.build();
              // ============approach 2===============
               URL[] classpath = {
		    (f.toURI()).toURL()
		};
		try(URLClassLoader clazzLoader = new URLClassLoader(classpath)){
		    PMML javaPmml = PMMLUtil.load(clazzLoader);
		    Evaluator evaluator = new ModelEvaluatorBuilder(javaPmml)
		    	.build();
                }

I've attached the associated jar file for your reference. Any help or pointers would be much appreciated.

That must be a classpath issue on your side.

The generated Service JAR file is not completely self-contained; it depends on the JPMML-Evaluator library, which in turn depends on the JPMML-Model library.

The org.dmg.pmml.PMML class resides inside the JPMML-Model library JAR file (Apache Maven coordinates org.jpmml:pmml-model). Please make sure that this artifact is on your application classpath.

You were right, I added the PMML classes ClassLoader as the parent to the URLClassLoader, and it solves the problem:

...
try(URLClassLoader clazzLoader = new URLClassLoader(classpath, PMML.class.getClassLoader())){
...