diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 128e0f35..01677bb3 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -18,7 +18,7 @@ jobs: matrix: # test against latest update of each major Java version, as well as specific updates of LTS versions: RUNTIME: [ol, wlp] - RUNTIME_VERSION: [23.0.0.12] + RUNTIME_VERSION: [24.0.0.3] java: [21, 17, 11, 8] exclude: - java: 8 @@ -71,11 +71,11 @@ jobs: - name: Run tests that require a minimum of Java 17 or later if: ${{ matrix.java == '17' || matrix.java == '21' }} run: - ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info + ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*,**/TestCompileJSPSource17*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info # Run tests - name: Run tests with Gradle on Ubuntu run: - ./gradlew clean install check -P"test.exclude"="**/TestSpringBootApplication30*,**/DevContainerTest*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info + ./gradlew clean install check -P"test.exclude"="**/TestSpringBootApplication30*,**/TestCompileJSPSource17*,**/DevContainerTest*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info # Copy build reports and upload artifact if build failed - name: Copy build/report/tests/test for upload if: ${{ failure() }} @@ -100,7 +100,7 @@ jobs: matrix: # test against latest update of each major Java version, as well as specific updates of LTS versions: RUNTIME: [ol, wlp] - RUNTIME_VERSION: [23.0.0.12] + RUNTIME_VERSION: [24.0.0.3] java: [21, 17, 11, 8] exclude: - java: 8 @@ -109,7 +109,7 @@ jobs: RUNTIME: wlp name: ${{ matrix.RUNTIME }} ${{ matrix.RUNTIME_VERSION }}, Java ${{ matrix.java }}, Windows env: - TEST_EXCLUDE: ${{ ((matrix.java == '8') && '**/TestCreateWithConfigDir*,**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*,**/TestSpringBootApplication30*,**/DevContainerTest*') || '**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*,**/TestSpringBootApplication30*,**/DevContainerTest*' }} + TEST_EXCLUDE: ${{ ((matrix.java == '8') && '**/TestCreateWithConfigDir*,**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*,**/TestSpringBootApplication30*,**/TestCompileJSPSource17*,**/DevContainerTest*') || '**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*,**/TestSpringBootApplication30*,**/TestCompileJSPSource17*,**/DevContainerTest*' }} steps: # Checkout repos - name: Checkout ci.gradle @@ -154,7 +154,7 @@ jobs: - name: Run tests that require a minimum of Java 17 or later if: ${{ matrix.java == '17' || matrix.java == '21' }} run: - ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info --no-daemon + ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*,**/TestCompileJSPSource17*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info --no-daemon # Run tests - name: Run tests with Gradle on Windows working-directory: C:/ci.gradle diff --git a/build.gradle b/build.gradle index 86d56c4c..c9e74f21 100644 --- a/build.gradle +++ b/build.gradle @@ -59,8 +59,8 @@ compileTestGroovy { targetCompatibility = JavaVersion.VERSION_1_8 } -def libertyAntVersion = "1.9.14" -def libertyCommonVersion = "1.8.32" +def libertyAntVersion = "1.9.15" +def libertyCommonVersion = "1.8.33" dependencies { implementation gradleApi() diff --git a/docs/compileJsp.md b/docs/compileJsp.md index 69cf96d4..3d482ff7 100644 --- a/docs/compileJsp.md +++ b/docs/compileJsp.md @@ -1,6 +1,8 @@ ## compileJsp task --- -The `compileJsp` task compiles the JSP files in the src/main/webapp directory so that they can be packaged with the application. +The `compileJsp` task compiles the JSP files in the src/main/webapp directory so that they can be packaged with the application. The Java version used for the compilation comes from either the `release` attribute on the `compileJava` task or the `sourceCompatibility` property with the first taking precedence. + +Note: As of Liberty version 24.0.0.1, this task only works with Long Term Service (LTS) releases of Java. See the [documentation](https://openliberty.io/docs/latest/reference/config/jspEngine.html) for the valid values for the `javaSourceLevel` attribute on the `jspEngine` configuration element. Prior to version 24.0.0.1, the `jdkSourceLevel` attribute was used on the `jspEngine` [element](https://openliberty.io/docs/23.0.0.12/reference/config/jspEngine.html) and only supported up to and including Java 8 (specified as 18). ### dependsOn `compileJsp` depends on `installLiberty` and `compileJava`. diff --git a/src/main/groovy/io/openliberty/tools/gradle/tasks/CompileJSPTask.groovy b/src/main/groovy/io/openliberty/tools/gradle/tasks/CompileJSPTask.groovy index e1e88544..0fd15f2c 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/tasks/CompileJSPTask.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/tasks/CompileJSPTask.groovy @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corporation 2017, 2020. + * (C) Copyright IBM Corporation 2017, 2024. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,6 +85,9 @@ class CompileJSPTask extends AbstractFeatureTask { logger.debug("Classpath: " + classpathStr) compileJsp.setClasspath(classpathStr) + // Java version for compiling jsps + setCompileJavaSourceVersion(compileJsp, task) + //Feature list Set installedFeatures = getSpecifiedFeatures(null); @@ -103,23 +106,41 @@ class CompileJSPTask extends AbstractFeatureTask { compileJsp.execute() } - private void setJspVersion(CompileJSPs compile, Set installedFeatures) { - //If no conditions are met, defaults to 2.3 from the ant task - if (project.liberty.jsp.jspVersion != null) { - compile.setJspVersion(project.liberty.jsp.jspVersion); - } - else { - Iterator it = installedFeatures.iterator(); - String currentFeature; - while (it.hasNext()) { - currentFeature = (String) it.next(); - if(currentFeature.startsWith("jsp-")) { - String version = currentFeature.replace("jsp-", ""); - compile.setJspVersion(version); - break; - } + private void setCompileJavaSourceVersion(CompileJSPs compile, Task task) { + Task compileTask = project.tasks.getByName('compileJava') + + if (compileTask != null) { + String release = (String) compileTask.getOptions().getRelease().getOrNull() + if (release != null) { + logger.info("Found release from compileJava options: "+release) + compile.setSource(release) + return + } + } + + if (project.hasProperty('sourceCompatibility')) { + logger.info("Found sourceCompatibility") + compile.setSource((String) project.getProperties().get('sourceCompatibility')) + } + } + + private void setJspVersion(CompileJSPs compile, Set installedFeatures) { + //If no conditions are met, defaults to 2.3 from the ant task + if (project.liberty.jsp.jspVersion != null) { + compile.setJspVersion(project.liberty.jsp.jspVersion); + } + else { + Iterator it = installedFeatures.iterator(); + String currentFeature; + while (it.hasNext()) { + currentFeature = (String) it.next(); + if(currentFeature.startsWith("jsp-")) { + String version = currentFeature.replace("jsp-", ""); + compile.setJspVersion(version); + break; } } + } } protected void setCompileDependencies(Task task, Set classpaths) { diff --git a/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSP.groovy b/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSP.groovy index 7ee90890..42699eb4 100644 --- a/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSP.groovy +++ b/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSP.groovy @@ -85,7 +85,17 @@ public class TestCompileJSP extends AbstractIntegrationTest{ Assert.assertTrue("servlet-3.1 found ==>", features.contains("servlet-3.1")) Assert.assertTrue("jsp-2.3 found ==>", features.contains("jsp-2.3")) + + // parse input XML Document + String expression2 = "/server/jspEngine"; + nodes = (NodeList) xPath.compile(expression2).evaluate(inputDoc, XPathConstants.NODESET) + Assert.assertEquals("Number of elements ==>", 1, nodes.getLength()) + + if (nodes.item(0) instanceof Element) { + Element child = (Element) nodes.item(0) + String nodeValue = child.getAttribute("javaSourceLevel") + Assert.assertTrue("Unexpected javaSourceLevel ==>"+nodeValue, nodeValue.equals("8")) + } } - } diff --git a/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSPSource17.groovy b/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSPSource17.groovy new file mode 100644 index 00000000..452deae3 --- /dev/null +++ b/src/test/groovy/io/openliberty/tools/gradle/TestCompileJSPSource17.groovy @@ -0,0 +1,102 @@ +package io.openliberty.tools.gradle; + +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.Test + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.junit.BeforeClass +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runners.MethodSorters +import org.junit.Assert; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestCompileJSPSource17 extends AbstractIntegrationTest{ + static File resourceDir = new File("build/resources/test/sampleJSP.servlet") + static File buildDir = new File(integTestDir, "/test-compile-jsp-source-17") + static String buildFilename = "testCompileJSP17.gradle" + + @BeforeClass + public static void setup() { + createDir(buildDir) + createTestProject(buildDir, resourceDir, buildFilename) + runTasks(buildDir, 'installFeature') + runTasks(buildDir, 'compileJsp') + } + + @Test + public void check_for_jsp() { + assert new File('build/testBuilds/test-compile-jsp-source-17/src/main/webapp/index.jsp').exists() : 'index.jsp not found!' + } + + @Test + public void test_1() { + + assert new File('build/testBuilds/test-compile-jsp-source-17/build/compileJsp').exists() : 'compileJsp Directory not found!' + } + + @Test + public void test_2() { + assert new File('build/testBuilds/test-compile-jsp-source-17/build/classes/java/_index.class').exists() : '_index.class not found!' + } + + @Test + public void check_jsp_server_xml_exists() { + assert new File('build/testBuilds/test-compile-jsp-source-17/build/compileJsp/servers/defaultServer/server.xml').exists() : 'server.xml not found!' + } + + @Test + public void check_jsp_server_xml_contains_features() { + File serverXml = new File("build/testBuilds/test-compile-jsp-source-17/build/compileJsp/servers/defaultServer/server.xml") + FileInputStream input = new FileInputStream(serverXml) + + // get input XML Document + DocumentBuilderFactory inputBuilderFactory = DocumentBuilderFactory.newInstance() + inputBuilderFactory.setIgnoringComments(true) + inputBuilderFactory.setCoalescing(true) + inputBuilderFactory.setIgnoringElementContentWhitespace(true) + inputBuilderFactory.setValidating(false) + inputBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false) + inputBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false) + DocumentBuilder inputBuilder = inputBuilderFactory.newDocumentBuilder() + Document inputDoc=inputBuilder.parse(input) + + // parse input XML Document + XPath xPath = XPathFactory.newInstance().newXPath() + String expression = "/server/featureManager/feature[text()]" + NodeList nodes = (NodeList) xPath.compile(expression).evaluate(inputDoc, XPathConstants.NODESET) + Assert.assertEquals("Number of elements ==>", 2, nodes.getLength()) + + ArrayList features = new ArrayList() + + for(int i = 0; i < nodes.getLength(); i++) { + features.add(nodes.item(i).getTextContent().trim()) + } + + Assert.assertTrue("servlet-3.1 found ==>", features.contains("servlet-3.1")) + Assert.assertTrue("jsp-2.3 found ==>", features.contains("jsp-2.3")) + + // parse input XML Document + String expression2 = "/server/jspEngine"; + nodes = (NodeList) xPath.compile(expression2).evaluate(inputDoc, XPathConstants.NODESET) + Assert.assertEquals("Number of elements ==>", 1, nodes.getLength()) + + if (nodes.item(0) instanceof Element) { + Element child = (Element) nodes.item(0) + String nodeValue = child.getAttribute("javaSourceLevel") + Assert.assertTrue("Unexpected javaSourceLevel ==>"+nodeValue, nodeValue.equals("17")) + } + } + + +} diff --git a/src/test/resources/sampleJSP.servlet/testCompileJSP17.gradle b/src/test/resources/sampleJSP.servlet/testCompileJSP17.gradle new file mode 100644 index 00000000..3e3275ef --- /dev/null +++ b/src/test/resources/sampleJSP.servlet/testCompileJSP17.gradle @@ -0,0 +1,98 @@ +/* + This test checks whether the compileJsp task was able to compile the index.jsp file from the test + project +*/ +group = 'liberty.gradle' + +buildscript { + repositories { + mavenLocal() + mavenCentral() + maven { + name = 'Sonatype Nexus Snapshots' + url = 'https://oss.sonatype.org/content/repositories/snapshots/' + } + } + dependencies { + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'war' +apply plugin: 'liberty' + +compileJava.options.release = 17 + +compileJava.options.encoding = 'UTF-8' + +ext { + // Liberty server properties + wlpServerName = 'LibertyProjectServer' + serverDirectory = "${project.buildDir}/wlp/usr/servers/${wlpServerName}" + testServerHttpPort = 9080 + testServerHttpsPort = 9443 + + // This is set in the ibm-web-ext.xml file + warContext = 'sampleJSP.servlet' + +} + +liberty { + server{ + serverXmlFile = file("src/resources/server.xml") + name = 'LibertyProjectServer' + deploy { + apps = [war] + } + looseApplication = false + stripVersion = true + } + jsp { + jspCompileTimeout = 35 + } +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'commons-logging', name: 'commons-logging', version:'1.0.4' + testImplementation group: 'junit', name: 'junit', version:'4.13.1' + providedCompile group: 'org.apache.geronimo.specs', name: 'geronimo-servlet_3.0_spec', version:'1.0' + testImplementation 'junit:junit:4.13.1' + providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version:'3.1.0' + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + +test { + println 'inside the test block' + reports.html.outputLocation = file("$buildDir/reports/unit") + reports.junitXml.outputLocation = file("$buildDir/test-results/unit") + exclude '**/it/**' +} + + +task integrationTest(type: Test) { + group 'Verification' + description 'Runs the integration tests.' + reports.html.outputLocation = file("$buildDir/reports/it") + reports.junitXml.outputLocation = file("$buildDir/test-results/it") + include '**/it/**' + exclude '**/unit/**' + + systemProperties = ['liberty.test.port': testServerHttpPort, 'war.name': warContext] +} + +task printMessageAboutRunningServer { + doLast { + println "The server is now running at http://localhost:${testServerHttpPort}/${warContext}" + println "To stop the server run 'gradle libertyStop'" + } +} + +deploy.dependsOn 'war' +war.dependsOn 'compileJSP' +integrationTest.dependsOn 'libertyStart', 'testClasses' +integrationTest.finalizedBy 'libertyStop' +libertyStart.finalizedBy 'printMessageAboutRunningServer'