oss-review-toolkit / ort

A suite of tools to automate software compliance checks.
https://oss-review-toolkit.org
Apache License 2.0
1.57k stars 308 forks source link

Improve support for different Java versions #8249

Open mnonnenmacher opened 7 months ago

mnonnenmacher commented 7 months ago

Currently the Docker image and the artifacts published to Maven Central are both built with Java 17. This can cause two kinds of issues:

One approach to solve this would be to release the Docker images and the Maven Central artifacts with different variants for each of the Java LTS releases, currently relevant are Java 11, 17, and 21.

Another more complex approach would be to decouple the Maven and Gradle analyzers from ORT itself and release them as standalone tools, comparable to the python-inspector. These tools could then be released with a bundled JVM for the different Java versions.

Also see some related PRs and issues: #4948, #6311, #8027, #8242

heliocastro commented 7 months ago

I can say decoupling Maven, and Gradle is the best suitable solution.

Explain what would be the alternatives and how this can become a nightmare:

1 - Multiple docker images with all LTS images. Today we build docker itself with Temurin as base: FROM eclipse-temurin:$JAVA_VERSION-jdk-$UBUNTU_VERSION as base This means that we will need to build base as standard image, and take care of java installs on later stage to avoid blowup the images with 3x all layers. We would treat java as another independent layer. Maintenance will be hard as long we start to change base distro, as we have layers pointing out for the base. Example: Today we have all build over Ubuntu 22.04, and python 3.10.x build for this. We will have soon the new LTS from Ubuntu, So base image will be updated to 24.04, and then same python 3.10.x will be built over this one. Any older image referring to this python will be unstable, as will point originally to older base. And not forgetting, we need rename the images for each version. Resume: maintenance complexity: Higher, size increase: High, effectiveness: medium

2 - Use SDKMAN for java So, instead of multiple images, we use SDKMAN to install parallel Java sdk's and during process change the environment to select the required JDK. It will slightly increase our build time for docker, but then will make multiple Java SDK's install easier and is future proof. But then we now transfer to Ort how it will manage in runtime the switch for the specific JDK and I honestly can't tell if is a good idea or not since I don't know that Ort code at all. Maybe a runtime environment switch will be easier from the Ort point of view. Resume: maintenance complexity: Low, size increase: Medium, effectiveness: ?

sschuberth commented 7 months ago

I'm also thinking into the direction of simply installing multiple JDK versions in parallel in the Docker image, and finding a way to choose the JDK at runtime for the package manager implementations. At least for SBT that would work, as it's called as an external CLI tool. Also for Gradle projects that leverage the toolchains mechanism that should work. Not sure about Maven, though.

mnonnenmacher commented 7 months ago

Not sure about Maven, though.

I'm not sure if have seen the issue with Maven projects so far, probably because it's more declarative than Gradle. Maybe it can happen if plugins are used the require a specific Java version, we at least load Wagon transport plugins.

heliocastro commented 7 months ago

Maven you can have in the properties:

    <java_source.version>17</java_source.version>
    <java_target.version>17</java_target.version>

But then, this is the model applied, so, if you are using java 21 to compile, it will apply only 17 characteristics. Again. sometimes not work well to the plugins.

sschuberth commented 7 months ago

Maven you can have in the properties

You have the same in Gradle, but these have no impact on the chosen JDK (if there are multiple ones on your system), but only on the command line options passed to the compiler.

sschuberth commented 7 months ago

My current idea, at least for SBT for now, is to bootstrap the required JDK via https://github.com/foojayio/discoclient at ORT analyzer runtime.

fb33 commented 6 months ago

Hi, Just a feedback with jdk21. I have some projects with gradle 8.5 and jdk21, and of course with the current ORT docker image, the analyzer failed. I make a quick (and naive) test, building in ORT image with jdk21 and run the analyzer. => there is no more issue, but the analyzer found no dependency !

I have also some projects with maven and jdk21, and there is no issue with them, all is fine.

fb33 commented 6 months ago

Do you have any idea when you'll fix the usage of jdk21 for gradle and sbt project ?

sschuberth commented 6 months ago

Do you have any idea when you'll fix the usage of jdk21 for gradle and sbt project ?

No commitment to that. But providing an example project could speed up things ๐Ÿ˜‰

fb33 commented 6 months ago

@sschuberth here is a sample of gradle project on jdk21 with the results&logs of ORT https://github.com/fb33/sample-gradle8.5-jdk21

hope this help. regards

sschuberth commented 1 week ago

Do you have any idea when you'll fix the usage of jdk21 for gradle and sbt project ?

@fb33 for Gradle it was basically fixed by https://github.com/oss-review-toolkit/ort/pull/9127, for SBT it will be fixed by https://github.com/oss-review-toolkit/ort/pull/9179. Both introduce package manager options to customize the JDK to use.

here is a sample of gradle project on jdk21 with the results&logs of ORT https://github.com/fb33/sample-gradle8.5-jdk21

Could you yourself give https://github.com/oss-review-toolkit/ort/pull/9179 a try on it?

fb33 commented 1 week ago

Hi @sschuberth

I have done some successful tests with ORT-32.1.0 ๐Ÿ‘

I don't know if I did it in the way you imagine, but here is what I done :

I built a special ORT docker image (with only tools for my stacks) in which I added open jdk 21. In the ort.yml, I indicate the javaHome here :

    packageManagers:
      GradleInspector:
        options:
          javaHome: /usr/lib/jvm/java-21-openjdk-amd64

I override javaHome (the default one - 17, or the jdk21) on the fly according to the stack of projects being audited.

sschuberth commented 1 week ago

I override javaHome (the default one - 17, or the jdk21) on the fly according to the stack of projects being audited.

Yes, that's a perfectly valid way to do it. If you can limit the number of required JDKs beforehand, you can add them to the Docker image and just configure the right Java home per ORT run. Alternatively, if you don't know which JDK will be required, you can let ORT bootstrap a JDK at runtime that matches the javaVersion option. If both javaHome and javaVersion are given, javaVersion takes precedence.

fb33 commented 1 week ago

Great ! I'll try the bootstrap method. thanks for the advice !

and good job for this new feature ! ๐Ÿ‘