Multiple copies of Javabeans Activation Framework
Description
Environment
Activity
Ian YoungJanuary 23, 2020 at 2:54 PM
Resolved by the following commits:
java-parent-project commit f0eec7b6d19c261d5887cd217814c2ccf51a3648
java-identity-provider commit 6d8c92eefbb691873d9da28f48c5d8ef7f8ff078
Ian YoungJanuary 20, 2020 at 11:41 AM
Using the jsplitpkgscan
application, I note that the remaining files still conflict, it's just that whatever we're doing in the build isn't noticing any more. Specifically:
javax.activation
27 file:/activation-1.1.1.jar
31 file:/jakarta.activation-api-1.2.1.jar
There are several other examples, which I'll cover in detail in IDP-1465.
It's clear that this is one example of a general pattern, where:
Originally, there was a single artifact called (in this case)
javax.activation:activation
, containing both the API and the implementation.The API and implementation are not separable here. They each depend on the other. They can't, therefore, be split into two artifacts.
To provide encapsulation pre-module system, current artifacts are:
com.sun.activation:jakarta.activation
is the implementation artifact, containing both API and implementation packages as before. The intention is that this is used at runtime.javax.activation:javax.activation-api
contains just the API classes (perhaps a different expression of the API that doesn't depend on the implementation, I don't know). The intention is that this is used at compile time and never included at runtime.
This pattern seems to be repeated for Activation, Mail and JAXB in particular, but probably other modules as well.
We need to:
Stop managing the original artifact in the parent POM
Exclude any references to the API artifacts from modules having them as compile-time dependencies (unless they have been managed to "optional"
Ensure that the implementation artifacts are included at runtime
Enforce that the _API-only_ artifacts are not included at runtime
Run
jpkgsplitscan
on products to make sure they don't have split packages because of this setup: they might not work at runtime, depending on which of the two implementations of the API packages "wins", which I don't think is guaranteed.
Ian YoungJanuary 16, 2020 at 4:50 PM
First stage: exclude the duplicate activation dependency that comes from hibernate. I have also moved the management of this dependency from the opensaml-parent to the java-parent-project, which is where I think we want something that is also ultimately going to need to interact with the other activation dependency.
{{java-parent-project}} commit 80e10dfbb8386e49e40fbcc931486bec824fad35
java-opensaml
commit 8f2883f8648de27808e2a42aae60692102d2b086
This leaves the following in the distribution:
./webapp/WEB-INF/lib/activation-1.1.1.jar
./webapp/WEB-INF/lib/jakarta.activation-api-1.2.1.jar
Ian YoungJanuary 15, 2020 at 11:00 AM
hibernate-core 5.4.10.Final still references javax.activation:javax.activation-api:1.2.0
Ian YoungDecember 3, 2019 at 7:46 PM
hibernate-core 5.4.9.Final still references javax.activation:javax.activation-api:1.2.0
I'm describing this in JPAR because ultimately this is probably going to need to be resolved at the level of the parent project, but there are implications for at least OpenSAML and the IdP.
I'll start with the IdP observation. In IdP v3, we have one copy of the Javabeans Activation Framework (JAF) in the form of
WEB-INF/lib/activation-1.1.jar
. This is managed in the java-parent-project POM asjavax.activation:activation:1.1
.This version hails from 2006 and contains the following packages:javax.activation (the API)
com.sun.activation.registries (implementation?)
com.sun.activation.viewers (implementation?)
In current snapshots of the v4 IdP, we have no less than three files:
activation-1.1.1.jar
javax.activation:activation:1.1.1
(note new version number, from 2009).managed by java-parent-project
contains the API and the implementation
javax.activation-api-1.2.0.jar
javax.activation:activation-api:1.2.0
(from 2017)just contains the
javax.activation
APIpulled in via Hibernate, I think
jakarta.activation-api-1.2.1.jar
jakarta.activation:jakarta.activation-api:jar:1.2.1
(from 2018)just contains the
javax.activation
APIpulled in via Hibernate, I think
My evidence for the Hibernate source of these others is from the following
dependency:tree
extract fromopensaml-storage-impl
:[INFO] +- org.hibernate:hibernate-core:jar:5.4.2.Final:compile [INFO] | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile [INFO] | +- javax.persistence:javax.persistence-api:jar:2.2:compile [INFO] | +- org.javassist:javassist:jar:3.24.0-GA:compile [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:compile [INFO] | +- antlr:antlr:jar:2.7.7:compile [INFO] | +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:jar:1.1.1.Final:compile [INFO] | +- org.jboss:jandex:jar:2.0.5.Final:compile [INFO] | +- com.fasterxml:classmate:jar:1.3.4:compile [INFO] | +- javax.activation:javax.activation-api:jar:1.2.0:compile [INFO] | +- org.dom4j:dom4j:jar:2.1.1:compile [INFO] | +- org.hibernate.common:hibernate-commons-annotations:jar:5.1.0.Final:compile [INFO] | +- javax.xml.bind:jaxb-api:jar:2.3.1:compile [INFO] | \- org.glassfish.jaxb:jaxb-runtime:jar:2.3.2:compile [INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile [INFO] | +- org.glassfish.jaxb:txw2:jar:2.3.2:compile [INFO] | +- com.sun.istack:istack-commons-runtime:jar:3.0.8:compile [INFO] | +- org.jvnet.staxex:stax-ex:jar:1.8.1:compile [INFO] | +- com.sun.xml.fastinfoset:FastInfoset:jar:1.2.16:compile [INFO] | \- jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
Of course, this may not be the only source: it's the only one I found, in passing, because the Javadoc generation in https://shibboleth.atlassian.net/browse/JPAR-129#icft=JPAR-129 noticed the multiple sources of the
javax.activation
package and gave me a screen-full of errors.All of these are going to end up on the classpath, and I don't think that can be assumed to end well for anyone.
I need to look into how this is supposed to work, but my suspicion is:
We probably should not be shipping an implementation of the JAF any more, but perhaps referring to it as a provided dependency
Regardless, we shouldn't be shipping the 2009 version at all. If not, this restriction should be enforced.
We might want to ship one or other of the API packages which provide the API, but only one of them. We need to manage dependencies on the one we want, enforce exclusion of the other one, and manage dependencies on hibernate and its
jaxb-runtime
dependency to exclude the one we don't want.I will note that if you Google around you can find other people with related issues, for example:
https://github.com/eclipse-ee4j/jaxb-stax-ex/issues/21
https://github.com/eclipse-ee4j/jaf/issues/18
https://github.com/eclipse-ee4j/jaxb-ri/issues/1284
https://github.com/eclipse-ee4j/jaxb-ri/pull/1296
Looks like a bit of a mess, in fact.