Comments (7)
Another idea - maybe there is some Apache Maven plugin that can rewrite JPMML-Model classes (during the packaging phase of the build) by changing all field access modifiers from private
to public
.
This way the JPMML-Model library could stay as it is, and you could still have your "tweaked" variant of it.
from jpmml-model.
One final hurdle was to permit Maven to find MyClassTransformer on the classpath when executing the plugin.
@0xcfe4f1 Apache Maven plugins can declare their own "locally scoped" dependencies. For example, see https://github.com/jpmml/jpmml-model/blob/master/pmml-model/pom.xml#L195-L201
from jpmml-model.
What are your JDK and JPMML-Model library versions? How is your build configured, are you including the org.jpmml:pmml-model
dependency, or the org.jpmml:pmml-model-metro
dependency?
So maybe making some fields in class org.dmg.pmml.PMML public could help.
That would be a bad thing to do.
Anyway, you can relax the visibility of PMML class model fields in your application code using Java reflection API.
Something like this:
java.lang.reflect.Field[] fields = PMML.class.getDeclaredFields();
for(java.lang.reflect.Field field : fields){
field.setAccessible(true);
}
You would need to do it before invoking the PMMLUtil#unmarshal(InputStream)
method.
from jpmml-model.
Also, could be the case that RapidMiner uses some custom classloading mechanism, which interferes with JAXB unmarshaller. Can you parse the PMML file using a command-line application?
from jpmml-model.
Also, could be the case that RapidMiner uses some custom classloading mechanism, which
interferes with JAXB unmarshaller. Can you parse the PMML file using a command-line application?
It works fine from the command line.
Something like this:
java.lang.reflect.Field[] fields = PMML.class.getDeclaredFields(); for(java.lang.reflect.Field field : fields){ field.setAccessible(true); }
You would need to do it before invoking the PMMLUtil#unmarshal(InputStream) method.
This doesn't work because of the security manager I guess. It produces a java.security.AccessControlException
java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at com.rapidminer.security.PluginSecurityManager.checkPermission(PluginSecurityManager.java:27)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:128)
at de.woistbier.rapidminer.pmml.operator.PMMLEvaluator.read(PMMLEvaluator.java:120)
at de.woistbier.rapidminer.pmml.operator.PMMLEvaluator.read(PMMLEvaluator.java:34)
at com.rapidminer.operator.io.AbstractReader.doWork(AbstractReader.java:126)
at com.rapidminer.operator.Operator.execute(Operator.java:1005)
at com.rapidminer.operator.execution.SimpleUnitExecutor.execute(SimpleUnitExecutor.java:77)
at com.rapidminer.operator.ExecutionUnit$3.run(ExecutionUnit.java:812)
at com.rapidminer.operator.ExecutionUnit$3.run(ExecutionUnit.java:807)
at java.security.AccessController.doPrivileged(Native Method)
at com.rapidminer.operator.ExecutionUnit.execute(ExecutionUnit.java:807)
at com.rapidminer.operator.OperatorChain.doWork(OperatorChain.java:428)
at com.rapidminer.operator.Operator.execute(Operator.java:1005)
at com.rapidminer.Process.run(Process.java:1205)
at com.rapidminer.Process.run(Process.java:1101)
at com.rapidminer.Process.run(Process.java:1054)
at com.rapidminer.Process.run(Process.java:1049)
at com.rapidminer.Process.run(Process.java:1039)
at com.rapidminer.gui.ProcessThread.run(ProcessThread.java:65)
from jpmml-model.
If it works from command-line, and not from within RapidMiner, then you should contact the RapidMiner team for technical assistance.
Most probably, RapidMiner's security manager is also preventing JAXB unmarshaller from doing its work - it should be the case that Sun/Oracle JAXB engine also uses Java reflection APIs to map XML and Java data structures.
The original JAXB error message is also an java.lang.IllegalAccessError
. It's thrown when a Java field is not accessible, for example when the Field#setAccessible(true)
was invoked, but didn't have any effect (in this case, the JAXB engine probably quietly swallowed the intermediate java.security.AccessControlException
).
from jpmml-model.
Another idea - maybe there is some Apache Maven plugin that can rewrite JPMML-Model classes (during the packaging phase of the build) by changing all field access modifiers from
private
topublic
.This way the JPMML-Model library could stay as it is, and you could still have your "tweaked" variant of it.
Villu, your intuition here is correct, thank you for the hint.
I recently experienced this exact problem when trying to unmarshall PMML XML files at runtime with JAXB via org.jpmml.model.PMMLUtil.unmarshal(...) on a JVM with a very restrictive security policy in place.
I solved the problem by modifying the Maven POM build of my project with the following plugins:
- maven-dependency-plugin - In the process-classes phase, configure this plugin to unpack the
org.jpmml:pmml-model
JAR dependency to the projecttarget/classes
path (required for the plugin below to manipulate the bytecode, as it can't reach inside JARs); - https://github.com/hielkehoeve/maven-javassist - In the process-classes phase, apply a custom Javassist transformer over classes in the
org.dmg.pmml
package to transform all declared field modifiers from protected/private to public (see below for my Javassist transformer implementation,MyClassTransformer
); - maven-shade-plugin - In the package phase, construct a JAR by excluding any
org.jpmml:pmml-model
dependencies except those which were modified by the Javassist plugin above.
After packaging my code with this build configuration, JAXB successfully unmarshalls PMML XML at runtime without the exception above (java.lang.IllegalAccessError: Class com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection can not access a member of class org.dmg.pmml.PMML with modifiers "private").
The Javassist transformer implementation was straightforward:
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.Modifier;
import nl.topicus.plugins.maven.javassist.ClassTransformer;
import nl.topicus.plugins.maven.javassist.TransformationException;
public class MyClassTransformer extends ClassTransformer {
@Override
public void applyTransformations(ClassPool pool, CtClass clazz) throws TransformationException {
for(CtField f : clazz.getDeclaredFields()) {
f.setModifiers(Modifier.setPublic(f.getModifiers()));
}
}
}
One final hurdle was to permit Maven to find MyClassTransformer
on the classpath when executing the plugin. I did this simply by using mvn install
on a separate Maven project which packaged MyClassTransformer
into its own group:artifact
and added this as a new dependency to my main project where the plugin is called. (Edit: As Villu has pointed out, this can be added as a locally scoped dependency for the plugin instead of the whole project).
from jpmml-model.
Related Issues (20)
- Field `PMML#extensions` should be in the last position, not in the first position
- Broken build. HOT 1
- XML filters for checking the structure of PMML documents during parsing.
- Ensure Java 9 compatibility HOT 1
- Refactor Apache Maven plugin to support JSON output data format HOT 3
- SAX whitespace filter is deleting significant whitespace
- Polymorphic mappings may fail when using EclipseLink JAXB runtime HOT 1
- Cannot update pmml-android from 1.3.6 to 1.4.15 due to jackson dependency HOT 4
- EmbeddedModel Not support HOT 2
- Downgrading PMML-4_4 to PMML-4_3 HOT 1
- A required class was missing while executing com.simpligility.maven.plugins:android-maven-plugin:4.6.0: javax/xml/bind/annotation/XmlSchema HOT 1
- Stop using ThreadLocal#withInitial(Supplier) HOT 10
- API to check validity of a pmml
- Cannot load JSON neither YAML in Android HOT 10
- Large `MapValues` elements are loaded very slowly in newer library versions HOT 17
- An empty MiningSchema is a deviation from the PMML standard HOT 5
- NoClassDefFoundError HOT 1
- License issue with SecondsSinceMidnight.java HOT 2
- Handle XMLNS protocol change from `http` to `https` HOT 3
- After upgrading JPMML to version 1.6.4, I can only use xsd file version 4.4 for schema validation. HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jpmml-model.