From 60eec2fee49d0e158710eb66c0976f38df05d942 Mon Sep 17 00:00:00 2001 From: Haotian Zhang <skyebefreeman@qq.com> Date: Fri, 28 Feb 2025 15:33:05 +0800 Subject: [PATCH] docs:update JDK version configuration in GitHub Actions. (#1510) --- .github/PULL_REQUEST_TEMPLATE.md | 8 - .github/workflows/codecov_jdk17.yml | 34 ++++ .../{codecov.yml => codecov_jdk8.yml} | 10 +- .github/workflows/junit_test_jdk17-21.yml | 40 ++++ ...{junit_test.yml => junit_test_jdk8-21.yml} | 11 +- .github/workflows/license-checker.yml | 2 + .../{snapshot.yml => snapshot_jdk17.yml} | 7 +- .github/workflows/snapshot_jdk8.yml | 48 +++++ CHANGELOG.md | 1 + spring-cloud-tencent-dependencies/pom.xml | 2 +- .../callee/QuickstartCalleeController.java | 2 + .../callee/QuickstartCalleeController.java | 2 + .../src/main/resources/application.yml | 6 + ...curityProtectionAutoConfigurationTest.java | 189 ------------------ .../FailedEventApplicationListenerTest.java | 154 -------------- 15 files changed, 145 insertions(+), 371 deletions(-) create mode 100644 .github/workflows/codecov_jdk17.yml rename .github/workflows/{codecov.yml => codecov_jdk8.yml} (85%) create mode 100644 .github/workflows/junit_test_jdk17-21.yml rename .github/workflows/{junit_test.yml => junit_test_jdk8-21.yml} (79%) rename .github/workflows/{snapshot.yml => snapshot_jdk17.yml} (90%) create mode 100644 .github/workflows/snapshot_jdk8.yml delete mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-tencent-security-protection-plugin/src/test/java/com/tencent/cloud/plugin/protection/SecurityProtectionAutoConfigurationTest.java delete mode 100644 spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/listener/FailedEventApplicationListenerTest.java diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ddd1ce6e1..31bc7906a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,11 +23,3 @@ closes # - [ ] Add information of this PR to CHANGELOG.md in root of project. - [ ] Add documentation in javadoc or comment below the PR if necessary. - -## Checklist (Optional) - -- [ ] Will pull request to branch of 2023. -- [ ] Will pull request to branch of 2022. -- [ ] Will pull request to branch of 2021. -- [ ] Will pull request to branch of 2020. -- [ ] Will pull request to branch of hoxton. diff --git a/.github/workflows/codecov_jdk17.yml b/.github/workflows/codecov_jdk17.yml new file mode 100644 index 000000000..2a7216bbe --- /dev/null +++ b/.github/workflows/codecov_jdk17.yml @@ -0,0 +1,34 @@ +name: Codecov with JDK 17 + +on: + push: + branches: + - 2024 + - 2023 + - 2022 + pull_request: + branches: + - 2024 + - 2023 + - 2022 + +jobs: + codecov: + runs-on: ubuntu-latest + + steps: + - name: Checkout codes + uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + - name: Test with Maven + run: mvn clean test -B -U -Psonatype + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + files: ${{ github.workspace }}/target/site/jacoco/jacoco.xml diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov_jdk8.yml similarity index 85% rename from .github/workflows/codecov.yml rename to .github/workflows/codecov_jdk8.yml index ef7a1b4cb..bb7ba75a0 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov_jdk8.yml @@ -1,18 +1,14 @@ -name: Codecov +name: Codecov with JDK 8 on: push: branches: - - 2023 - - 2022 - 2021 - 2020 - hoxton - greenwich pull_request: branches: - - 2023 - - 2022 - 2021 - 2020 - hoxton @@ -25,11 +21,11 @@ jobs: steps: - name: Checkout codes uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 8 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: 17 + java-version: 8 - name: Test with Maven run: mvn clean test -B -U -Psonatype - name: Upload coverage to Codecov diff --git a/.github/workflows/junit_test_jdk17-21.yml b/.github/workflows/junit_test_jdk17-21.yml new file mode 100644 index 000000000..0d76c8bfb --- /dev/null +++ b/.github/workflows/junit_test_jdk17-21.yml @@ -0,0 +1,40 @@ +name: Junit Test with JDK from 17 to 21 + +on: + push: + branches: + - 2024 + - 2023 + - 2022 + pull_request: + branches: + - 2024 + - 2023 + - 2022 + +jobs: + build: + strategy: + matrix: + java: [ 17, 21 ] + os: [ 'windows-latest', 'ubuntu-latest' ] + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout codes + uses: actions/checkout@v4 + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: ${{ matrix.java }} + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Test with Maven + run: mvn clean test -f pom.xml -B -P sonatype -U diff --git a/.github/workflows/junit_test.yml b/.github/workflows/junit_test_jdk8-21.yml similarity index 79% rename from .github/workflows/junit_test.yml rename to .github/workflows/junit_test_jdk8-21.yml index 68606512e..56af9ed31 100644 --- a/.github/workflows/junit_test.yml +++ b/.github/workflows/junit_test_jdk8-21.yml @@ -1,27 +1,24 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Test with Junit +name: Junit Test with JDK from 8 to 21 on: push: branches: - - hoxton - 2021 - 2020 + - hoxton - greenwich pull_request: branches: - - hoxton - 2021 - 2020 + - hoxton - greenwich jobs: junit: strategy: matrix: - java: [ 8, 11, 17 ] + java: [ 8, 11, 17, 21 ] os: [ 'windows-latest', 'ubuntu-latest' ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/license-checker.yml b/.github/workflows/license-checker.yml index acb393eac..524788527 100644 --- a/.github/workflows/license-checker.yml +++ b/.github/workflows/license-checker.yml @@ -3,6 +3,7 @@ name: License checker on: push: branches: + - 2024 - 2023 - 2022 - 2021 @@ -11,6 +12,7 @@ on: - greenwich pull_request: branches: + - 2024 - 2023 - 2022 - 2021 diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot_jdk17.yml similarity index 90% rename from .github/workflows/snapshot.yml rename to .github/workflows/snapshot_jdk17.yml index fc91cd338..af766a65e 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot_jdk17.yml @@ -1,14 +1,11 @@ -name: Snapshot +name: Snapshot with JDK 17 on: push: branches: + - 2024 - 2023 - 2022 - - 2021 - - 2020 - - hoxton - - greenwich jobs: check-snapshot: diff --git a/.github/workflows/snapshot_jdk8.yml b/.github/workflows/snapshot_jdk8.yml new file mode 100644 index 000000000..c5fa346d2 --- /dev/null +++ b/.github/workflows/snapshot_jdk8.yml @@ -0,0 +1,48 @@ +name: Snapshot with JDK 8 + +on: + push: + branches: + - 2021 + - 2020 + - hoxton + - greenwich + +jobs: + check-snapshot: + runs-on: ubuntu-latest + outputs: + IS_SNAPSHOT: ${{ steps.set_output_1.outputs.IS_SNAPSHOT }} + steps: + - name: Checkout codes + uses: actions/checkout@v4 + - name: Check deploy type + id: set_output_1 + run: | + line="$(grep SNAPSHOT pom.xml || true)" + echo $line + if [ -n "$line" ]; then + echo "IS_SNAPSHOT=true" >> $GITHUB_OUTPUT + else + echo "IS_SNAPSHOT=false" >> $GITHUB_OUTPUT + fi + snapshot: + runs-on: ubuntu-latest + needs: check-snapshot + if: ${{ needs.check-snapshot.outputs.IS_SNAPSHOT == 'true' }} + steps: + - name: Checkout codes + uses: actions/checkout@v4 + - name: Set up JDK 8 + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'temurin' + server-id: nexus-snapshots + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - name: Publish package + run: mvn clean deploy -B -U -Psonatype + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 691bceb0b..7edc0ded2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,3 +8,4 @@ - [feat:use polaris-all for shading third-party dependencies.](https://github.com/Tencent/spring-cloud-tencent/pull/1498) - [feat:support default instance circuit breaker rule.](https://github.com/Tencent/spring-cloud-tencent/pull/1499) - [fix: fix count circuit breaker in gateway & return 404 when context api does not match.](https://github.com/Tencent/spring-cloud-tencent/pull/1508) +- [docs:update JDK version configuration in GitHub Actions.](https://github.com/Tencent/spring-cloud-tencent/pull/1510) diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 430588145..2e1a61602 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -78,7 +78,7 @@ <!-- Dependencies --> <bcpkix-jdk18on.version>1.78.1</bcpkix-jdk18on.version> - <byte-buddy.version>1.12.19</byte-buddy.version> + <byte-buddy.version>1.14.19</byte-buddy.version> <jackson.version>2.15.3</jackson.version> <mocktio.version>4.9.0</mocktio.version> <system-stubs-jupiter.version>2.0.2</system-stubs-jupiter.version> diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java index 56ed7aca1..af758762e 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-a/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java @@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; @@ -42,6 +43,7 @@ import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; * * @author Haotian Zhang */ +@RefreshScope @RestController @RequestMapping("/quickstart/callee") public class QuickstartCalleeController { diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java index 6d9a976b1..8a36e7c77 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-callee-service-b/src/main/java/com/tencent/cloud/quickstart/callee/QuickstartCalleeController.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -43,6 +44,7 @@ import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; * * @author Haotian Zhang */ +@RefreshScope @RestController @RequestMapping("/quickstart/callee") public class QuickstartCalleeController { diff --git a/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/application.yml b/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/application.yml index d45c52e7b..dadcd07d7 100644 --- a/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/application.yml +++ b/spring-cloud-tencent-examples/quickstart-example/quickstart-gateway-service/src/main/resources/application.yml @@ -50,6 +50,12 @@ spring: - Path=/QuickstartCallerService/** filters: - StripPrefix=1 + - id: QuickstartCalleeService + uri: lb://QuickstartCalleeService + predicates: + - Path=/QuickstartCalleeService/** + filters: + - StripPrefix=1 logging: file: name: /sct-demo-logs/${spring.application.name}/root.log diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-security-protection-plugin/src/test/java/com/tencent/cloud/plugin/protection/SecurityProtectionAutoConfigurationTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-security-protection-plugin/src/test/java/com/tencent/cloud/plugin/protection/SecurityProtectionAutoConfigurationTest.java deleted file mode 100644 index cb93c89ea..000000000 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-security-protection-plugin/src/test/java/com/tencent/cloud/plugin/protection/SecurityProtectionAutoConfigurationTest.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making spring-cloud-tencent available. - * - * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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 com.tencent.cloud.plugin.protection; - -import java.security.Permission; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.web.servlet.function.RouterFunction; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -/** - * Test for {@link SecurityProtectionAutoConfiguration}. - */ -@ExtendWith(MockitoExtension.class) -class SecurityProtectionAutoConfigurationTest { - - @Mock - private ConfigurableApplicationContext applicationContext; - - @Test - void testServletProtectionNoRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ServletProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ServletProtectionConfiguration(); - config.applicationContext = applicationContext; - config.routerFunctions = null; - - // Act - config.afterPropertiesSet(); - - // Verify - // Should not call exit when no RouterFunctions present - verify(applicationContext, never()).close(); - } - - @Test - void testServletProtectionEmptyRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ServletProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ServletProtectionConfiguration(); - config.applicationContext = applicationContext; - config.routerFunctions = new ArrayList<>(); - - // Act - config.afterPropertiesSet(); - - // Verify - // Should not call exit when RouterFunctions list is empty - verify(applicationContext, never()).close(); - } - - @Test - void testServletProtectionWithRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ServletProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ServletProtectionConfiguration(); - config.applicationContext = mock(ConfigurableApplicationContext.class); - List<RouterFunction> routerFunctions = new ArrayList<>(); - routerFunctions.add(mock(RouterFunction.class)); - config.routerFunctions = routerFunctions; - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - config.afterPropertiesSet(); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - @Test - void testReactiveProtectionNoRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration(); - config.applicationContext = applicationContext; - config.routerFunctions = null; - - // Act - config.afterPropertiesSet(); - - // Verify - verify(applicationContext, never()).close(); - } - - @Test - void testReactiveProtectionEmptyRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration(); - config.applicationContext = applicationContext; - config.routerFunctions = new ArrayList<>(); - - // Act - config.afterPropertiesSet(); - - // Verify - verify(applicationContext, never()).close(); - } - - @Test - void testReactiveProtectionWithRouterFunctions() { - // Arrange - SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration config = - new SecurityProtectionAutoConfiguration.ReactiveProtectionConfiguration(); - config.applicationContext = mock(ConfigurableApplicationContext.class); - List<org.springframework.web.reactive.function.server.RouterFunction> routerFunctions = new ArrayList<>(); - routerFunctions.add(mock(org.springframework.web.reactive.function.server.RouterFunction.class)); - config.routerFunctions = routerFunctions; - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - config.afterPropertiesSet(); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - @Test - void testInterruptedExceptionHandling() throws InterruptedException { - // Arrange - ConfigurableApplicationContext mockContext = mock(ConfigurableApplicationContext.class); - Thread testThread = new Thread(() -> ExitUtils.exit(mockContext, 3000)); - - - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - // Act - testThread.start(); - testThread.interrupt(); - Thread.sleep(6000); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - public static class ExitSecurityManager extends SecurityManager { - - @Override - public void checkPermission(Permission perm) { - if (perm.getName().contains("exitVM")) { - throw new SecurityException("System.exit is not allowed"); - } - } - } -} diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/listener/FailedEventApplicationListenerTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/listener/FailedEventApplicationListenerTest.java deleted file mode 100644 index 8e38f769f..000000000 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/listener/FailedEventApplicationListenerTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making spring-cloud-tencent available. - * - * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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 com.tencent.cloud.polaris.context.listener; - -import java.security.Permission; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.mockito.Mockito.when; - - -class FailedEventApplicationListenerTest { - - @Mock - private ConfigurableApplicationContext mockConfigurableContext; - - @Mock - private ApplicationContext mockApplicationContext; - - @Mock - private ApplicationFailedEvent mockFailedEvent; - - private FailedEventApplicationListener listener; - - @BeforeEach - void setUp() { - MockitoAnnotations.openMocks(this); - listener = new FailedEventApplicationListener(); - } - - @Test - void testSetApplicationContext() { - // Test setting application context - listener.setApplicationContext(mockApplicationContext); - } - - @Test - void testOnApplicationEventWithConfigurableContext() { - // Arrange - listener.setApplicationContext(mockConfigurableContext); - when(mockFailedEvent.getException()).thenReturn(new RuntimeException("Test Exception")); - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - // Act - listener.onApplicationEvent(mockFailedEvent); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - @Test - void testOnApplicationEventWithNonConfigurableContext() { - // Arrange - listener.setApplicationContext(mockApplicationContext); - when(mockFailedEvent.getException()).thenReturn(new RuntimeException("Test Exception")); - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - // Act - listener.onApplicationEvent(mockFailedEvent); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - @Test - void testOnApplicationEventWithInterruptedException() { - // Arrange - listener.setApplicationContext(mockConfigurableContext); - Thread.currentThread().interrupt(); // Simulate interruption - - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - // Act - listener.onApplicationEvent(mockFailedEvent); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - @Test - void testOnApplicationEventWithNullException() { - // Arrange - listener.setApplicationContext(mockConfigurableContext); - when(mockFailedEvent.getException()).thenReturn(null); - - - SecurityManager originalSecurityManager = System.getSecurityManager(); - System.setSecurityManager(new ExitSecurityManager()); - - try { - // Act - listener.onApplicationEvent(mockFailedEvent); - } - catch (SecurityException e) { - // Ignore - } - finally { - System.setSecurityManager(originalSecurityManager); - } - } - - public static class ExitSecurityManager extends SecurityManager { - - @Override - public void checkPermission(Permission perm) { - if (perm.getName().contains("exitVM")) { - throw new SecurityException("System.exit is not allowed"); - } - } - } -}