Multiple copies of Javabeans Activation Framework

Description

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 as javax.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 API

    • pulled 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 API

    • pulled in via Hibernate, I think

My evidence for the Hibernate source of these others is from the following dependency:tree extract from opensaml-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:

Looks like a bit of a mess, in fact.

Environment

None

Activity

Show:

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

Fixed

Details

Assignee

Reporter

Fix versions

Affects versions

Created May 28, 2019 at 1:53 PM
Updated April 21, 2020 at 3:01 PM
Resolved January 23, 2020 at 2:54 PM