Open brendandburns opened 1 year ago
I fixed this by locking to 2.13.3 but that's not a long term solution.
Hi @brendandburns! Thank you for raising this. We have recently made some changes to CodeQL's ability to discover which versions of Java are installed in the build environment.
As you can see in the logs, both versions of CodeQL infer that the project wants to be built with Java 8 (more on that in a moment). The difference is that the old version of CodeQL couldn't find Java 8 installed, and therefore just stuck to the default. The new version of CodeQL can find Java 8 and therefore acts on its conclusion that Java 8 is best for the project.
For Maven-based projects, CodeQL looks at the pom.xml
in the root directory of the project and searches a few elements for hints about what Java version should be used to build the project. One of the first locations it looks at is project/properties/java.version
. In the case of this repository, the Java version specified there is 1.8
and so CodeQL concludes that this is the best Java version for the project.
So a simple fix here might be to just change that value in the root-level pom.xml
to 17
instead of 1.8
. Would that work for you?
Unfortunately, that doesn't work. We mostly build for java 8, but we have one sub-module pom that conditionally builds exclusively for Java 17, because it uses Spring 6 which only supports Java 17:
https://github.com/kubernetes-client/java/blob/master/spring-aot/pom.xml#L71
So in this case, infering the language from the base pom.xml doesn't work correctly for this project.
Additionally, I think this should be considered a breaking change, since we have something that worked in 2.13.3 and no longer works in 2.13.4
Thanks for the update that switching to Java 17 for the entire repository is not an option for you.
I would recommend that you change the CodeQL workflow to use a manual build, rather than rely on CodeQL's automatic build functionality. In essence, all the automatic build process currently does for you here is:
You can invoke Maven yourself in the CodeQL workflow in place of the automatic build step:
- name: Setup Java 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17.0.x'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# This is what the CodeQL automatic build currently invokes
- name: Build project
run: ./mvnw clean package -f "pom.xml" -B -V -e -Dfindbugs.skip -Dcheckstyle.skip -Dpmd.skip=true -Dspotbugs.skip -Denforcer.skip -Dmaven.javadoc.skip -DskipTests -Dmaven.test.skip.exec -Dlicense.skip=true -Drat.skip=true -Dspotless.check.skip=true
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
This will skip the Java version inference and generally give you more control over the build. If you wanted to, you could e.g. build using an older version of Java and exclude the spring-aot
submodule instead, but the above will do what happened with older versions of CodeQL.
Another approach that I explored would be to teach Maven to actually use the configured Java versions for each project. You can do this by having a workflow which installs both Java 8 and 17:
- name: Setup Java 8
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 8
- name: Setup Java 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 17
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v2
This results in a toolchains.xml
file containing both Java versions. Maven can then be configured to detect these using the maven-toolchains-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<toolchains>
<jdk>
<version>8</version>
</jdk>
<jdk>
<version>17</version>
</jdk>
</toolchains>
</configuration>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
</plugin>
During the build, Maven will then automatically use the respective Java versions based on what is configured in the submodules' pom.xml
files. However, I don't know whether this approach is feasible for you since Maven will now require both Java 8 and Java 17 to be present for each build and I can see that in your regular build process you are targeting Java 8, 11, or 17 exclusively for the entire repo, but exclude the spring-aot
submodule from the build for Java 8 and 11.
I'm using the
setup-java
action in my config to set the Java version to 17.Previous to the 2.13.4 release, this was detected correctly, but starting with the 2.13.4 releases, it is selecting the built-in Java 8 version that is in the github action image.
Output from 2.13.3:
Output from 2.3.14: