Unfortunately, it is not possible to raise the byte code level beyond
Java 1.8 for classes generated using CGLIB due to the fact that CGLIB
generates STATICHOOK methods which set static final fields outside the
initializer method <clinit> (i.e., a static initialization block).
Attempting to raise the level to Java 17 (or even Java 9) results in
exceptions like the following.
Caused by: java.lang.IllegalAccessError: Update to static final field
org.example.MyBean$$SpringCGLIB$$0.CGLIB$THREAD_CALLBACKS attempted from
a different method (CGLIB$STATICHOOK1) than the initializer method <clinit>
at org.example.MyBean$$SpringCGLIB$$0.CGLIB$STATICHOOK1(<generated>)
at org.example.MyBean$$SpringCGLIB$$0.<clinit>(<generated>)
This commit therefore introduces inline comments pointing out why we
stay with Java 1.8 byte code level with CGLIB.
See gh-34602
FormHttpMessageConverter could throw a more specific
HttpMessageNotReadableException instead of an IllegalArgumentException
when the http form data is invalid.
See gh-34594
Signed-off-by: Russell Bolles <rbolles@netflix.com>
This commit removes the use of RepeatableContainers.of() in
AnnotationJmxAttributeSource since that is unnecessary when using the
MergedAnnotations API with @Repeatable annotations such as
@ManagedOperationParameter and @ManagedNotification.
Closes gh-34606
This commit introduces null-safe support for java.util.Optional in the
following SpEL operators:
- PropertyOrFieldReference
- MethodReference
- Indexer
- Projection
- Selection
- Elvis
Specifically, when a null-safe operator is applied to an empty
`Optional`, it will be treated as if the `Optional` were `null`, and
the subsequent operation will evaluate to `null`. However, if a
null-safe operator is applied to a non-empty `Optional`, the subsequent
operation will be applied to the object contained in the `Optional`,
thereby effectively unwrapping the `Optional`.
For example, if `user` is of type `Optional<User>`, the expression
`user?.name` will evaluate to `null` if `user` is either `null` or an
empty `Optional` and will otherwise evaluate to the `name` of the
`user`, effectively `user.get().getName()` for property access.
Note, however, that invocations of methods defined in the `Optional`
API are still supported on an empty `Optional`. For example, if `name`
is of type `Optional<String>`, the expression `name?.orElse('Unknown')`
will evaluate to "Unknown" if `name` is an empty `Optional` and will
otherwise evaluate to the `String` contained in the `Optional` if
`name` is a non-empty `Optional`, effectively `name.get()`.
Closes gh-20433
Prior to this commit, MockCookie.parse() failed with an
IllegalArgumentException when attempting to parse a custom attribute
with a value, such as "Version=1". This is a regression that was
inadvertently introduced in 7fc4937199
when adding support for the "Partitioned" attribute which does not
support a value.
This commit addresses this regression by parsing both the name and the
value from an optional, custom attribute.
See gh-31454
Closes gh-34575