JAXB3 Migration#1023
Conversation
… 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
left a comment
There was a problem hiding this comment.
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:
-
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-forfor (Type x : rawList)over a list of wrappers → ClassCastException. It only compiles because the list is declared as a rawList.
- Any remaining raw cast
-
Optional elements are now nullable wrappers.
AgetXxx().getValue()chain on an absent (optional) element → NullPointerException, and the existingif (x != null)guard below becomes dead code. -
ObjectFactory.createXxx()factory methods now take a value argument.
Passing the subtypeAttributeServiceTypeinto a factory whose declared value type isEndpointTypemakes JAXB emit a spuriousxsi: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 |
7× 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.
- RestAuthNameValueOutputCallbackHandler.java: keep correct NameValueOutputCallback Javadoc - ResourceOwnerSessionValidator.java: merge copyright attributions
No description provided.