From e193ca1d24c97448fe0d903794004d89a75c5e47 Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Sun, 24 Jul 2022 08:07:14 +0100 Subject: [PATCH] Upgrade to Boot 3.x - For now port spring-native to framework config. - 3rd party configs should go somewhere else. - Fix changes from javax to jakarta. - Change java settings as we now require jdk 17. - Fixes #385 --- .github/workflows/ci-pr.yml | 8 +- .github/workflows/ci-publish.yml | 2 +- .github/workflows/ci.yml | 8 +- .github/workflows/e2e.yml | 4 +- .github/workflows/manual.yml | 11 +- .github/workflows/next-dev-version.yml | 2 +- .github/workflows/release-ga.yml | 2 +- .github/workflows/release-milestone.yml | 2 +- e2e/spring-shell-e2e-tests/src/utils.ts | 4 +- pom.xml | 11 +- .../shell/CoreResourcesRuntimeHints.java | 32 ++ .../shell/ParameterValidationException.java | 3 +- .../java/org/springframework/shell/Shell.java | 4 +- .../java/org/springframework/shell/Utils.java | 6 +- .../shell/command/CommandExecution.java | 2 +- .../invocation/InvocableShellMethod.java | 4 +- .../native-image/resource-config.json | 9 - .../resources/META-INF/spring/aot.factories | 2 + .../shell/docs/CommandContextSnippets.java | 2 +- spring-shell-samples/pom.xml | 95 ++-- .../shell/samples/SpringShellSample.java | 7 +- .../samples/config/SamplesRuntimeHints.java | 99 ++++ .../SpringShellNativeConfiguration.java | 332 ++++++------ .../shell/samples/standard/Commands.java | 2 +- .../META-INF/native-image/jni-config.json | 512 ------------------ .../main/resources/META-INF/spring.factories | 2 - .../resources/META-INF/spring/aot.factories | 2 + .../config/SamplesRuntimeHintsTests.java | 45 ++ .../StandardCommandsModelsRuntimeHints.java | 49 ++ ...StandardCommandsResourcesRuntimeHints.java | 34 ++ .../META-INF/native-image/reflect-config.json | 26 - .../native-image/resource-config.json | 12 - .../resources/META-INF/spring/aot.factories | 3 + .../shell/standard/commands/HelpTests.java | 2 +- .../shell/standard/ShellMethod.java | 2 + .../StandardMethodTargetRegistrar.java | 1 + .../StandardResourcesRuntimeHints.java | 32 ++ .../StandardCompletionModelsRuntimeHints.java | 50 ++ .../META-INF/native-image/reflect-config.json | 10 - .../native-image/resource-config.json | 9 - .../resources/META-INF/spring/aot.factories | 3 + 41 files changed, 589 insertions(+), 858 deletions(-) create mode 100644 spring-shell-core/src/main/java/org/springframework/shell/CoreResourcesRuntimeHints.java delete mode 100644 spring-shell-core/src/main/resources/META-INF/native-image/resource-config.json create mode 100644 spring-shell-core/src/main/resources/META-INF/spring/aot.factories create mode 100644 spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SamplesRuntimeHints.java delete mode 100644 spring-shell-samples/src/main/resources/META-INF/native-image/jni-config.json delete mode 100644 spring-shell-samples/src/main/resources/META-INF/spring.factories create mode 100644 spring-shell-samples/src/main/resources/META-INF/spring/aot.factories create mode 100644 spring-shell-samples/src/test/java/org/springframework/shell/samples/config/SamplesRuntimeHintsTests.java create mode 100644 spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsModelsRuntimeHints.java create mode 100644 spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsResourcesRuntimeHints.java delete mode 100644 spring-shell-standard-commands/src/main/resources/META-INF/native-image/reflect-config.json delete mode 100644 spring-shell-standard-commands/src/main/resources/META-INF/native-image/resource-config.json create mode 100644 spring-shell-standard-commands/src/main/resources/META-INF/spring/aot.factories create mode 100644 spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardResourcesRuntimeHints.java create mode 100644 spring-shell-standard/src/main/java/org/springframework/shell/standard/completion/StandardCompletionModelsRuntimeHints.java delete mode 100644 spring-shell-standard/src/main/resources/META-INF/native-image/reflect-config.json delete mode 100644 spring-shell-standard/src/main/resources/META-INF/native-image/resource-config.json create mode 100644 spring-shell-standard/src/main/resources/META-INF/spring/aot.factories diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index b7439988..6b93a941 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -11,15 +11,9 @@ jobs: fail-fast: false matrix: include: - - nickname: linux jdk8 - java: 8 - disable-samples: true - - nickname: linux jdk11 - java: 11 - disable-samples: false - nickname: linux jdk17 java: 17 - disable-samples: false + disable-samples: true name: CI PR ${{ matrix.nickname }} steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/ci-publish.yml b/.github/workflows/ci-publish.yml index 8433a273..ef963144 100644 --- a/.github/workflows/ci-publish.yml +++ b/.github/workflows/ci-publish.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/setup-java@v2 with: distribution: adopt - java-version: 8 + java-version: 17 - uses: jfrog/setup-jfrog-cli@v2 with: version: 2.13.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61dab0a8..f39895c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,15 +13,9 @@ jobs: fail-fast: false matrix: include: - - nickname: linux jdk8 - java: 8 - disable-samples: true - - nickname: linux jdk11 - java: 11 - disable-samples: false - nickname: linux jdk17 java: 17 - disable-samples: false + disable-samples: true name: CI Build ${{ matrix.nickname }} steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 55805ec1..69992280 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -27,12 +27,12 @@ jobs: - uses: actions/setup-java@v2 with: distribution: adopt - java-version: 11 + java-version: 17 cache: maven - uses: graalvm/setup-graalvm@v1 with: version: ${{ matrix.graal }} - java-version: 11 + java-version: 17 components: native-image set-java-home: false github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 1074b5c2..4c3497a1 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -22,20 +22,15 @@ jobs: name: Build ${{ matrix.nickname }} steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 - with: - distribution: adopt - java-version: 11 - cache: maven - uses: graalvm/setup-graalvm@v1 with: version: ${{ matrix.graal }} - java-version: 11 + java-version: 17 components: native-image - set-java-home: false + set-java-home: true github-token: ${{ secrets.GITHUB_TOKEN }} - run: | - ./mvnw clean package -Pnative + ./mvnw clean package -Pnativex - uses: actions/upload-artifact@v2 with: name: spring-shell-samples-${{ matrix.nickname }} diff --git a/.github/workflows/next-dev-version.yml b/.github/workflows/next-dev-version.yml index f3fbd2da..b6f9e106 100644 --- a/.github/workflows/next-dev-version.yml +++ b/.github/workflows/next-dev-version.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - uses: jvalkeal/setup-maven@v1 with: maven-version: 3.8.4 diff --git a/.github/workflows/release-ga.yml b/.github/workflows/release-ga.yml index 634720b2..303e92e4 100644 --- a/.github/workflows/release-ga.yml +++ b/.github/workflows/release-ga.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - uses: jvalkeal/setup-maven@v1 with: maven-version: 3.8.4 diff --git a/.github/workflows/release-milestone.yml b/.github/workflows/release-milestone.yml index 759e6bd3..1f381be5 100644 --- a/.github/workflows/release-milestone.yml +++ b/.github/workflows/release-milestone.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 17 - uses: jvalkeal/setup-maven@v1 with: maven-version: 3.8.4 diff --git a/e2e/spring-shell-e2e-tests/src/utils.ts b/e2e/spring-shell-e2e-tests/src/utils.ts index 4f0a8e82..76885aef 100644 --- a/e2e/spring-shell-e2e-tests/src/utils.ts +++ b/e2e/spring-shell-e2e-tests/src/utils.ts @@ -7,8 +7,8 @@ export const cliPathRelative = isWindows ? '..\\..\\spring-shell-samples\\target\\spring-shell-samples.exe' : '../../spring-shell-samples/target/spring-shell-samples'; export const jarPathRelative = isWindows - ? '..\\..\\spring-shell-samples\\target\\spring-shell-samples-2.1.0-SNAPSHOT-exec.jar' - : '../../spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT-exec.jar'; + ? '..\\..\\spring-shell-samples\\target\\spring-shell-samples-3.0.0-SNAPSHOT-exec.jar' + : '../../spring-shell-samples/target/spring-shell-samples-3.0.0-SNAPSHOT-exec.jar'; export const cliPath = path.resolve(cliPathRelative); export const jarPath = path.resolve(jarPathRelative); export const nativeDesc = 'native'; diff --git a/pom.xml b/pom.xml index 53ed52a3..bf3ecf37 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.2 + 3.0.0-SNAPSHOT @@ -22,6 +22,7 @@ + 17 3.21.0 4.3.1 1.2 @@ -107,14 +108,6 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins diff --git a/spring-shell-core/src/main/java/org/springframework/shell/CoreResourcesRuntimeHints.java b/spring-shell-core/src/main/java/org/springframework/shell/CoreResourcesRuntimeHints.java new file mode 100644 index 00000000..b2107d9b --- /dev/null +++ b/spring-shell-core/src/main/java/org/springframework/shell/CoreResourcesRuntimeHints.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 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.shell; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; + +/** + * {@link RuntimeHintsRegistrar} for Shell Core resources. + * + * @author Janne Valkealahti + */ +class CoreResourcesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerPattern("org/springframework/shell/component/*.stg"); + } +} diff --git a/spring-shell-core/src/main/java/org/springframework/shell/ParameterValidationException.java b/spring-shell-core/src/main/java/org/springframework/shell/ParameterValidationException.java index 46c6a07f..684aefee 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/ParameterValidationException.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/ParameterValidationException.java @@ -15,9 +15,10 @@ */ package org.springframework.shell; -import javax.validation.ConstraintViolation; import java.util.Set; +import jakarta.validation.ConstraintViolation; + /** * Thrown when one or more parameters fail bean validation constraints. * diff --git a/spring-shell-core/src/main/java/org/springframework/shell/Shell.java b/spring-shell-core/src/main/java/org/springframework/shell/Shell.java index 22769824..67842e16 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/Shell.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/Shell.java @@ -24,8 +24,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.jline.terminal.Terminal; import org.jline.utils.Signals; diff --git a/spring-shell-core/src/main/java/org/springframework/shell/Utils.java b/spring-shell-core/src/main/java/org/springframework/shell/Utils.java index dacc8bdb..19498895 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/Utils.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/Utils.java @@ -28,9 +28,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; diff --git a/spring-shell-core/src/main/java/org/springframework/shell/command/CommandExecution.java b/spring-shell-core/src/main/java/org/springframework/shell/command/CommandExecution.java index 3c742e87..19f989e9 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/command/CommandExecution.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/command/CommandExecution.java @@ -19,7 +19,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.validation.Validator; +import jakarta.validation.Validator; import org.jline.terminal.Terminal; diff --git a/spring-shell-core/src/main/java/org/springframework/shell/command/invocation/InvocableShellMethod.java b/spring-shell-core/src/main/java/org/springframework/shell/command/invocation/InvocableShellMethod.java index fad1096e..551563c3 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/command/invocation/InvocableShellMethod.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/command/invocation/InvocableShellMethod.java @@ -24,8 +24,8 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; -import javax.validation.ConstraintViolation; -import javax.validation.Validator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/spring-shell-core/src/main/resources/META-INF/native-image/resource-config.json b/spring-shell-core/src/main/resources/META-INF/native-image/resource-config.json deleted file mode 100644 index abeb6fdd..00000000 --- a/spring-shell-core/src/main/resources/META-INF/native-image/resource-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "org/springframework/shell/component/.*.stg" - } - ] - } -} diff --git a/spring-shell-core/src/main/resources/META-INF/spring/aot.factories b/spring-shell-core/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 00000000..3b5d200b --- /dev/null +++ b/spring-shell-core/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.shell.CoreResourcesRuntimeHints diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandContextSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandContextSnippets.java index 3a7366e9..4589b5e6 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandContextSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/CommandContextSnippets.java @@ -15,7 +15,7 @@ */ package org.springframework.shell.docs; -import javax.validation.constraints.Null; +import jakarta.validation.constraints.Null; import org.springframework.shell.command.CommandContext; diff --git a/spring-shell-samples/pom.xml b/spring-shell-samples/pom.xml index 417d5a38..ff766c60 100644 --- a/spring-shell-samples/pom.xml +++ b/spring-shell-samples/pom.xml @@ -14,10 +14,6 @@ Examples of using Spring Shell 2 - - 0.12.0 - - @@ -44,10 +40,9 @@ spring-shell-starter-jna - org.springframework.experimental - spring-aot - ${spring-native.version} - true + org.springframework.boot + spring-boot-starter-test + test @@ -64,14 +59,9 @@ - native + nativex - - org.springframework.experimental - spring-native - ${spring-native.version} - org.junit.platform @@ -81,52 +71,37 @@ - - org.springframework.experimental - spring-aot-maven-plugin - ${spring-native.version} - - - generate - - generate - - - - - - org.graalvm.buildtools - native-maven-plugin - 0.9.9 - true - - - build-native - - build - - package - - - test-native - - test - - test - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - exec - - + + + org.springframework.boot + spring-boot-maven-plugin + + + aot-generate + + aot-generate + + + + repackage + + exec + + + + + + org.graalvm.buildtools + native-maven-plugin + + + build-native + + build + + + + diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/SpringShellSample.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/SpringShellSample.java index 905eaad6..a5de865d 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/SpringShellSample.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/SpringShellSample.java @@ -19,6 +19,7 @@ import org.jline.utils.AttributedString; import org.jline.utils.AttributedStyle; import org.springframework.boot.SpringApplication; +import org.springframework.boot.Banner.Mode; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.shell.jline.PromptProvider; @@ -35,7 +36,11 @@ import org.springframework.shell.jline.PromptProvider; public class SpringShellSample { public static void main(String[] args) throws Exception { - SpringApplication.run(SpringShellSample.class, args); + SpringApplication application = new SpringApplication(SpringShellSample.class); + application.setBannerMode(Mode.OFF); + application.run(args); + // TODO: follow up with boot why spring.main.banner-mode=off doesn't work + // SpringApplication.run(SpringShellSample.class, args); } @Bean diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SamplesRuntimeHints.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SamplesRuntimeHints.java new file mode 100644 index 00000000..901a09a4 --- /dev/null +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SamplesRuntimeHints.java @@ -0,0 +1,99 @@ +/* + * Copyright 2022 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.shell.samples.config; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.ProxyHints; +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.ResourceHints; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.util.ClassUtils; + +public class SamplesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + ResourceHints resource = hints.resources(); + ProxyHints proxy = hints.proxies(); + ReflectionHints reflection = hints.reflection(); + // should go graalvm-reachability-metadata + registerResources(resource); + // should go graalvm-reachability-metadata + registerProxies(proxy, "com.sun.jna.Library", "com.sun.jna.Callback", + "org.jline.terminal.impl.jna.win.Kernel32", "org.jline.terminal.impl.jna.linux.CLibrary"); + // should go graalvm-reachability-metadata + registerForMostReflection(reflection, "com.sun.jna.CallbackReference", "com.sun.jna.Native", + "com.sun.jna.NativeLong", "com.sun.jna.Pointer", "com.sun.jna.Structure", + "com.sun.jna.ptr.IntByReference", "com.sun.jna.ptr.PointerByReference", "com.sun.jna.Klass", + "com.sun.jna.Structure$FFIType", "com.sun.jna.Structure$FFIType$size_t"); + // should go graalvm-reachability-metadata + registerForMostReflection(reflection, "org.jline.terminal.impl.jna.win.Kernel32$CHAR_INFO", + "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_CURSOR_INFO", + "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_SCREEN_BUFFER_INFO", + "org.jline.terminal.impl.jna.win.Kernel32$COORD", + "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD$EventUnion", + "org.jline.terminal.impl.jna.win.Kernel32$KEY_EVENT_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$MOUSE_EVENT_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$WINDOW_BUFFER_SIZE_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$MENU_EVENT_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD", + "org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT", + "org.jline.terminal.impl.jna.win.Kernel32$UnionChar"); + // from spring-native sb-3.0.x branch + registerHibernateValidatorHints(hints, classLoader); + } + + private void registerHibernateValidatorHints(RuntimeHints hints, ClassLoader classLoader) { + if (!ClassUtils.isPresent("org.hibernate.validator.HibernateValidator", classLoader)) { + return; + } + hints.reflection().registerType(TypeReference.of("org.hibernate.validator.internal.util.logging.Log_$logger"), + hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)); + hints.reflection().registerType( + TypeReference.of("org.hibernate.validator.internal.util.logging.Messages_$bundle"), + hint -> hint.withField("INSTANCE", fieldHint -> { + })); + } + + private void registerResources(ResourceHints resource) { + resource.registerPattern("com/sun/jna/win32-x86-64/jnidispatch.dll"); + } + + private void registerProxies(ProxyHints proxy, String... classNames) { + typeReferences(classNames) + .forEach(tr -> proxy.registerJdkProxy(jdkProxyHint -> jdkProxyHint.proxiedInterfaces(tr))); + } + + private void registerForMostReflection(ReflectionHints reflection, String... classNames) { + reflection.registerTypes(typeReferences(classNames), + hint -> { + hint.withMembers(MemberCategory.DECLARED_CLASSES, MemberCategory.DECLARED_FIELDS, + MemberCategory.PUBLIC_CLASSES, MemberCategory.PUBLIC_FIELDS, + MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS); + }); + } + + private Iterable typeReferences(String... classNames) { + return Stream.of(classNames).map(TypeReference::of).collect(Collectors.toList()); + } + +} diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SpringShellNativeConfiguration.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SpringShellNativeConfiguration.java index ebe3dbce..f4ae013a 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SpringShellNativeConfiguration.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/config/SpringShellNativeConfiguration.java @@ -15,172 +15,172 @@ */ package org.springframework.shell.samples.config; -import com.sun.jna.CallbackReference; -import com.sun.jna.Native; -import com.sun.jna.NativeLong; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.ptr.PointerByReference; +// import com.sun.jna.CallbackReference; +// import com.sun.jna.Native; +// import com.sun.jna.NativeLong; +// import com.sun.jna.Pointer; +// import com.sun.jna.Structure; +// import com.sun.jna.ptr.IntByReference; +// import com.sun.jna.ptr.PointerByReference; -import org.springframework.nativex.hint.FieldHint; -import org.springframework.nativex.hint.JdkProxyHint; -import org.springframework.nativex.hint.MethodHint; -import org.springframework.nativex.hint.NativeHint; -import org.springframework.nativex.hint.ResourceHint; -import org.springframework.nativex.hint.TypeAccess; -import org.springframework.nativex.hint.TypeHint; -import org.springframework.nativex.type.NativeConfiguration; +// import org.springframework.nativex.hint.FieldHint; +// import org.springframework.nativex.hint.JdkProxyHint; +// import org.springframework.nativex.hint.MethodHint; +// import org.springframework.nativex.hint.NativeHint; +// import org.springframework.nativex.hint.ResourceHint; +// import org.springframework.nativex.hint.TypeAccess; +// import org.springframework.nativex.hint.TypeHint; +// import org.springframework.nativex.type.NativeConfiguration; -@NativeHint( - resources = { - @ResourceHint( - patterns = { - "com/sun/jna/win32-x86-64/jnidispatch.dll" - } - ), - }, - types = { - @TypeHint( - types = { - CallbackReference.class, Native.class, NativeLong.class, PointerByReference.class, IntByReference.class - }, - typeNames = { "com.sun.jna.Klass" }, - access = { - TypeAccess.PUBLIC_CLASSES, TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_FIELDS, - TypeAccess.PUBLIC_METHODS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - types = Structure.class, - fields = { - @FieldHint( name = "memory", allowWrite = true), - @FieldHint( name = "typeInfo") - }, - methods = { - @MethodHint( name = "newInstance", parameterTypes = { Class.class, Pointer.class }), - @MethodHint( name = "newInstance", parameterTypes = { Class.class, long.class }), - @MethodHint( name = "newInstance", parameterTypes = { Class.class }) - }, - access = { - TypeAccess.PUBLIC_CLASSES, TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_FIELDS, - TypeAccess.PUBLIC_METHODS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "com.sun.jna.Structure$FFIType", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "com.sun.jna.Structure$FFIType$size_t", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CHAR_INFO", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_CURSOR_INFO", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_SCREEN_BUFFER_INFO", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$COORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD$EventUnion", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$KEY_EVENT_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$MOUSE_EVENT_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$WINDOW_BUFFER_SIZE_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$MENU_EVENT_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ), - @TypeHint( - typeNames = "org.jline.terminal.impl.jna.win.Kernel32$UnionChar", - access = { - TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, - TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS - } - ) - }, - jdkProxies = { - @JdkProxyHint( typeNames = { "com.sun.jna.Library" }), - @JdkProxyHint( typeNames = { "com.sun.jna.Callback" }), - @JdkProxyHint( typeNames = { "org.jline.terminal.impl.jna.win.Kernel32" }), - @JdkProxyHint( typeNames = { "org.jline.terminal.impl.jna.linux.CLibrary" }) - } -) -public class SpringShellNativeConfiguration implements NativeConfiguration { +// @NativeHint( +// resources = { +// @ResourceHint( +// patterns = { +// "com/sun/jna/win32-x86-64/jnidispatch.dll" +// } +// ), +// }, +// types = { +// @TypeHint( +// types = { +// CallbackReference.class, Native.class, NativeLong.class, PointerByReference.class, IntByReference.class +// }, +// typeNames = { "com.sun.jna.Klass" }, +// access = { +// TypeAccess.PUBLIC_CLASSES, TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_FIELDS, +// TypeAccess.PUBLIC_METHODS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// types = Structure.class, +// fields = { +// @FieldHint( name = "memory", allowWrite = true), +// @FieldHint( name = "typeInfo") +// }, +// methods = { +// @MethodHint( name = "newInstance", parameterTypes = { Class.class, Pointer.class }), +// @MethodHint( name = "newInstance", parameterTypes = { Class.class, long.class }), +// @MethodHint( name = "newInstance", parameterTypes = { Class.class }) +// }, +// access = { +// TypeAccess.PUBLIC_CLASSES, TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_FIELDS, +// TypeAccess.PUBLIC_METHODS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "com.sun.jna.Structure$FFIType", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "com.sun.jna.Structure$FFIType$size_t", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CHAR_INFO", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_CURSOR_INFO", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_SCREEN_BUFFER_INFO", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$COORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD$EventUnion", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$KEY_EVENT_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$MOUSE_EVENT_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$WINDOW_BUFFER_SIZE_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$MENU_EVENT_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ), +// @TypeHint( +// typeNames = "org.jline.terminal.impl.jna.win.Kernel32$UnionChar", +// access = { +// TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.DECLARED_CLASSES, TypeAccess.DECLARED_CONSTRUCTORS, +// TypeAccess.DECLARED_FIELDS, TypeAccess.DECLARED_METHODS +// } +// ) +// }, +// jdkProxies = { +// @JdkProxyHint( typeNames = { "com.sun.jna.Library" }), +// @JdkProxyHint( typeNames = { "com.sun.jna.Callback" }), +// @JdkProxyHint( typeNames = { "org.jline.terminal.impl.jna.win.Kernel32" }), +// @JdkProxyHint( typeNames = { "org.jline.terminal.impl.jna.linux.CLibrary" }) +// } +// ) +public class SpringShellNativeConfiguration /*implements NativeConfiguration*/ { } diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/Commands.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/Commands.java index 6985e545..c5398b4a 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/Commands.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/Commands.java @@ -21,7 +21,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Size; import org.springframework.shell.standard.ShellComponent; import org.springframework.shell.standard.ShellMethod; diff --git a/spring-shell-samples/src/main/resources/META-INF/native-image/jni-config.json b/spring-shell-samples/src/main/resources/META-INF/native-image/jni-config.json deleted file mode 100644 index 6e16c854..00000000 --- a/spring-shell-samples/src/main/resources/META-INF/native-image/jni-config.json +++ /dev/null @@ -1,512 +0,0 @@ -[ - { - "name" : "com.sun.jna.Native", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.lang.Class", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.lang.reflect.Method", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.lang.String", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.Buffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.ByteBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.CharBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.ShortBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.IntBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.LongBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.FloatBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.nio.DoubleBuffer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "java.lang.Void", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Boolean", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Byte", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Character", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Short", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Integer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Long", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Float", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "java.lang.Double", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true }, - { "name" : "TYPE" } - ] - }, - { - "name" : "com.sun.jna.Pointer", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "peer", "allowWrite" : true } - ] - }, - { - "name" : "com.sun.jna.Structure$ByValue", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.WString", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.NativeMapped", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.IntegerType", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.PointerType", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.JNIEnv", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.Native$ffi_callback", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.FromNativeConverter", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.Structure", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "memory", "allowWrite" : true }, - { "name" : "typeInfo", "allowWrite" : true } - ], - "methods" : [ - { "name" : "newInstance", "parameterTypes" : ["java.lang.Class","com.sun.jna.Pointer"] }, - { "name" : "newInstance", "parameterTypes" : ["java.lang.Class", "long"] }, - { "name" : "newInstance", "parameterTypes" : ["java.lang.Class"] }, - { "name" : "getTypeInfo", "parameterTypes": ["java.lang.Object"] } - ] - }, - { - "name" : "com.sun.jna.Callback", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.CallbackReference$AttachOptions", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.CallbackReference", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.IntegerType", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "value", "allowWrite" : true } - ] - }, - { - "name" : "com.sun.jna.PointerType", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "pointer", "allowWrite" : true } - ] - }, - { - "name" : "com.sun.jna.Structure$FFIType", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.Structure$FFIType$size_t", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.Structure$FFIType$FFITypes", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "ffi_type_void", "allowWrite" : true }, - { "name" : "ffi_type_float", "allowWrite" : true }, - { "name" : "ffi_type_double", "allowWrite" : true }, - { "name" : "ffi_type_longdouble", "allowWrite" : true }, - { "name" : "ffi_type_uint8", "allowWrite" : true }, - { "name" : "ffi_type_sint8", "allowWrite" : true }, - { "name" : "ffi_type_uint16", "allowWrite" : true }, - { "name" : "ffi_type_sint16", "allowWrite" : true }, - { "name" : "ffi_type_uint32", "allowWrite" : true }, - { "name" : "ffi_type_sint32", "allowWrite" : true }, - { "name" : "ffi_type_uint64", "allowWrite" : true }, - { "name" : "ffi_type_sint64", "allowWrite" : true }, - { "name" : "ffi_type_pointer", "allowWrite" : true } - ] - }, - { - "name" : "com.sun.jna.NativeLong", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "com.sun.jna.ptr.PointerByReference", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$CHAR_INFO", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "uChar", "allowWrite" : true }, - { "name" : "Attributes", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_CURSOR_INFO", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "dwSize", "allowWrite" : true }, - { "name" : "bVisible", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$CONSOLE_SCREEN_BUFFER_INFO", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "dwSize", "allowWrite" : true }, - { "name" : "dwCursorPosition", "allowWrite" : true }, - { "name" : "wAttributes", "allowWrite" : true }, - { "name" : "srWindow", "allowWrite" : true }, - { "name" : "dwMaximumWindowSize", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$COORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "X", "allowWrite" : true }, - { "name" : "Y", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "EventType", "allowWrite" : true }, - { "name" : "Event", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$INPUT_RECORD$EventUnion", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "KeyEvent", "allowWrite" : true }, - { "name" : "MouseEvent", "allowWrite" : true }, - { "name" : "WindowBufferSizeEvent", "allowWrite" : true }, - { "name" : "MenuEvent", "allowWrite" : true }, - { "name" : "FocusEvent", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$KEY_EVENT_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "bKeyDown", "allowWrite" : true }, - { "name" : "wRepeatCount", "allowWrite" : true }, - { "name" : "wVirtualKeyCode", "allowWrite" : true }, - { "name" : "wVirtualScanCode", "allowWrite" : true }, - { "name" : "uChar", "allowWrite" : true }, - { "name" : "dwControlKeyState", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$MOUSE_EVENT_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "dwMousePosition", "allowWrite" : true }, - { "name" : "dwButtonState", "allowWrite" : true }, - { "name" : "dwControlKeyState", "allowWrite" : true }, - { "name" : "dwEventFlags", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$WINDOW_BUFFER_SIZE_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "dwSize", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$MENU_EVENT_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "dwCommandId", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$FOCUS_EVENT_RECORD", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "bSetFocus", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$SMALL_RECT", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "Left", "allowWrite" : true }, - { "name" : "Top", "allowWrite" : true }, - { "name" : "Right", "allowWrite" : true }, - { "name" : "Bottom", "allowWrite" : true } - ] - }, - { - "name" : "org.jline.terminal.impl.jna.win.Kernel32$UnionChar", - "allDeclaredConstructors" : true, - "allPublicConstructors" : true, - "allDeclaredMethods" : true, - "allPublicMethods" : true, - "fields" : [ - { "name" : "UnicodeChar", "allowWrite" : true }, - { "name" : "AsciiChar", "allowWrite" : true } - ] - } -] diff --git a/spring-shell-samples/src/main/resources/META-INF/spring.factories b/spring-shell-samples/src/main/resources/META-INF/spring.factories deleted file mode 100644 index dfa413b7..00000000 --- a/spring-shell-samples/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.nativex.type.NativeConfiguration=\ -org.springframework.shell.samples.config.SpringShellNativeConfiguration diff --git a/spring-shell-samples/src/main/resources/META-INF/spring/aot.factories b/spring-shell-samples/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 00000000..9044e9ad --- /dev/null +++ b/spring-shell-samples/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.shell.samples.config.SamplesRuntimeHints diff --git a/spring-shell-samples/src/test/java/org/springframework/shell/samples/config/SamplesRuntimeHintsTests.java b/spring-shell-samples/src/test/java/org/springframework/shell/samples/config/SamplesRuntimeHintsTests.java new file mode 100644 index 00000000..7cfb4e80 --- /dev/null +++ b/spring-shell-samples/src/test/java/org/springframework/shell/samples/config/SamplesRuntimeHintsTests.java @@ -0,0 +1,45 @@ +package org.springframework.shell.samples.config; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeHint; +import org.springframework.aot.hint.TypeReference; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SamplesRuntimeHintsTests { + + @Test + void test() { + String[] classNames = Arrays.asList("com.sun.jna.CallbackReference", "com.sun.jna.Native", + "com.sun.jna.NativeLong", "com.sun.jna.Pointer", "com.sun.jna.Structure", + "com.sun.jna.ptr.IntByReference", "com.sun.jna.ptr.PointerByReference", "com.sun.jna.Klass", + "com.sun.jna.Structure$FFIType", "com.sun.jna.Structure$FFIType$size_t").toArray(new String[0]); + ReflectionHints hints = registerHints(); + typeReferences(classNames).forEach(typeReference -> { + TypeHint typeHint = hints.getTypeHint(typeReference); + assertThat(typeHint).withFailMessage(() -> "No hints found for typeReference " + typeReference).isNotNull(); + Set memberCategories = typeHint.getMemberCategories(); + assertThat(memberCategories).containsExactlyInAnyOrder(MemberCategory.DECLARED_CLASSES, + MemberCategory.DECLARED_FIELDS, MemberCategory.PUBLIC_CLASSES, MemberCategory.PUBLIC_FIELDS, + MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_PUBLIC_METHODS); + }); + } + + private ReflectionHints registerHints() { + RuntimeHints hints = new RuntimeHints(); + new SamplesRuntimeHints().registerHints(hints, getClass().getClassLoader()); + return hints.reflection(); + } + + private Stream typeReferences(String... classNames) { + return Stream.of(classNames).map(TypeReference::of); + } +} diff --git a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsModelsRuntimeHints.java b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsModelsRuntimeHints.java new file mode 100644 index 00000000..20674106 --- /dev/null +++ b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsModelsRuntimeHints.java @@ -0,0 +1,49 @@ +/* + * Copyright 2022 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.shell.standard.commands; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; + +/** + * {@link RuntimeHintsRegistrar} for Shell Standard Commands temlate model classes. + * + * @author Janne Valkealahti + */ +class StandardCommandsModelsRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + ReflectionHints reflection = hints.reflection(); + registerForDeclaredMethodsInvocation(reflection, CommandAvailabilityInfoModel.class, CommandInfoModel.class, + CommandParameterInfoModel.class, GroupCommandInfoModel.class, GroupsInfoModel.class); + } + + private void registerForDeclaredMethodsInvocation(ReflectionHints reflection, Class... classes) { + reflection.registerTypes(typeReferences(classes), + hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS)); + } + + private Iterable typeReferences(Class... classes) { + return Stream.of(classes).map(TypeReference::of).collect(Collectors.toList()); + } +} diff --git a/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsResourcesRuntimeHints.java b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsResourcesRuntimeHints.java new file mode 100644 index 00000000..8743f786 --- /dev/null +++ b/spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/StandardCommandsResourcesRuntimeHints.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 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.shell.standard.commands; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; + +/** + * {@link RuntimeHintsRegistrar} for Shell Standard Commands resources. + * + * @author Janne Valkealahti + */ +class StandardCommandsResourcesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources() + .registerPattern("template/*.st") + .registerPattern("template/*.stg"); + } +} diff --git a/spring-shell-standard-commands/src/main/resources/META-INF/native-image/reflect-config.json b/spring-shell-standard-commands/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index deebdd28..00000000 --- a/spring-shell-standard-commands/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "name": "org.springframework.shell.standard.commands.CommandInfoModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.commands.CommandParameterInfoModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.commands.GroupCommandInfoModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.commands.GroupsInfoModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.commands.CommandParameterInfoModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.commands.CommandAvailabilityInfoModel", - "allDeclaredMethods": true - } -] diff --git a/spring-shell-standard-commands/src/main/resources/META-INF/native-image/resource-config.json b/spring-shell-standard-commands/src/main/resources/META-INF/native-image/resource-config.json deleted file mode 100644 index 79195069..00000000 --- a/spring-shell-standard-commands/src/main/resources/META-INF/native-image/resource-config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "template/.*.st" - }, - { - "pattern": "template/.*.stg" - } - ] - } -} diff --git a/spring-shell-standard-commands/src/main/resources/META-INF/spring/aot.factories b/spring-shell-standard-commands/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 00000000..fbd5df3d --- /dev/null +++ b/spring-shell-standard-commands/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,3 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.shell.standard.commands.StandardCommandsResourcesRuntimeHints,\ +org.springframework.shell.standard.commands.StandardCommandsModelsRuntimeHints diff --git a/spring-shell-standard-commands/src/test/java/org/springframework/shell/standard/commands/HelpTests.java b/spring-shell-standard-commands/src/test/java/org/springframework/shell/standard/commands/HelpTests.java index 37018ab5..11d70642 100644 --- a/spring-shell-standard-commands/src/test/java/org/springframework/shell/standard/commands/HelpTests.java +++ b/spring-shell-standard-commands/src/test/java/org/springframework/shell/standard/commands/HelpTests.java @@ -23,7 +23,7 @@ import java.util.Collection; import java.util.Locale; import java.util.Optional; -import javax.validation.constraints.Max; +import jakarta.validation.constraints.Max; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; diff --git a/spring-shell-standard/src/main/java/org/springframework/shell/standard/ShellMethod.java b/spring-shell-standard/src/main/java/org/springframework/shell/standard/ShellMethod.java index 8e6b9563..ee1db610 100644 --- a/spring-shell-standard/src/main/java/org/springframework/shell/standard/ShellMethod.java +++ b/spring-shell-standard/src/main/java/org/springframework/shell/standard/ShellMethod.java @@ -21,6 +21,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.shell.context.InteractionMode; /** @@ -32,6 +33,7 @@ import org.springframework.shell.context.InteractionMode; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented +@Reflective public @interface ShellMethod { /** diff --git a/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java index 9db814c2..85a9e79f 100644 --- a/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java +++ b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java @@ -75,6 +75,7 @@ public class StandardMethodTargetRegistrar implements MethodTargetRegistrar, App @Override public void register(CommandCatalog registry) { Map commandBeans = applicationContext.getBeansWithAnnotation(ShellComponent.class); + log.debug("Found commandBeans to register {}", commandBeans); for (Object bean : commandBeans.values()) { Class clazz = bean.getClass(); ReflectionUtils.doWithMethods(clazz, method -> { diff --git a/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardResourcesRuntimeHints.java b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardResourcesRuntimeHints.java new file mode 100644 index 00000000..2d1a981e --- /dev/null +++ b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardResourcesRuntimeHints.java @@ -0,0 +1,32 @@ +/* + * Copyright 2022 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.shell.standard; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; + +/** + * {@link RuntimeHintsRegistrar} for Shell Standard resources. + * + * @author Janne Valkealahti + */ +class StandardResourcesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerPattern("org/springframework/shell/component/*.stg"); + } +} diff --git a/spring-shell-standard/src/main/java/org/springframework/shell/standard/completion/StandardCompletionModelsRuntimeHints.java b/spring-shell-standard/src/main/java/org/springframework/shell/standard/completion/StandardCompletionModelsRuntimeHints.java new file mode 100644 index 00000000..28bc9238 --- /dev/null +++ b/spring-shell-standard/src/main/java/org/springframework/shell/standard/completion/StandardCompletionModelsRuntimeHints.java @@ -0,0 +1,50 @@ +/* + * Copyright 2022 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.shell.standard.completion; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; + +/** + * {@link RuntimeHintsRegistrar} for Shell Standard completion temlate model classes. + * + * @author Janne Valkealahti + */ +class StandardCompletionModelsRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + ReflectionHints reflection = hints.reflection(); + registerForDeclaredMethodsInvocation(reflection, AbstractCompletions.DefaultCommandModel.class, + AbstractCompletions.DefaultCommandModelCommand.class, + AbstractCompletions.DefaultCommandModelOption.class); + } + + private void registerForDeclaredMethodsInvocation(ReflectionHints reflection, Class... classes) { + reflection.registerTypes(typeReferences(classes), + hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS)); + } + + private Iterable typeReferences(Class... classes) { + return Stream.of(classes).map(TypeReference::of).collect(Collectors.toList()); + } +} diff --git a/spring-shell-standard/src/main/resources/META-INF/native-image/reflect-config.json b/spring-shell-standard/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index c0541d00..00000000 --- a/spring-shell-standard/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "name": "org.springframework.shell.standard.completion.AbstractCompletions$DefaultCommandModel", - "allDeclaredMethods": true - }, - { - "name": "org.springframework.shell.standard.completion.AbstractCompletions$DefaultCommandModelCommand", - "allDeclaredMethods": true - } -] \ No newline at end of file diff --git a/spring-shell-standard/src/main/resources/META-INF/native-image/resource-config.json b/spring-shell-standard/src/main/resources/META-INF/native-image/resource-config.json deleted file mode 100644 index 9e8cab21..00000000 --- a/spring-shell-standard/src/main/resources/META-INF/native-image/resource-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "completion/.*" - } - ] - } -} diff --git a/spring-shell-standard/src/main/resources/META-INF/spring/aot.factories b/spring-shell-standard/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 00000000..cc170ba2 --- /dev/null +++ b/spring-shell-standard/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,3 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +org.springframework.shell.standard.StandardResourcesRuntimeHints,\ +org.springframework.shell.standard.completion.StandardCompletionModelsRuntimeHints