Skip to content

Blackbird: skip generated setters the accessor can't call - #366

Merged
cowtowncoder merged 6 commits into
FasterXML:2.xfrom
parker89:pw/blackbird-setup-checks
Oct 30, 2026
Merged

cowtowncoder merged 6 commits into
FasterXML:2.xfrom
parker89:pw/blackbird-setup-checks

Conversation

@parker89

@parker89 parker89 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Some setters work through reflection but fail Blackbird's generated accessor, either during setup or when called. Regular beans can fail deserialization or fall back to reflection on every call. These problems already exist in released versions; they aren't caused by the builder change in #364.

First in the stack: #366 → #364 → #367. This fix stands on its own.

Leave a property to MethodProperty when:

  • The receiver or parameter types are inaccessible from the accessor, or can't be shown to be the same classes through its loader.
  • The identity of the return type or a narrowed receiver's declaring class cannot be established safely.
  • lookup.unreflect rejects an inherited setter that reflection can call.

Accessibility uses Lookup.accessClass on Java 9+ and a conservative package/loader check on Java 8. None of these checks loads a class: the receiver, parameter and return types, and a narrowed receiver's declaring class, must be defined by the accessor's own loader or be java.* types. Asking a child-first loader can otherwise define a conflicting copy, which can't be undone and breaks application code. As a result, properties with cross-loader signatures (including JDK javax.* types) may use reflection. Unsupported setters, such as double, bypass these checks.

When a check cannot establish that optimization is safe, the property stays reflective. Tests cover inaccessible types, child-first loaders, inherited setters, and checks that must not load classes, including that the application's own code still works afterwards. All Blackbird tests pass on Java 8, 11, 17 and 25.

parker89 and others added 5 commits October 29, 2026 09:22
Move the setter checks into `ReflectionHack.canLinkAccessor` and also use
it for getters, which could fail with a LinkageError on every call when
the bean's loader shadows a type in an inherited getter's signature.

Only check that signature types come from the lookup class's loader when
the method's declaring class doesn't: otherwise that loader already
resolved them, and setters such as ones taking a parent-loader or `javax.*`
type were needlessly left to reflection.

Like setters, leave getters that `unreflect` refuses to reflection instead
of failing the whole serializer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Newer JDKs don't name the declaring class of an inherited protected
method when calling it through a narrowed receiver, so only Java 8 needs
it to be the same class from the lookup class's loader; on JDK 14+ such
accessors are now optimized again.

Log at FINE when a setter or getter is left to reflection, so it's
possible to find out why a property isn't optimized.

Mention getters in the release notes for FasterXML#366, and add a test-base
`mapperBuilder` taking custom lookups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cowtowncoder cowtowncoder added the blackbird Issue related to Blackbird module label Oct 30, 2026
@cowtowncoder cowtowncoder added this to the 2.23.0 milestone Oct 30, 2026
@cowtowncoder
cowtowncoder merged commit 0e17487 into FasterXML:2.x Oct 30, 2026
4 checks passed
@cowtowncoder cowtowncoder changed the title Blackbird: skip generated setters the accessor can't call (2.x) Blackbird: skip generated setters the accessor can't call Oct 30, 2026
cowtowncoder added a commit to parker89/jackson-modules-base that referenced this pull request Oct 30, 2026
2.x has FasterXML#366 squashed; this branch already had it up to 2806ae1, so
resolve against that rather than the older merge base. Keep both release
notes entries and both sets of tests; builder tests now use
`_mapperWithLookupIn`, and expect inherited protected builder setters to
be optimized on JDK 14+ as for beans.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cowtowncoder added a commit to stevenschlansker/jackson-modules-base that referenced this pull request Oct 30, 2026
Brings FasterXML#366 (Blackbird: skip generated setters and getters the accessor
can't call) to 3.x. Ported to the 3.x test setup, where Blackbird runs as a
named module that doesn't read a child loader's unnamed module and so keeps
its own lookup: the child-loader tests now run both with and without that
read, expecting optimization accordingly.

That setup also showed `CreatorOptimizer` failing outright for such beans,
as `LambdaMetafactory` can't crack their constructor handle; leave those
creators to reflection instead. `TestBBClassloaders` now passes, so move it
out of `tofix`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cowtowncoder added a commit to stevenschlansker/jackson-modules-base that referenced this pull request Oct 30, 2026
Brings FasterXML#366, which patched the LambdaMetafactory engine this branch
replaced: keep this branch's engine (CreatorOptimizer and ReflectionHack
stay removed) and its ChildClassloaderTest, and drop TestReflectionHack.

Port the FasterXML#366 tests to the generated-codec engine, which handles every
scenario: assert generated readers and writers instead of per-property
classes, and drop the old engine's skip-logging test. Lookups are no
longer read, so drop the lookup helpers the 3.x port added and run those
tests with and without module reads instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cowtowncoder added a commit to parker89/jackson-modules-base that referenced this pull request Oct 30, 2026
…retries

Picks up the builder branch's merge of 2.x, which has FasterXML#366 squashed, so
this branch no longer conflicts with 2.x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cowtowncoder added a commit that referenced this pull request Oct 30, 2026
Brings #367 (Blackbird: don't retry failed bean setters through
reflection), and adds a 3.2.5 release notes section listing the
Blackbird changes from 3.1.9 (#363, #364, #366, #367).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.23 blackbird Issue related to Blackbird module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants