diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java index 3d79b860f8..5c7d164ffb 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/aot/CoreRuntimeHints.java @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 the original author or authors. + * Copyright 2022-2026 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,6 +98,13 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) { "java.util.concurrent.locks.ReentrantLock$FairSync", "java.util.concurrent.locks.ReentrantLock$NonfairSync", "java.util.concurrent.ConcurrentHashMap$Segment"); + Set> mongoDbPersistenceTypes = Set.of( + org.springframework.batch.core.repository.persistence.ExecutionContext.class, + org.springframework.batch.core.repository.persistence.ExitStatus.class, + org.springframework.batch.core.repository.persistence.JobExecution.class, + org.springframework.batch.core.repository.persistence.JobInstance.class, + org.springframework.batch.core.repository.persistence.JobParameter.class, + org.springframework.batch.core.repository.persistence.StepExecution.class); // resource hints hints.resources().registerPattern("org/springframework/batch/core/schema-h2.sql"); @@ -112,6 +119,10 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) { hints.resources().registerPattern("org/springframework/batch/core/schema-postgresql.sql"); hints.resources().registerPattern("org/springframework/batch/core/schema-sqlserver.sql"); hints.resources().registerPattern("org/springframework/batch/core/schema-sybase.sql"); + hints.resources().registerPattern("org/springframework/batch/core/schema-mongodb.jsonl"); + hints.resources().registerPattern("org/springframework/batch/core/schema-mongodb.js"); + hints.resources().registerPattern("org/springframework/batch/core/schema-drop-mongodb.jsonl"); + hints.resources().registerPattern("org/springframework/batch/core/schema-drop-mongodb.js"); // proxy hints hints.proxies() @@ -153,6 +164,7 @@ public void registerHints(RuntimeHints hints, ClassLoader classLoader) { jdkTypes.stream() .map(TypeReference::of) .forEach(type -> hints.reflection().registerType(type, MemberCategory.values())); + mongoDbPersistenceTypes.forEach(type -> hints.reflection().registerType(type, MemberCategory.values())); // reflection hints: methods Method jobContextGetJobParametersMethod = ReflectionUtils.findMethod(JobContext.class, "getJobParameters"); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/aot/CoreRuntimeHintsTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/aot/CoreRuntimeHintsTests.java new file mode 100644 index 0000000000..b6c1a5d03a --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/aot/CoreRuntimeHintsTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.batch.core.aot; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.batch.core.repository.persistence.ExecutionContext; +import org.springframework.batch.core.repository.persistence.ExitStatus; +import org.springframework.batch.core.repository.persistence.JobExecution; +import org.springframework.batch.core.repository.persistence.JobInstance; +import org.springframework.batch.core.repository.persistence.JobParameter; +import org.springframework.batch.core.repository.persistence.StepExecution; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CoreRuntimeHintsTests { + + private RuntimeHints runtimeHints; + + @BeforeEach + void setUp() { + this.runtimeHints = new RuntimeHints(); + new CoreRuntimeHints().registerHints(this.runtimeHints, getClass().getClassLoader()); + } + + @Test + void testMongoDbSchemaResourcesAreRegistered() { + Stream + .of("org/springframework/batch/core/schema-mongodb.jsonl", + "org/springframework/batch/core/schema-mongodb.js", + "org/springframework/batch/core/schema-drop-mongodb.jsonl", + "org/springframework/batch/core/schema-drop-mongodb.js") + .forEach(resource -> { + assertNotNull(getClass().getClassLoader().getResource(resource), + () -> "Resource not found: " + resource); + assertTrue(RuntimeHintsPredicates.resource().forResource(resource).test(this.runtimeHints), + () -> "Resource hint not found for " + resource); + }); + } + + @Test + void testMongoDbPersistenceTypesAreRegisteredForReflection() { + Stream + .of(JobInstance.class, ExecutionContext.class, ExitStatus.class, StepExecution.class, JobExecution.class, + JobParameter.class) + .forEach(type -> assertTrue(RuntimeHintsPredicates.reflection() + .onType(type) + .withMemberCategories(MemberCategory.values()) + .test(this.runtimeHints), () -> "Reflection hint not found for " + type.getName())); + } + +}