This Java agent has been designed to instrument specific JDK calls for
reflective introspection and invocations. This is useful for testing
runtime hints in integration tests.
As of GraalVM 23, there is a new VM option that does this in a much more
efficient and precise fashion. Developers can use the
`-XX:MissingRegistrationReportingMode` with the "Warn" or "Exit" value.
The option will look for reachability metadata and emit logs in "Warn"
mode or immediately exit the application with in "Exit" mode.
This commit deprecates the `RuntimeHintsAgent` in favor of this new,
more reliable option.
See gh-33847
The `RuntimeHints` API mainly reflects what is needed to write GraalVM
reachability metadata. The latest GraalVM version simplified its
format. This commit applies relevant simplifications as parts of it are
not needed anymore.
The new metadata format implies methods, constructors and fields
introspection as soon as a reflection hint is registered for a type. As
a result, `ExecutableMode.INTROSPECT`, and all `MemberCategory` values
except `MemberCategory.INVOKE_*` are being deprecated.
They have no replacement, as registering a type hint is enough.
In practice, it is enough to replace this:
```
hints.reflection().registerType(MyType.class, MemberCategory.DECLARED_FIELDS);
```
By this:
```
hints.reflection().registerType(MyType.class);
```
As for `MemberCategory.PUBLIC_FIELDS` and `MemberCategory.DECLARED_FIELDS`,
values were replaced by `INVOKE_PUBLIC_FIELDS` and
`INVOKE_DECLARED_FIELDS` to make their original intent clearer and align
with the rest of the API. Note, if you were using those values for
reflection only, you can safely remove those hints in favor of a simple
type hint.
See gh-33847
As of GraalVM 23, a new and simplified reachability metadata format is
available. Metadata now consists of a single
"reachability-metadata.json" file that contains all the information
previously spread in multiple files. The new format does not include
some introspection flags, as they're now automatically included when a
hint is registered against a type.
Also, "typeReachable" has been renamed as "typeReached" to highlight the
fact that the event considered is the static initialization of the type,
not when the static analysis performed during native compilation is
reaching the type.
This new format ships with a JSON schema, which this commit is tested
against.
See gh-33847
Prior to this commit, the resource hints for AOT applications would
generate JSON metadata with `java.util.regex.Pattern`, like:
```
{
"resources": {
"includes": [
{
"pattern": "\\Qbanner.txt\\E"
}
]
}
}
```
This regexp feature, as well as "includes" and "excludes" are not supported
anymore with the new metadata format. This commit removes the pattern
format which is now replaced by a "glob" format.
"globs" should only contain "*" (zero or more characters in a path
segment) or "**" (zero or more path segments).
Some instances of resource hint registration should be migrated as a
result.
For example, "/files/*.ext" matched both "/files/a.ext" and
"/files/folder/b.txt" in the past. The new behavior matches only the
former, unless the "/files/**/*.ext" glob pattern is used.
This commit also removes the "excludes" support, which was not widely
used and very often could lead to subtle behavior.
Closes gh-31340
As a follow up to commit 0088b9c7f8, this commit introduces an
integration test which verifies that a spy created via @MockitoSpyBean
using the MockReset.AFTER strategy is not reset between the refresh of
the ApplicationContext and the first use of the spy within a @Test
method.
See gh-33941
See gh-33986
Prior to this commit, Spring would create directly
`SimpleMetadataReaderFactory` instances or would manually create
`CachingMetadataReaderFactory` which extend
`SimpleMetadataReaderFactory`. This would prevent usage of the new
`ClassFileMetadataReaderFactory` in our internal codebase.
This commit replaces manual instantiations with calls to
`MetadataReaderFactory` factory methods and makes
`CachingMetadataReaderFactory` delegate to another factory created with
the same factory methods.
This allows internal usage of `ClassFileMetadataReaderFactory`
internally.
Closes gh-33616
Prior to this commit, Spring Framework would allow two ways of getting
class metadata:
* `StandardClassMetadata`, using the Java reflection API
* `SimpleMetadataReaderFactory`, using ASM to read the class bytecode
This commit adds a new implementation for this feature, this time using
the new `ClassFile` API which is taken out of preview in Java 24.
See gh-33616
This commit adds a DSL Gradle extension for optionally enabling Java
preview features in a specific project module. The "--enable-preview"
JVM flag will be configured automatically for compile and test tasks
where this is applied:
```
springFramework {
enableJavaPreviewFeatures = true
}
```
See gh-33616
Before this commit, in Spring Framework 6.2, Kotlin value class
unboxing was done at CoroutinesUtils level, which is a good fit
for InvocableHandlerMethod use case, but not for other ones like
AopUtils.
This commit moves such unboxing to InvocableHandlerMethod in
order to keep the HTTP response body support while fixing other
regressions.
Closes gh-33943
The log message for a NoClassDefFoundError is now a DEBUG level message
handled like a TypeNotPresentException and similar to the following.
DEBUG: Skipping validation constraint hint inference for class
org.example.CustomConstraint due to a NoClassDefFoundError for
com.example.MissingType
See gh-33949
Prior to this commit, AOT processing for bean validation failed with a
NoClassDefFoundError for constraints with missing dependencies.
With this commit, the processing no longer fails, and a warning is
logged instead.
See gh-33940
Closes gh-33949
Co-authored-by: Sam Brannen <sam.brannen@broadcom.com>
Commit 6c2cba5d8a introduced a regression by inadvertently removing the
MockReset strategy comparison when resetting @MockitoBean and
@MockitoSpyBean mocks.
This commit reinstates the MockReset strategy check and introduces
tests for this feature.
Closes gh-33941
Prior to this commit, AOT processing for bean validation failed with a
StackOverflowError for constraints with fields having recursive generic
types.
With this commit, the algorithm tracks visited classes and aborts
preemptively when a cycle is detected.
Closes gh-33950
Co-authored-by: Sam Brannen <sam.brannen@broadcom.com>
This commit upgrades our Mock Servlet classes for Servlet 6.1 support:
* the read/write `ByteBuffer` variants for `ServletInputStream` and
`ServletOutputStream` were not added as the default implementation
matches well the testing use case.
* Implement the session accessor with a simple lambda. Our mocks do not
simulate the scheduling of request/response processing on different
threads.
* Ensure that the response content length can only be written before the
response is committed. Calling those methods after commit is a no-op,
per specification.
Closes gh-33749
As of Servlet 6.1, the `ServletInputStream` and `ServletOutputStream`
offer read and write variants based on `ByteBuffer` instead of byte
arrays. This can improve performance and avoid memory copy for I/O
calls.
This was already partially supported for some servers like Tomcat
through specific adapters. This commit moves this support to the
standard `ServletHttpHandlerAdapter` and makes it available for all
Servlet 6.1+ containers.
Closes gh-33748
Prior to this commit, `RestClient` would not use the full URI created by
the uri handler as a template request attribute.
This means that HTTP client observations would not contain the base URI
in recorded observations as the uri template keyvalue.
Closes gh-33928
This commit makes it clear that there are no visibility requirements
for @TestBean fields or factory methods as well as @MockitoBean or
@MockitoSpyBean fields.
Closes gh-33923