Skip to content

JAXB3 Migration#1023

Open
maximthomas wants to merge 17 commits into
OpenIdentityPlatform:masterfrom
maximthomas:features/jaxb3-update-2026-05-19
Open

JAXB3 Migration#1023
maximthomas wants to merge 17 commits into
OpenIdentityPlatform:masterfrom
maximthomas:features/jaxb3-update-2026-05-19

Conversation

@maximthomas

Copy link
Copy Markdown
Contributor

No description provided.

@maximthomas maximthomas requested a review from vharseko May 21, 2026 10:13
@vharseko vharseko linked an issue May 27, 2026 that may be closed by this pull request
@vharseko vharseko added this to the 16.2.0 milestone Jun 1, 2026
vharseko added 11 commits June 20, 2026 12:56
… after JAXB3 migration

getIDPSSOConfigOrSPSSOConfig() now returns List<JAXBElement<BaseConfigType>>,
but removeFromEntityConfig still cast elements directly to BaseConfigType /
AttributeType. Unwrap via getValue(), mirroring addToEntityConfig.
…B3 migration

getSingleLogoutService() returns List<SingleLogoutServiceElement> (JAXBElement
wrappers); unwrap to List<EndpointType> before LogoutUtil.doLogout().
Unwrap the SingleLogoutService wrapper list to List<EndpointType> before
LogoutUtil.doLogout(). The wrapper-expecting getSLOServiceLocation() path is
left unchanged.
…r JAXB3 migration

convertAttributes() added the AttributeValueElement wrapper instead of its
content to the list passed to setAttributeValueString(), which casts each
element to String. Add the unwrapped value.
…ws after JAXB3 migration

getIDPSSOConfigOrSPSSOConfigOrAuthnAuthorityConfig() returns
List<JAXBElement<BaseConfigType>>; unwrap via getValue() before use.
…ter JAXB3 migration

getUse() returns null when the optional use attribute is absent (one key for
both signing and encryption); guard before calling value().
… migration

SingleLogoutService / NameIDMappingService / AuthnQueryService /
AssertionIDRequestService endpoints were created with createAttributeServiceType(),
which injects a spurious xsi:type="AttributeServiceType" on marshal. Use
createEndpointType().
…DFFCOTUtils after JAXB3 migration

getAffiliationDescriptorConfig() is null for ordinary SP/IDP entities; guard the
wrapper before getValue() in add/remove EntityConfig.
…ements after JAXB3 migration

Optional JAXB elements are now possibly-null JAXBElement wrappers. Add a
null-safe jaxbValue() helper in IDPPBaseContainer and use it across the IDPP
container read-back methods.
…nt after JAXB3 migration

getIDPSSODescriptor() can return null for an unknown issuer; reject with
InvalidGrantException instead of dereferencing the null wrapper.
AttributeValueElement.getValue() returns the scalar content (not a List) for
string-valued attributes, so the "instanceof List" guard silently skipped
context matching. Normalize scalar and list content to restore the previous
getContent() behaviour.

@vharseko vharseko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1023 "JAXB3 Migration" — fix registry

Branch tip after follow-up work: f168117cc6 (11 commits on top of 63ff4448ae).
PR: #1023


Root cause (common to all 11 fixes)

The migration moves XML binding from JAXB 1.0 / javax.xml.bind to JAXB 3.0 / jakarta.xml.bind and stops checking generated classes into the repo — they are now generated at build time (jaxb-maven-plugin). In doing so the shape of the generated API changes, which breaks consumer code in three ways that compile but fail at runtime:

  1. Global XML elements are now JAXBElement<T> wrappers.
    A getter that used to return the concrete type now returns a wrapper, so callers must call .getValue().

    • Any remaining raw cast (Type) iter.next() or enhanced-for for (Type x : rawList) over a list of wrappers → ClassCastException. It only compiles because the list is declared as a raw List.
  2. Optional elements are now nullable wrappers.
    A getXxx().getValue() chain on an absent (optional) element → NullPointerException, and the existing if (x != null) guard below becomes dead code.

  3. ObjectFactory.createXxx() factory methods now take a value argument.
    Passing the subtype AttributeServiceType into a factory whose declared value type is EndpointType makes JAXB emit a spurious xsi:type="AttributeServiceType" on marshal → invalid SAML2 metadata.


Commit registry

# Commit File(s) Type Essence
1 dac13f3c06 WSFederationCOTUtils.java CCE remove path not migrated
2 9e8cad2dd5 SAML2SingleLogoutHandler.java CCE wrappers into doLogout(List<EndpointType>)
3 ea473f7fc0 SPSingleLogout.java CCE same in SP SLO
4 6a4d81419b AttributeQueryUtil.java CCE wrapper added instead of value
5 3435063154 GetCircleOfTrusts.java, ImportSAML2MetaData.java CCE raw cast to BaseConfigType
6 271ad11235 SAMLv2ModelImpl.java NPE getUse() == null
7 faf0be2e7e SAMLv2ModelImpl.java XML spurious xsi:type on endpoints
8 d9d4b8e13e IDFFCOTUtils.java NPE no affiliation config
9 5aa4d1c5e3 IDPP* containers NPE optional Liberty PP elements
10 f77dbb76bd Saml2GrantTypeHandler.java NPE unknown issuer
11 f168117cc6 SAML2IDPProxyFRImpl.java logic silently disabled context matching

Per-fix detail

1. dac13f3c06 — WSFederationCOTUtils.removeFromEntityConfig (CCE)

File: openam-federation-library/.../wsfederation/meta/WSFederationCOTUtils.java
Problem: getIDPSSOConfigOrSPSSOConfig() returns List<JAXBElement<BaseConfigType>>. addToEntityConfig was migrated to .getValue(), but the sibling removeFromEntityConfig was not: it still did (BaseConfigType) iter.next() and (AttributeType) iter2.next(). Removing a WS-Fed entity from a circle of trust → CCE.
Fix: generics + .getValue(), mirroring the add method.

2. 9e8cad2dd5 — Multi-protocol SOAP single logout (CCE)

File: .../multiprotocol/SAML2SingleLogoutHandler.java
Problem: getSingleLogoutService()List<SingleLogoutServiceElement> (which are JAXBElement<EndpointType>). The list is passed to LogoutUtil.doLogout(List<EndpointType>), whose for (EndpointType e : list) → CCE. Sibling paths (IDPSessionListener/SPSessionListener) were fixed; this one was missed.
Fix: .stream().map(JAXBElement::getValue).collect(...) before doLogout.

3. ea473f7fc0 — SP single logout (CCE)

File: .../saml2/profile/SPSingleLogout.java
Problem: same wrapper list passed into doLogout(List<EndpointType>).
Fix: unwrap to List<EndpointType>. The second slosList (feeds getSLOServiceLocation, which expects the wrappers) is intentionally left unchanged.

4. 6a4d81419b — SAML2 attribute query conversion (CCE)

File: .../saml2/profile/AttributeQueryUtil.java
Problem: convertAttributes() added the wrapper AttributeValueElement instead of its content. The list goes to setAttributeValueString(), which does (String) iter.next() → CCE. The computed content was unused.
Fix: add content (the unwrapped value).

5. 3435063154 — OpenFM workflows (CCE)

Files: OpenFM/.../workflow/GetCircleOfTrusts.java, ImportSAML2MetaData.java
Problem: getIDPSSOConfigOrSPSSOConfigOrAuthnAuthorityConfig()List<JAXBElement<BaseConfigType>>, but the code did (BaseConfigType) config.iterator().next() → CCE when resolving the realm for a hosted entity.
Fix: generics + .getValue().

6. 271ad11235 — KeyDescriptor without use (NPE)

File: openam-console/.../federation/model/SAMLv2ModelImpl.java
Problem: keyOne.getValue().getUse().value()getUse() is null when a <KeyDescriptor> omits the optional use attribute (one key for both signing and encryption). The next line if (type == null ...) was written for exactly that null case but is now unreachable. NPE when viewing the entity in the console.
Fix: null guard before .value().

7. faf0be2e7e — invalid metadata endpoints (XML)

File: openam-console/.../federation/model/SAMLv2ModelImpl.java
Problem: SingleLogoutService / NameIDMappingService / AuthnQueryService / AssertionIDRequestService endpoints were built with createAttributeServiceType(). Since AttributeServiceType extends EndpointType, marshalling injects a spurious xsi:type="AttributeServiceType" → off-schema metadata. 8 sites.
Fix: createEndpointType(). The two legitimate createAttributeServiceElement(createAttributeServiceType()) sites are left untouched.

8. d9d4b8e13e — IDFFCOTUtils without affiliation config (NPE)

File: .../federation/meta/IDFFCOTUtils.java
Problem: getAffiliationDescriptorConfig().getValue() — for ordinary SP/IDP entities the getter is null, so .getValue() fails before the dead if (affiConfig != null) check. 2 sites (add/remove EntityConfig).
Fix: null-check the wrapper before .getValue().

9. 5aa4d1c5e3 — Liberty Personal Profile containers (NPE)

Files: IDPPBaseContainer.java + IDPPFacade, IDPPDemographics, IDPPLegalIdentity, IDPPEmploymentIdentity, IDPPCommonName, IDPPAddressCard
Problem: read-back methods (getXxxMap/createAddressCard) do obj.getXxx().getValue() on optional PP elements; for absent ones (common, e.g. middle name) → NPE. The old code stored the nullable value and downstream getAttributeMap handled null fine.
Fix: add protected static <T> T jaxbValue(JAXBElement<T>) to the base class and apply it at every read site.

10. f77dbb76bd — OAuth2 SAML2 bearer, unknown issuer (NPE)

File: openam-oauth2-saml2/.../core/Saml2GrantTypeHandler.java
Problem: metaManager.getIDPSSODescriptor(...) can return null for an unknown issuer; idpSsoDescriptor.getValue() → NPE. Previously null was handled gracefully (clean rejection). This turns a rejection into an uncaught exception.
Fix: null-check the descriptor → InvalidGrantException("Unknown assertion issuer").

11. f168117cc6 — IDP proxy: authn-context matching (logic)

File: .../saml2/plugins/SAML2IDPProxyFRImpl.java
Problem: AttributeValueElement.getValue() returns a scalar (String) for string-valued attributes, not a List, so the instanceof List guard silently skipped the whole proxy-IDP authn-context selection block (a silent regression, no error).
Fix: normalize scalar and list content to List, restoring the previous getContent() behaviour.


Verification

  • Build (JDK 26 / Maven 3.9.16) of the affected modules — BUILD SUCCESS:
    Federation Library, OpenFM, Admin Console, OAuth2-SAML2.
  • Schema modules (saml2/liberty/wsfederation/xacml3) build and generate classes correctly.
  • The cumulative diff of all 11 commits is byte-identical to the patch that was built and verified.
  • Push to the PR branch was a fast-forward (63ff4448ae..f168117cc6).

Still to verify manually (not covered by compilation)

  • JSPs (not compile-checked): SA_IDP.jsp, SA_SP.jsp, spSingleLogoutInit.jsp, realmSelection.jsp.
  • Functionally: SAML2 SLO (SOAP + multi-protocol), attribute query, COT add/remove (SAML2 / WS-Fed / IDFF), Liberty Personal Profile, OAuth2 SAML2 bearer.

vharseko added 2 commits June 20, 2026 14:07
- RestAuthNameValueOutputCallbackHandler.java: keep correct NameValueOutputCallback Javadoc
- ResourceOwnerSessionValidator.java: merge copyright attributions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAM has doubled in size since version 14

2 participants