diff --git a/CHANGELOG.md b/CHANGELOG.md index bd6ec57e..eca3c7bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **BREAKING:** Upgrade Groovy from 4.0.31 to 5.0.6 +- **BREAKING:** Drop Java 8 support — minimum is now Java 11 (Groovy 5.x requires JDK 11+) +- Bump exported API package versions to 20.0.0 + ## [19.1.0] - 2026-05-04 ### Changed diff --git a/README.md b/README.md index 383c0946..f42750de 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ in the package for reference. ## Compatibility -AEM Groovy Console 19.0.8+ runs on Java 8, 11, 17 & 21 with an embedded Groovy version of 4.0.22 +AEM Groovy Console 20.x requires **Java 11, 17 or 21** with an embedded Groovy version of 5.0.6. + +For environments still on Java 8, use AEM Groovy Console 19.x (last release on the Groovy 4.x line). Supported versions: diff --git a/all/pom.xml b/all/pom.xml index c0bc45d8..18864a20 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -6,7 +6,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-all diff --git a/api/pom.xml b/api/pom.xml index 49ae7ef3..106e16ac 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -8,7 +8,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-api diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/impl/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/impl/package-info.groovy index 21e83a7d..006b8b64 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/impl/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/impl/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.api.context.impl; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/package-info.groovy index 5cd71463..49a7b7a9 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/context/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.api.context; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/package-info.groovy index 19ca69f7..df2b767a 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/api/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/api/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.api; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/audit/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/audit/package-info.groovy index b8faa8a6..291c48fe 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/audit/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/audit/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.1.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.audit; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/configuration/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/configuration/package-info.groovy index 37697910..7fb8ecb1 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/configuration/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/configuration/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.configuration; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/constants/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/constants/package-info.groovy index 5f131794..cfd583d8 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/constants/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/constants/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.1") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.constants; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/extension/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/extension/package-info.groovy index 3009b3a4..597d9a4b 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/extension/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/extension/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.extension; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/notification/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/notification/package-info.groovy index 0785fa23..9175b653 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/notification/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/notification/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.notification; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/package-info.groovy index a05e6853..4ab242ab 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/response/impl/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/response/impl/package-info.groovy index 7df8d89c..309d56d8 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/response/impl/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/response/impl/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.response.impl; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/response/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/response/package-info.groovy index ac5c5346..6615452b 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/response/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/response/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.response; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/table/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/table/package-info.groovy index d3dea61b..c1d3e60d 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/table/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/table/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.table; diff --git a/api/src/main/groovy/be/orbinson/aem/groovy/console/utils/package-info.groovy b/api/src/main/groovy/be/orbinson/aem/groovy/console/utils/package-info.groovy index 289e0c3f..af926631 100644 --- a/api/src/main/groovy/be/orbinson/aem/groovy/console/utils/package-info.groovy +++ b/api/src/main/groovy/be/orbinson/aem/groovy/console/utils/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.utils; diff --git a/bundle/pom.xml b/bundle/pom.xml index 3e0c350b..2f1ed0c1 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -8,7 +8,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-bundle diff --git a/bundle/src/main/groovy/be/orbinson/aem/groovy/console/components/package-info.groovy b/bundle/src/main/groovy/be/orbinson/aem/groovy/console/components/package-info.groovy index d2c7bfe0..cd67a499 100644 --- a/bundle/src/main/groovy/be/orbinson/aem/groovy/console/components/package-info.groovy +++ b/bundle/src/main/groovy/be/orbinson/aem/groovy/console/components/package-info.groovy @@ -1,3 +1,3 @@ @org.osgi.annotation.bundle.Export -@org.osgi.annotation.versioning.Version("19.0.0") +@org.osgi.annotation.versioning.Version("20.0.0") package be.orbinson.aem.groovy.console.components; diff --git a/groovy/groovy-osgi/pom.xml b/groovy/groovy-osgi/pom.xml index 3f0500f9..6317cfa8 100644 --- a/groovy/groovy-osgi/pom.xml +++ b/groovy/groovy-osgi/pom.xml @@ -8,7 +8,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT ../../pom.xml diff --git a/groovy/pom.xml b/groovy/pom.xml index 54a21c7a..5e2b02d2 100644 --- a/groovy/pom.xml +++ b/groovy/pom.xml @@ -8,7 +8,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT pom diff --git a/it.tests/pom.xml b/it.tests/pom.xml index 553b7e01..ede024c7 100644 --- a/it.tests/pom.xml +++ b/it.tests/pom.xml @@ -9,7 +9,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-it-tests @@ -86,6 +86,11 @@ 14 *.json + + + org.apache.felix:org.apache.felix.http.jetty12:HIGHEST + project.version diff --git a/it.tests/src/main/features/jetty12.json b/it.tests/src/main/features/jetty12.json new file mode 100644 index 00000000..966153ac --- /dev/null +++ b/it.tests/src/main/features/jetty12.json @@ -0,0 +1,11 @@ +{ + // WORKAROUND: Sling Starter 14 ships org.apache.felix.http.jetty12 1.1.8, which + // intermittently fails IT startup. Pin 1.2.0 here (the aggregate's artifactsOverrides + // takes HIGHEST). Remove this file and the override once we move to Sling Starter 15. + "bundles": [ + { + "id": "org.apache.felix:org.apache.felix.http.jetty12:1.2.0", + "start-order": "5" + } + ] +} diff --git a/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java b/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java index 37713d66..9e97fe7e 100644 --- a/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java +++ b/it.tests/src/test/java/be/orbinson/aem/groovy/console/it/GroovyConsoleServiceIT.java @@ -20,9 +20,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; -import static org.awaitility.Awaitility.await; import static org.junit.jupiter.api.Assertions.*; class GroovyConsoleServiceIT { @@ -36,11 +34,60 @@ class GroovyConsoleServiceIT { @BeforeAll static void setUp() { httpClient = HttpClients.createDefault(); + waitForStableReadiness(300, 15); + } - // Wait for the Sling Starter and the Groovy Console content package to be fully installed - await().atMost(120, TimeUnit.SECONDS) - .pollInterval(5, TimeUnit.SECONDS) - .untilAsserted(() -> assertTrue(isHealthy(), "System not healthy")); + /** + * Polls the Groovy Console servlet with a no-op script until it has returned 200 OK for a + * continuous window. This guards against the Sling Starter package-install refresh cascade + * that briefly tears down our bundle: a single OK isn't enough — we need stability before + * the test cases start firing requests. + */ + private static void waitForStableReadiness(long overallTimeoutSec, long stabilityWindowSec) { + long deadline = System.currentTimeMillis() + overallTimeoutSec * 1000; + long stableSince = -1; + while (System.currentTimeMillis() < deadline) { + boolean ready = isGroovyConsoleReady(); + long now = System.currentTimeMillis(); + if (ready) { + if (stableSince < 0) { + stableSince = now; + } else if (now - stableSince >= stabilityWindowSec * 1000) { + return; + } + } else { + stableSince = -1; + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + fail("Interrupted while waiting for Groovy Console readiness"); + } + } + fail("Groovy Console did not become stable within " + overallTimeoutSec + + "s (need " + stabilityWindowSec + "s of continuous OK)"); + } + + private static boolean isGroovyConsoleReady() { + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpPost post = new HttpPost(BASE_URL + "/bin/groovyconsole/post"); + List params = new ArrayList<>(); + params.add(new BasicNameValuePair("script", "return 'ready'")); + post.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8)); + post.addHeader("Authorization", AUTH_HEADER); + post.addHeader("Connection", "close"); + try (CloseableHttpResponse response = client.execute(post)) { + if (response.getStatusLine().getStatusCode() != 200) { + return false; + } + String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); + JsonObject json = JsonParser.parseString(body).getAsJsonObject(); + return "ready".equals(json.get("result").getAsString()); + } + } catch (Exception e) { + return false; + } } @AfterAll @@ -223,20 +270,6 @@ void testXmlFragmentExtensions() throws Exception { assertEquals("1", response.get("result").getAsString()); } - private static boolean isHealthy() { - try { - HttpGet healthCheck = new HttpGet(BASE_URL + "/system/health.json?tags=systemalive,groovyconsole"); - healthCheck.addHeader("Authorization", AUTH_HEADER); - try (CloseableHttpResponse response = httpClient.execute(healthCheck)) { - String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); - JsonObject jsonResponse = JsonParser.parseString(body).getAsJsonObject(); - return "OK".equals(jsonResponse.get("overallResult").getAsString()); - } - } catch (Exception e) { - return false; - } - } - private static JsonObject doGet(String path) throws IOException { HttpGet get = new HttpGet(BASE_URL + path); get.addHeader("Authorization", AUTH_HEADER); diff --git a/pom.xml b/pom.xml index 217045df..6c6e348c 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ be.orbinson.aem aem-groovy-console pom - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT AEM Groovy Console @@ -84,8 +84,8 @@ yyyy-MM-dd'T'HH:mm:ss.SSSZ - 1.8 - 1.8 + 11 + 11 UTF-8 UTF-8 ${maven.build.timestamp} @@ -93,8 +93,8 @@ 6.4.0 6.5.10 - 4.0.31 - 9.7 + 5.0.6 + 9.9.1 0.9.4 @@ -168,8 +168,8 @@ 3.8.1 groovy-eclipse-compiler - 1.8 - 1.8 + 11 + 11 utf-8 diff --git a/ui.apps.aem/pom.xml b/ui.apps.aem/pom.xml index 7252628e..d5c618de 100644 --- a/ui.apps.aem/pom.xml +++ b/ui.apps.aem/pom.xml @@ -6,7 +6,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-ui.apps.aem diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index 43c2a5a8..08902bb8 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -6,7 +6,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-ui.apps diff --git a/ui.config/pom.xml b/ui.config/pom.xml index fd959fc6..4bec4771 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -5,7 +5,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-ui.config diff --git a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.felix.hc.generalchecks.ServicesCheck-groovyconsole.config b/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.felix.hc.generalchecks.ServicesCheck-groovyconsole.config deleted file mode 100644 index cbd50cbe..00000000 --- a/ui.config/src/main/content/jcr_root/apps/groovyconsole-config/osgiconfig/config/org.apache.felix.hc.generalchecks.ServicesCheck-groovyconsole.config +++ /dev/null @@ -1,3 +0,0 @@ -hc.name="Groovy Console Services" -hc.tags=["groovyconsole"] -services.list=["be.orbinson.aem.groovy.console.GroovyConsoleService"] diff --git a/ui.content/pom.xml b/ui.content/pom.xml index fc0f019b..fc6213dd 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -6,7 +6,7 @@ be.orbinson.aem aem-groovy-console - 19.1.1-SNAPSHOT + 20.0.0-SNAPSHOT aem-groovy-console-ui.content