Closed doljae closed 2 years ago
Question 1
The JPMML upgrade from 1.5.X to 1.6.X (initiated in JPMML-Model library, propagated into JPMML-Evaluator library) was about replacing "old" javax.xml.bind.*
classes (aka Java XML Binding) with "new" jakarta.xml.bind.*
classes (aka Jakarta XML Binding).
As you can imagine, this is a major classpath change, and you should take a couple of minutes to check the project README for instructions.
These instructions suggest that your Java application should depend on the org.jpmml:pmml-evaluator-metro
dependency. The -metro
suffix indicates that jakarta.xml.bind.*
classes will be provided by the GlassFish Metro JAXB runtime - this is a very good default.
Should work with all Java SE versions 1.8 and up - as demonstrated here using GitHub Actions CI (click on some CI run, and you'll see a list of ten Java versions, all green): https://github.com/jpmml/jpmml-evaluator/actions/workflows/maven.yml
Previously, I was using org.jpmml:pmml-evaluator-extension:1.5.16
The org.jpmml:pmml-evaluator-extension
module was merged into the main org.jpmml:pmml-evaluator
module.
It was providing a couple of Java-backed user-defined function classes, which now reside inside the org.jpmml.evaluator.functions.*
package.
I added 7 dependencies to use jpmml as the latest version 1.6.x as before
You only need this one dependency - org.jpmml:pmml-evaluator-metro:1.6.3
.
A proper build manager (such as Apache Maven) should be able to import all transitive dependencies automatically.
I'd strongly advise against importing any Jakarta XML Binding libraries manually. My module dependency declarations are correct, up-to-date and maximally short, so you won't be able to improve the situation in any way.
In any case, it is very inconvenient to use now.
TLDR: replace org.jpmml:pmml-evaluator(-extension)
with org.jpmml:pmml-evaluator-metro
, and everything will be OK.
Functional duplicate of #234
@vruusmann Thank you for answer. However, I have already tried the method you suggested.
This is my submodule's build scripts's dependencies
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
runtimeOnly("mysql:mysql-connector-java")
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("org.springdoc:springdoc-openapi-ui")
implementation("io.reactivex.rxjava3:rxjava")
implementation("com.h2database:h2")
testImplementation("com.h2database:h2")
implementation("org.jpmml:pmml-evaluator-metro:1.6.3")
}
And this is the result searching "metro" to IntelliJ dependency analyer
Same result, LoadingModelEvaluatorBuilder.java
@vruusmann I've already checked the readme and the issue you linked to. So I thought that using the metro dependency instead would solve it, but I got the same issue.
@vruusmann For accurate verification, create an empty spring boot project with spring-initializer, add only metro dependency, and check. As a result, an error still occurs.
And this is the result searching "metro" to IntelliJ dependency analyer
TBH, your diagnostic tools - SBT(?) and IntelliJ dependency analyzer - are no authority for me.
The fact of the matter is that Apache Maven is able to correctly traverse the dependency chain, and all Apache Maven-based builds compile and execute successfully. There are no classpath errors anywhere.
For example, jump into the pmml-evaluator-metro
directory and print the dependency tree:
$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building JPMML evaluator GlassFish Metro runtime 1.6-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ pmml-evaluator-metro ---
[INFO] org.jpmml:pmml-evaluator-metro:jar:1.6-SNAPSHOT
[INFO] +- org.jpmml:pmml-evaluator:jar:1.6-SNAPSHOT:compile
[INFO] | +- org.jpmml:pmml-model:jar:1.6.3:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.1:compile (version selected from constraint [2.9.4,2.13.1])
[INFO] | | \- jakarta.xml.bind:jakarta.xml.bind-api:jar:3.0.1:compile
[INFO] | +- com.google.guava:guava:jar:31.0.1-jre:compile (version selected from constraint [19.0,31.0.1-jre])
[INFO] | | \- com.google.guava:failureaccess:jar:1.0.1:compile
[INFO] | \- org.apache.commons:commons-math3:jar:3.6.1:compile (version selected from constraint [3.1,3.6.1])
[INFO] \- org.jpmml:pmml-model-metro:jar:1.6.3:compile
[INFO] \- org.glassfish.jaxb:jaxb-runtime:jar:3.0.2:compile
[INFO] +- com.sun.activation:jakarta.activation:jar:2.0.1:compile
[INFO] \- org.glassfish.jaxb:jaxb-core:jar:3.0.2:compile
[INFO] +- org.glassfish.jaxb:txw2:jar:3.0.2:compile
[INFO] \- com.sun.istack:istack-commons-runtime:jar:4.0.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.700 s
[INFO] Finished at: 2022-05-17T14:33:26+03:00
[INFO] Final Memory: 37M/1963M
[INFO] ------------------------------------------------------------------------
The org.jpmml:pmml-evaluator-metro
dependency includes the org.jpmml:pmml-model-metro
dependency. which in turn imports the complete set of Jakarta XML Bind interface and implementation libraries.
As a result, an error still occurs.
Maybe you need to rebuild your IntelliJ project after you change the dependency?
There could be some dependency caching going on.
Maybe you need to rebuild your IntelliJ project after you change the dependency?
There could be some dependency caching going on.
I tried but it didn't work. Even if I think about it, adding the metro dependency as per your opinion seems to add all the necessary dependencies.
./gradlew dependencies
...
\--- org.jpmml:pmml-evaluator-metro:1.6.3
+--- org.jpmml:pmml-evaluator:1.6.3
| +--- org.jpmml:pmml-model:1.6.3
| | +--- com.fasterxml.jackson.core:jackson-annotations:[2.9.4, 2.13.1] -> 2.13.2
| | | \--- com.fasterxml.jackson:jackson-bom:2.13.2
| | | \--- com.fasterxml.jackson.core:jackson-annotations:2.13.2 (c)
| | \--- jakarta.xml.bind:jakarta.xml.bind-api:3.0.1 -> 2.3.3
| | \--- jakarta.activation:jakarta.activation-api:1.2.2
| +--- com.google.guava:guava:[19.0, 31.0.1-jre] -> 31.0.1-jre
| | \--- com.google.guava:failureaccess:1.0.1
| \--- org.apache.commons:commons-math3:[3.1, 3.6.1] -> 3.6.1
\--- org.jpmml:pmml-model-metro:1.6.3
+--- org.jpmml:pmml-model:1.6.3 (*)
\--- org.glassfish.jaxb:jaxb-runtime:3.0.2 -> 2.3.6
+--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (*)
+--- org.glassfish.jaxb:txw2:2.3.6
\--- com.sun.istack:istack-commons-runtime:3.0.12
...
I don't know the reason. (Of course there's possibility there's some bug in IntelliJ) Can you advise for me to fix this issue?...
Can you advise for me to fix this issue?
Update your toolchain to Apache Maven! :-)
@vruusmann
Update your toolchain to Apache Maven! :-)
so you mean I replace my build tool to maven right?(use pom.xml
, not build.gradle
)
so you mean I replace my build tool to maven right?
That would be a major change (bigger than upgrading JPMML-Evaluator from 1.5.X to 1.6.X), so you need to weight the pros and cons, and make a decision yourself.
All I can say is that all JPMML family libraries/applications use Apache Maven. And I can't remember having any classpath issues, ever.
With Apache Maven you can generate IDE project files automatically. For example, for Eclipse IDE you simply do mvn eclipse:eclipse
, and you will have project files ready with guaranteed correct classpath.
I believe Apache Maven has similar helper plugin for IntellJ also. Try googling around, maybe that will help you get the project files correct.
@vruusmann
Thank you for your kind support. I made a maven-based spring boot project based on your advice and tested it by adding only metro dependency.
The same issue occurred as a result of the test, and the project cannot be started. Of course, according to the CI/CD log you shared, it seems that it builds without any problem, but the problem is still that it cannot be used in the actual project after adding a dependency in maven.
I use OpenJDK17(Zulu) & Spring boot 2.6.7 using Spring-Initializer, just add metro dependency and check there's no compile error.
Share the repository link.
After cloning this project, please check if it builds & runs normally.
@vruusmann plus, if does not work, please re-open this issue for other users' support or comments π
I made a maven-based spring boot project based on your advice and tested it by adding only metro dependency.
I've cloned your repository, and indeed the build fails because of a missing jakarta.xml.bind.JAXBException
class:
$ mvn clean install
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /path/to/jpmml-maven-test/src/main/java/com/example/tetsets/TetsetsApplication.java:[20,52] cannot access jakarta.xml.bind.JAXBException
class file for jakarta.xml.bind.JAXBException not found
The problem is that the Spring framework overrides Jakarta XML Binding. See below - I'm expecting to see the org.glassfish.jaxb:jaxb-runtime:jar:3.0.2
dependency (according to my above pmml-evaluator-metro
test), but the Spring framework has forcefully replaced it with a org.glassfish.jaxb:jaxb-runtime:jar:2.3.6
dependency:
$ mvn dependency:tree
[INFO] --- maven-dependency-plugin:3.2.0:tree (default-cli) @ tetsets ---
[INFO] com.example:tetsets:jar:0.0.1-SNAPSHOT
...
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.6.7:test
...
[INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:compile
[INFO] | | \- jakarta.activation:jakarta.activation-api:jar:1.2.2:compile
...
[INFO] \- org.jpmml:pmml-evaluator-metro:jar:1.6.3:compile
[INFO] +- org.jpmml:pmml-evaluator:jar:1.6.3:compile
[INFO] | +- org.jpmml:pmml-model:jar:1.6.3:compile
[INFO] | | \- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.2:compile
[INFO] | +- com.google.guava:guava:jar:31.0.1-jre:compile (version selected from constraint [19.0,31.0.1-jre])
[INFO] | | \- com.google.guava:failureaccess:jar:1.0.1:compile
[INFO] | \- org.apache.commons:commons-math3:jar:3.6.1:compile (version selected from constraint [3.1,3.6.1])
[INFO] \- org.jpmml:pmml-model-metro:jar:1.6.3:compile
[INFO] \- org.glassfish.jaxb:jaxb-runtime:jar:2.3.6:compile
[INFO] +- org.glassfish.jaxb:txw2:jar:2.3.6:compile
[INFO] +- com.sun.istack:istack-commons-runtime:jar:3.0.12:compile
[INFO] \- com.sun.activation:jakarta.activation:jar:1.2.2:runtime
TLDR: my classpath definition has been sabotaged by the Spring framework!
The solution, of course, is to tell the Spring framework to stop meddling with my classpath definition.
You can try two things - maybe they work individually, maybe they work only when applied together:
org.glassfish.jaxb:jaxb-runtime:jar:3.0.2
dependency declaration into your pom.xml
. This should override any automatic dependency resolution results.org.glassfish.jaxb
-groupId dependencies coming in from there:<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<!-- THIS -->
<exclusions>
<exclusion>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
Of course, the Spring framework itself may refuse to work with the updated org.glassfish.jaxb:jaxb-runtime:jar:3.0.2
dependency. You will find it out during testing.
I'll try to apply my suggestions to your repository to see what works.
I'll try to apply my suggestions to your repository to see what works.
The following dependency declaration seems to work with Spring framework:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<exclusion>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator-metro</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Override Jakarta XML Bind interface -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<!-- Override Jakarta XML Bind implementation -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>
</dependencies>
@doljae The lesson for you:
When you encounter a classpath conflict then do the following:
org.jpmml:pmml-evaluator-metro
dependency by printing out its classpath using mvn dependency:tree
.org.jpmml:pmml-evaluator-metro
dependency after it has been embedded into an actual application (here: Spring framework).@vruusmann Thank you for your kind answer π I understand the root cause of this problem through your comment.
If I use pmml-valuator-metro
as you commented, no compilation error will occur.
However, although it is not known exactly, if jakarta.xml.bind-api
and jaxb-runtime
are separately declared and used, there seems to be a problem somewhere in the code that uses the spring framework.
As a result of making and checking the same build.gradle
that you commented on pom.xml
, there is no problem with using jpmml
in an empty project, but it seems that there is a problem with the code using another spring code. (I doubt the something of Spring Test.)
In conclusion, I confirmed that to use jpmml version 1.6.3
as my project was built the same as before, I had to have the following dependency combination.
dependency("org.jpmml:pmml-evaluator:1.6.3") // or using -metro
dependency("jakarta.xml.bind:jakarta.xml.bind-api:3.0.1")
dependency("org.glassfish.jaxb:jaxb-runtime:3.0.2")
dependency("jakarta.activation:jakarta.activation-api:2.1.0")
dependency("javax.xml.bind:jaxb-api:2.3.1")
I think the Spring team already knows this part and expects that it is deliberately eroding the current dependency structure. Nevertheless, I am going to ask the spring team about this issue.
Separately, under the current situation, it is difficult to use jpml 1.6.x with spring projects. So I am considering downgrading to 1.5 version
and using the extension dependency that I used before. For the purpose of this dependency, I think it would be okay not to use the latest version.
Anyway, thanks to your comment, I learned a lot about dependency structure. Thank you again π
there seems to be a problem somewhere in the code that uses the spring framework.
Your spring application compiles without errors, but when you actually run it, it throws some classpath conflict error?
In principle, it is possible to configure the build so that JPMML-Evaluator and Spring have their own Jakarta XML Binding library versions (all within the same uber-JAR file). This trick is called "package relocation", and it is rather easy to implement using Apache Maven: https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
I don't have time to provide an example today, but maybe later this week.
@vruusmann I don't know how many times I say thank you.
Anyway, I briefly looked up the concept of package relocation
you mentioned, and it seems that the only way to utilize this is to currently enable me to use latest spring boot and jpmml 1.6.x.
(I'm trying to see your exact example and apply a gradle script that does the same thing.)
I found the PR below in the spring-boot
project, that is, the project responsible for the part where spring automatically manages sub-dependencies.
The milestone for this PR is 2.7.0-M2
. In other words, with a very high probability, Glassfish 2.3.6
will be used for 2.7 GA.
Currently, the latest Spring boot version is 2.6.7
. It is expected to use 3.x version of Glassfish in the Spring project someday, but it seems like a very distant future.
As far as I know, there doesn't seem to be any way to use the latest version of spring boot with jpmml other than the package relocation
you mentioned at the moment.
As far as I know, there doesn't seem to be any way to use the latest version of spring boot with jpmml other than the package relocation you mentioned at the moment.
OK, if the Spring framework does not work with the org.glassfish.jaxb:jaxb-runtime:3.0.2
dependency, then we cannot use it.
The simplest workaround on the JPMML-Evaluator side is to simply switch Jakarta XML Bind implementations. Next to the (default-) org.jpmml:pmml-evaluator-metro
dependency there is a org.jpmml:pmml-evaluator-moxy
dependency, which relies on the EclipseLink MOXy implementation.
In this setup, JPMML-Evaluator and Spring framework would be sharing JAXB interfaces as defined by the jakarta.xml.bind:jakarta.xml.bind-api:3.0.1
dependency (interfaces should be backwards compatible). However, during application execution, JPMML-Evaluator would be using the latest EclipseLink MOXy implementation, whereas Spring framework would be using a legacy GlassFish Metro implementation.
The following dependency configuration works fine with your sample project:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<exclusions>
<exclusion>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator-moxy</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Override Jakarta XML Bind interface -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
@doljae Perform the above dependency change, and try to run your Spring Boot application. Does the model loading succeed, or not?
There is a possibility that both components will be a little bit confused, because they see two JAXB implementations available at the same time, and cannot decide which one to use. In principle, it should be possible to "activate" one specific JAXB implementation (over all others) by specifying the jakarta.xml.bind.JAXBContextFactory
Java system property.
@vruusmann I tried your suggestion (use moxy, enforce jakarta.xml.bind-api 3.0.1), sadly it does not work π, I mean the error was occured during runtime(+running test cases), not compile time. According to the test failure logs, there's are two kinds of logs were occured.
jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at app//jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:255)
at app//jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:243)
Maybe this error is occured because as you said, There is a possibility that both components will be a little bit confused
.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
...
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.hibernate.boot.spi.XmlMappingBinderAccess.<init>(XmlMappingBinderAccess.java:43)
at org.hibernate.boot.MetadataSources.getXmlMappingBinderAccess(MetadataSources.java:115)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.prepare(MetadataBuildingProcess.java:110)
...
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
This error means Spring ApplicationContext cannot create JPA related java beans
, and the JPA implementations is Hibernate
. I comment the stack overflow link which said Hibernate need javax.xml.* packages
.
@vruusmann And maybe the spring team's answer is this article below
According to this link & article in the comment, Spring projects will use old version Glassfish until the release of Spring 6 & Boot 3, which mean the easiest way for using jpmml with Spring is to use jpmml 1.5.x with pmml-extension I guess.
To be honest, I am a beginner in this area. So I don't know well. If I want to use the latest version of jpmml, there seems to be no other way than package relocation as you said.
1: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
The problem is that LoadingModelEvaluatorBuilder
is trying to locate the intended Jakarta XML Binding implementation in a very safe and stable way, using the Jakarta XML Binding interface methods:
https://github.com/jpmml/jpmml-evaluator/blob/1.6.3/pmml-evaluator/src/main/java/org/jpmml/evaluator/LoadingModelEvaluatorBuilder.java#L143
The org.jpmml.model.JAXBUtil#createUnmarshaller()
utility method works fine if the application classpath has been set up orderly. Specifically, there is one conflict-free JAXB implemenntation available.
In the current case, it would be nice if we could tell to LoadingModelEvaluatorBuilder
that we want to load the PMML XML document using EclipseLink MOXy unmarshaller.
Something like this would be ideal:
EvaluatorBuilder evaluatorBuilder = new LoadingModelEvaluatorBuilder()
.setJAXBContext(org.eclipse.persistence.jaxb.JAXBContext.class)
.load("mymodel.pmml");
Evaluator evaluator = evaluatorBuilder.build();
- java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Looks like jakarta.xml.bind:jakarta.xml.bind-api:2.3.3
and jakarta.xml.bind:jakarta.xml.bind-api:3.0.1
dependencies are not equivalent, because the former contains javax.xml.bind.*
classes and the latter jakarta.xml.bind.*
classes. I was fooled by the dependency prefix "jakarta".
In principle your project should include these two dependencies (the former for Spering framework, the latter for JPMML-Model/JPMML-Evaluator). Unfortunately, this is not technically possible, because dependency names (as defined by groupId
plus artifactId
) must be unique.
So, the solution is to replace the jakarta.xml.bind:jakarta.xml.bind-api:2.3.3
dependency with some other (differently named-) dependency that contains all javax.xml.bind.*
classes.
Maybe javax.xml.bind:jaxb-api:2.3.1
is the best option here.
@doljae Looks like you need to stick with JPMML-Evaluator 1.5.X a little bit longer, until I extend the LoadingModelEvaluatorBuilder
class with a setter for specifying the Jakarta XML Binding implementation class.
Will probably happen in the 1.6.4 release. However, the ETA of 1.6.4 is currently unknown.
@vruusmann OK, I'll try to check if I'm following the context properly.
Latest Spring related dependencies use javax.xml.bind.*
, because Spring enforce to use org.glassfish.jaxb:jaxb-runtime:jar:2.3.6
Latest jpmml (1.6.x) use jakarta.xml.bind-api:3.x.x
, because it uses glassfish 3.x.x
Current jpmml makes conflict if there are more than one implementation of JAXBContext.
In this situation, latest jpmml use jakarta.xml.bind.*
, so there are only one choice with Spring,
*_enforce glassfish 3.x.x & add additional dependencies for api & implementation of javax.xml.bind._**
Although you release jpmml 1.6.4 which has new feature: LoadingModelEvaluatorBuilder class with a setter for specifying the Jakarta XML Binding implementation class
, using with spring project makes conflict because spring enforce to use org.glassfish.jaxb:jaxb-runtime:jar:2.3.6
and latest jpmml use jakarta.xml.bind.*
, not javax.xml.bind.*
If you make another type of jpmml for this situation(like metro, moxy), which has javax.xml.bind.*
, maybe it does not conflict with Spring.
(I wasn't talking about making something like this. I was just trying to make sure I understand what you're saying, and I hope you don't misunderstand me. Of course, if there is, many Spring users will be happy.)
In comment https://github.com/jpmml/jpmml-evaluator/issues/246#issuecomment-1130977138 points 1, 2 and 4 are correct. Point 3 not so much.
Let's elaborate a bit further:
The *:bind-api
dependency is responsible for defining JAXB interface classes, whereas the *:jaxb-runtime
is responsible for defining JAXB implementation classes. They must always match at the major version level (2.3 interfaces with 2.3 runtime; 3.0 interfaces with 3.0 runtime).
The resolution of the JAXBContext
class is initiated via JAXB interface methods:
javax.xml.bind.JAXBContext#newInstance()
.jakarta.xml.bind.JAXBContext#newInstance()
.Note the different package prefix javax
vs jakarta
!
Now in principle, it whould be possible to have JAXB 2.3 and 3.0 versions peacefully co-exist in one Java application. Spring framework is hard-coded to work with the 2.3 version, and JPMML-Evaluator with the 3.0 version!
That's the theory. In the current case the situation is a bit more complicated because we have a jakarta.xml.bind:jakarta.xml.bind-api
which cannot be included twice into Apache Maven-managed classpath (we would like to include both of its 2.3 and 3.0 versions). We can work around this by replacing jakarta.xml.bind:jakarta.xml.bind-api:2.3.3
with javax.xml.bind:jaxb-api:2.3.1
.
@doljae Can you develop your sample project a bit further to make it "do some Spring + PMML business logic" during unit testing?
It would be much easier to suggest classpath workarounds when I have an instant feedback mechanism available. Right now I must rely on your comments.
@vruusmann
Thank you for your support. In fact, there is a security problem in the company that uses pmml, so I am worried about this part. I will try to create a spring boot project based on maven and upload an example sample.
In fact, reproducing the error is simple. After writing only one class or method of jpmml as code, it can be reproduced by writing code using hibernate and DB of spring data jpa and testing, run and build.
(If the Glassfish version is not fixed to 3.0.x, a compilation error occurs. If fixed, a JAXBException occurs in JPA-related classes
)
Anyway, I'll try to share a sample project as soon as possible. thank you.
@vruusmann OK, I reproduced the error. Repository link : https://github.com/doljae/jpmml-maven-test
You can reproduce the error by testing in this order. The pom.xml is tuned the same as when using the metro dependency you gave.
This way I can reproduce the 2nd error I commented on. (Of course, I have to use gradle, not maven, so I can't use a method to solve it using maven's some special plugins(if exists π )
Repository link : https://github.com/doljae/jpmml-maven-test
This repository still contains a deficient pom.xml
.
However, it wasn't difficult to fix (as explained in https://github.com/jpmml/jpmml-evaluator/issues/246#issuecomment-1131217181):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- Free the 'jakarta.xml.bind:jakarta.xml.bind-api' dependency groupId:artifactId slot for re-definition -->
<exclusions>
<exclusion>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator-metro</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Define Java XML Bind interface for Spring -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Define Jakarta XML Bind interface for JPMML-Evaluator -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
Please note that I didn't need to explicitly define the org.glassfish.jaxb:jaxb-runtime:3.0.2
dependency, because it's coming in automatically via pmml-evaluator-metro
.
After this change, the project builds and tests cleanly:
$ mvn clean install
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.2.2:jar (default-jar) @ demo ---
[INFO] Building jar: /tmp/jpmml-maven-test/target/demo-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.6.7:repackage (repackage) @ demo ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.479 s
[INFO] Finished at: 2022-05-19T19:12:09Z
[INFO] ------------------------------------------------------------------------
@vruusmann
OK, I tried using the pom.xml you commented and verified that my project works fine. I tried writing a gradle script with a similar configuration and it works equally well π
The problem is that this is my test project and I still get the error in my main project π
The error log is as follows.
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at app//org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
... 149 more
Caused by: jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at app//org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
... 149 more
[java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory]
at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
at app//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
It seems difficult for me to reproduce this in my test project. This error was occured when I try to add Evaluator
implementation class to ApplicationContext.
This is sample code in my main project
@Bean
public Evaluator mainEvaluator() throws Exception {
return loadEvaluator("XXXX.pmml"); // -> exception point!, jakarta.xml.bind.JAXBException: Implementation of Jakarta XML Binding-API has not been found on module path or classpath.
}
private Evaluator loadEvaluator(String pmmlFileName){
...
return evaluator;
}
I also leaves the state of the dependency tree for confirmation.
./gradlew :dependencyInsight --dependency javax.xml.bind
> Task :dependencyInsight
javax.xml.bind:jaxb-api:2.3.1 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
javax.xml.bind:jaxb-api:2.3.1
\--- org.hibernate:hibernate-core:5.4.33
+--- org.springframework.boot:spring-boot-starter-data-jpa:2.5.8
| \--- compileClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)
\--- org.hibernate:hibernate-envers:5.4.33
\--- org.springframework.data:spring-data-envers:2.5.7 (requested org.hibernate:hibernate-envers:5.4.32.Final)
\--- compileClasspath (requested org.springframework.data:spring-data-envers)
javax.xml.bind:jaxb-api -> 2.3.1
\--- compileClasspath
(*) - dependencies omitted (listed previously)
./gradlew :dependencyInsight --dependency jakarta.xml.bind
> Task :dependencyInsight
jakarta.xml.bind:jakarta.xml.bind-api:3.0.1 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
jakarta.xml.bind:jakarta.xml.bind-api:3.0.1
\--- org.jpmml:pmml-model:1.6.3
+--- org.jpmml:pmml-evaluator:1.6.3
| \--- org.jpmml:pmml-evaluator-metro:1.6.3
| \--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
\--- org.jpmml:pmml-model-metro:1.6.3
\--- org.jpmml:pmml-evaluator-metro:1.6.3 (*)
jakarta.xml.bind:jakarta.xml.bind-api -> 3.0.1
\--- compileClasspath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 -> 3.0.1
\--- org.glassfish.jaxb:jaxb-runtime:2.3.5
+--- org.jpmml:pmml-model-metro:1.6.3 (requested org.glassfish.jaxb:jaxb-runtime:3.0.2)
| \--- org.jpmml:pmml-evaluator-metro:1.6.3
| \--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
\--- org.hibernate:hibernate-core:5.4.33 (requested org.glassfish.jaxb:jaxb-runtime:2.3.1)
+--- org.springframework.boot:spring-boot-starter-data-jpa:2.5.8
| \--- compileClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)
\--- org.hibernate:hibernate-envers:5.4.33
\--- org.springframework.data:spring-data-envers:2.5.7 (requested org.hibernate:hibernate-envers:5.4.32.Final)
\--- compileClasspath (requested org.springframework.data:spring-data-envers)
(*) - dependencies omitted (listed previously)
./gradlew :dependencyInsight --dependency glassfish
> Task :dependencyInsight
org.glassfish.jaxb:jaxb-runtime:2.3.5 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.glassfish.jaxb:jaxb-runtime:2.3.1 -> 2.3.5
\--- org.hibernate:hibernate-core:5.4.33
+--- org.springframework.boot:spring-boot-starter-data-jpa:2.5.8
| \--- compileClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)
\--- org.hibernate:hibernate-envers:5.4.33
\--- org.springframework.data:spring-data-envers:2.5.7 (requested org.hibernate:hibernate-envers:5.4.32.Final)
\--- compileClasspath (requested org.springframework.data:spring-data-envers)
org.glassfish.jaxb:jaxb-runtime:3.0.2 -> 2.3.5
\--- org.jpmml:pmml-model-metro:1.6.3
\--- org.jpmml:pmml-evaluator-metro:1.6.3
\--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
org.glassfish.jaxb:txw2:2.3.5 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.glassfish.jaxb:txw2:2.3.5
\--- org.glassfish.jaxb:jaxb-runtime:2.3.5
+--- org.jpmml:pmml-model-metro:1.6.3 (requested org.glassfish.jaxb:jaxb-runtime:3.0.2)
| \--- org.jpmml:pmml-evaluator-metro:1.6.3
| \--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
\--- org.hibernate:hibernate-core:5.4.33 (requested org.glassfish.jaxb:jaxb-runtime:2.3.1)
+--- org.springframework.boot:spring-boot-starter-data-jpa:2.5.8
| \--- compileClasspath (requested org.springframework.boot:spring-boot-starter-data-jpa)
\--- org.hibernate:hibernate-envers:5.4.33
\--- org.springframework.data:spring-data-envers:2.5.7 (requested org.hibernate:hibernate-envers:5.4.32.Final)
\--- compileClasspath (requested org.springframework.data:spring-data-envers)
(*) - dependencies omitted (listed previously)
./gradlew :dependencyInsight --dependency jpmml
> Task :dependencyInsight
org.jpmml:pmml-evaluator:1.6.3
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.jpmml:pmml-evaluator:1.6.3
\--- org.jpmml:pmml-evaluator-metro:1.6.3
\--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
org.jpmml:pmml-evaluator-metro:1.6.3 (selected by rule)
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.jpmml:pmml-evaluator-metro -> 1.6.3
\--- compileClasspath
org.jpmml:pmml-model:1.6.3
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.jpmml:pmml-model:1.6.3
+--- org.jpmml:pmml-evaluator:1.6.3
| \--- org.jpmml:pmml-evaluator-metro:1.6.3
| \--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
\--- org.jpmml:pmml-model-metro:1.6.3
\--- org.jpmml:pmml-evaluator-metro:1.6.3 (*)
org.jpmml:pmml-model-metro:1.6.3
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.category = library
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 17
]
org.jpmml:pmml-model-metro:1.6.3
\--- org.jpmml:pmml-evaluator-metro:1.6.3
\--- compileClasspath (requested org.jpmml:pmml-evaluator-metro)
(*) - dependencies omitted (listed previously)
@vruusmann
I reproduced the error which I mentioned in the previous comment. You can reproduce the error by testing in this order. (same as before)
Repository link : https://github.com/doljae/jpmml-maven-test
- Execute docker/docker-compose.yml to load the MySQL container.
- Execute the EmployeeJpaTest.test() method.
I changed test configuration from @DataJpaTest to @SpringBootTest, which scan all Java bean from Configuration file(in this case, JPMMLConfiguration) and register it to ApplicationContext.
java.lang.ClassNotFoundException: org.glassfish.jaxb.runtime.v2.ContextFactory at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
It means that the Spring framework cannot find JAXB implementation classes.
Yesterday evening, I showed you how to fix your application classpath for JAXB interface classes. Now you need to do the same for JAXB implementations.
Looks like the application classpath only contains "new" JAXB implementation (org.glassfish.jaxb:jaxb-runtime:3.0.2
), which is OK by JPMML-Evaluator, but is not OK for Spring framework.
Again, as explained in my above comments (yesterday), the easiest way to do so is to switch from GlassFish Metro to EclipseLink MOXy for the JPMML-Evaluator components. You haven't done so in your pom.xml
yet.
@vruusmann
It is clear that I do not fully understand this classpath and xml related dependencies.
However, even if any of the latest versions of jpmml including jpmml-metro
and jpmml-moxy
are used, it seems to be necessary to exclude specific dependencies and add dependencies that provide separate apis and implementations to avoid conflicts with Spring. (at least 2 or more)
As I commented at the beginning, I can use the latest version of jpmml with Spring by adding a dependency that can catch errors that occur. (exclude xml api, add new xml api, add implementation, etc...)
However, I am skeptical that this is a good choice in my current development environment compared to using the 1.5 version. And this will be the same for users who use other Spring.
So I think it is a good choice to roll back to version 1.5 in my project environment considering the unpredictable side effects. As of Spring Boot 3, Jakarta.xml.bind.*
classpath will be used to match related dependency compatibility, and it seems best for now to bring the latest jpmml version.
@vruusmann
Apart from this, it would be good to add a guide to jpmml version selection for users using the Spring project to the README. If it's okay, I'll post a PR on the relevant part.
it would be good to add a guide to jpmml version selection for users using the Spring project
This topic can be generalized further: "How to configure application classpath so that it would contains BOTH Java XML Binding (javax.xml.bind.*
) and Jakarta XML Binding (jakarta.xml.bind.*
) classes".
Your concern is about the Spring framework. Yesterday, when I was performing JPMML-SparkML library upgrade, then I found a similar classpath conflict in Apache Spark ML 3.X versions as well.
I'm currently thinking about doing a small blog post about diagnostics & workarounds & final resolution.
If it's okay, I'll post a PR on the relevant part.
You can drop your "condensed resolution" into this thread.
Later, it will be possible to pin this issue for better visibility for the next one-two years (until the world catches up with jakarta.xml.bind.*
classes).
@vruusmann
Sorry for the late reply.
Later, it will be possible to pin this issue for better visibility for the next one-two years (until the world catches up with > jakarta.xml.bind.* classes).
I strongly agree with your opinion. I'm sure pinning this issue will help many jpmml users (including those using Spring).
To be honest, I didn't think I would be able to comment and support this issue for this long. Thank you for your active support π
When the latest version of jpmml(1.6.x) coexists with Spring Framework 5 and Spring Boot 2
projects, an error occurs due to sub-dependency conflicts. Please refer to this issue for related history.
After the release and migration of Spring Framework 6, Spring Boot 3
, it is expected that there will be no conflicts with the latest version of jpmml. Until then, we recommend that you consider using the 1.5.x version.
I maintain my position that it is possible for a single application to make use of both Java XML Binding and Jakarta XML Binding APIs, without any compile-time or run-time classpath conflicts.
Attached is a small demo project jaxb_demo.zip
, which contains a small and self-contained proof about it.
Workflow:
jaxb_demo.zip
.jaxb_demo.zip
, and step into the jaxb_demo
directory.mvn clean install
.Example runs:
JAVA_HOME
environment variable. This demo project works fine with all Java 8 though 17 versions.$JAVA_HOME/bin/java -Djakarta.xml.bind.JAXBContextFactory=org.eclipse.persistence.jaxb.JAXBContextFactory -jar target/jaxb_demo-executable-1.0-SNAPSHOT.jar etc/DecisionTreeIris.pmml
.The demo application class jaxb.demo.Demo
prints out the following information:
javax.xml.bind.JAXBContext
object instance - this is the entry point for Java XML Binding users.jakarta.xml.bind.JAXBContext
object instance - this is the entry point for Jakarta XML Binding users.org.jpmml.evaluator.Evaluator
object instance - this is the entry point for JPMML-Evaluator users.A couple of things to pay attention to in jaxb_demo/pom.xml
:
org.jpmml:pmml-evaluator-moxy
dependency. The intent is to bring in an alternative EclipseLink MOXy JAXB runtime, which is independent from the "default" GlassFish Metro JAXB runtime.jakarta.xml.bind:jakarta.xml.bind-api:2.3.3
with javax.xml.bind:jaxb-api:2.3.1
.jakarta.xml.bind.JAXBContextFactory
system property as org.eclipse.persistence.jaxb.JAXBContextFactory
. This activation can be performed using Java.exe command-line options, or from within the Java application code using the System#setProperty(String, String)
method.@vruusmann
I checked your demo project. I'm leaving a comment because I think you have some misunderstanding.
I also wrote in the first text of this issue that I left out that I solved the problem through a couple of dependency combinations. And with your explanation, I was able to raise my understanding and confirm it through the attached sample project. I learned a lot from your latest comment's explanation. π
For projects that do not use frameworks or do not have complex dependency relationships in build scripts, it is expected that there will be no problems using the latest version of jpmml.
As you better know, if it's a corporate project rather than an individual, small-scale project, you should be wary of work with a wide range of modifications. I think it's definitely justified to make a safer choice in this and this situation.
Personally, I prefer to use the latest version. If it was my personal project, I would have applied the method you suggested to use the latest version.
Anyway, it is true that it is inconvenient to use the latest version of jpmml from the perspective of a person using the Spring framework(or user who use some kind of dependency management plugins.
Dependencies that were used in one line become multiple lines, and some settings in the build script need to be modified as well. That's why in the previous comment, I left that it would be convenient to have a new jpmml-evaluator that uses the javax.xml.bind.*
package, that is, uses the 2.3.x version of the glassfish runtime.
Anyway, I'm sure that your comment on mixed use of Java XML Binding plus Jakarta XML Binding in detail will be helpful to many users. π
@doljae what did you finally end up doing? I am also stuck in a similar situation with 1.6.4 jpmml-evaluator.
@doljae what did you finally end up doing? I am also stuck in a similar situation with 1.6.4 jpmml-evaluator.
Hello, @paranjapeved15 π Like I said in my previous comment, I had an issue with the dependency management feature of the framework I was using in my project.
So I kept the existing 1.5.x
. The core features of jpmml that I have been using are similar to the 1.5
and 1.6
versions, and I decided that it would be okay not to apply the latest version, including the above troubleshooting, to the project.
If you want to use the 1.6.x
version and it is difficult to use 1.6.x
directly in your development environment, get a maintainer's guide or make sure that you can use jakarta.xml.*
sub-packages and classes in your project.
For the latter one, you will need to add a separate configuration or dependency.
FYI, if you're using Spring Boot, I know that the Boot 3 version of dependency management changed glassfish
to using the jakarta
package. So, if you use Boot 3 or higher, you will be able to use jpmml 1.6.x
without any special problems.
Of course you need to check π
@doljae Looks like you need to stick with JPMML-Evaluator 1.5.X a little bit longer, until I extend the
LoadingModelEvaluatorBuilder
class with a setter for specifying the Jakarta XML Binding implementation class.Will probably happen in the 1.6.4 release. However, the ETA of 1.6.4 is currently unknown.
@vruusmann did you extend the LoadingModelEvaluatorBuilder in 1.6.4?
Description
jpmml-evaluator
is insufficient to use.1.6.3
LoadingModelEvaluatorBuilder.java
Question 1
Question 2
org.jpmml:pmml-evaluator-extension:1.5.16
. With this dependency alone, I was able to use all the functions I wanted.pmml-evaluator-extension
seems to have been discontinued, and I added 7 dependencies to use jpmml as the latest version 1.6.x as before. And I spent a lot of time trying to catch the error.