From 3cbcc86996fe018db6cff5efe6acce89ba704fb4 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Sat, 6 Apr 2024 06:07:29 +0900 Subject: [PATCH] Switch from Meson to Maven Maven is commonly used for Java packages; Meson is not. Also, Meson's Java support is incomplete and we've had to carry workarounds for adding entries to the JAR manifest. Historically the built artifact has been called openslide.jar. We're already renaming it to openslide-java-$version.jar in CI, and Maven prefers to include the version number in the JAR filename. For clarity and consistency, use Maven's defaults with a sensible artifactId, building the artifact as openslide-java-$version.jar. Allow Maven to add its usual additional metadata to the JAR, including a couple MANIFEST.MF properties and a complete copy of pom.xml. Document selecting the correct JDK version at build time, if needed. Maven does not necessarily run on the latest, or default, JDK on the system (e.g. Fedora pins it to an older LTS), so it may be necessary to explicitly set JAVA_HOME. We don't learn that our JDK is too old until we try to compile with it. The Maven toolchains mechanism could prevent this, but toolchains are not autodiscovered: they must be explicitly configured by the environment, which often does not do this. (In GitHub Actions, actions/setup-java does set up a toolchains file, but Fedora and Ubuntu do not.) If we declared a toolchain dependency, we would require the user to set up a toolchains file before building; it's easier to not do this, and fail at build time if Java is too old. Maven prints warnings unless pom.xml hardcodes version numbers for every plugin mentioned there. If version numbers are specified, Maven fetches and runs exactly those plugin versions, with no way to smoothly use the latest available version. Maven calls these version pins a "good practice", but really they're an antipattern that encourages continued reliance on old versions of build tooling, making the ecosystem more brittle. Mitigate as best we can: hardcode plugin versions to avoid the warning, then enable monthly Dependabot version updates so we don't retain pins to stale versions. Closes: https://github.com/openslide/openslide-java/issues/68 Signed-off-by: Benjamin Gilbert --- .github/ISSUE_TEMPLATE/release.md | 2 +- .github/dependabot.yml | 9 +++ .github/workflows/java.yaml | 22 +++--- .gitignore | 1 + README.md | 14 ++-- meson.build | 69 ------------------- meta/MANIFEST.MF.in | 5 -- pom.xml | 108 ++++++++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 93 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .gitignore delete mode 100644 meson.build delete mode 100644 meta/MANIFEST.MF.in create mode 100644 pom.xml diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md index 9b5677e..7465e1e 100644 --- a/.github/ISSUE_TEMPLATE/release.md +++ b/.github/ISSUE_TEMPLATE/release.md @@ -1,6 +1,6 @@ # OpenSlide Java release process -- [ ] Update `CHANGELOG.md` and version in `meson.build` +- [ ] Update `CHANGELOG.md` and version in `pom.xml` - [ ] Create and push signed tag - [ ] Verify that GitHub Actions created a [GitHub release](https://github.com/openslide/openslide-java/releases) with release notes and a JAR - [ ] Update website: `_data/releases.yaml`, `_includes/news.md` diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..be9e20a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + # Periodically check for Maven plugin updates + - package-ecosystem: maven + directory: / + schedule: + interval: monthly + commit-message: + prefix: maven diff --git a/.github/workflows/java.yaml b/.github/workflows/java.yaml index e9686a4..2a8f3a7 100644 --- a/.github/workflows/java.yaml +++ b/.github/workflows/java.yaml @@ -33,16 +33,15 @@ jobs: with: distribution: oracle java-version: 22 + cache: maven - name: Install dependencies (Linux) if: matrix.os == 'ubuntu-latest' run: | - sudo apt-get install libopenslide0 ninja-build - # Ubuntu 22.04 packages Meson 0.61 - pip install --user meson + sudo apt-get install libopenslide0 - name: Install dependencies (macOS) if: matrix.os == 'macos-14' run: | - brew install meson openslide + brew install openslide # allow smoke test to find OpenSlide echo "DYLD_LIBRARY_PATH=/opt/homebrew/lib" >> $GITHUB_ENV - name: Install dependencies (Windows) @@ -50,7 +49,6 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - pip install meson ninja mkdir -p "c:\\openslide" cd "c:\\openslide" release=$(gh release list -R openslide/openslide-bin -L 1 \ @@ -64,24 +62,20 @@ jobs: # allow smoke test to find OpenSlide echo "PATH=c:\\openslide\\${zipname}\\bin;$PATH" >> $GITHUB_ENV - name: Build - run: | - meson setup builddir - meson compile -C builddir + run: mvn -Dmaven.compiler.failOnWarning=true - name: Smoke test run: | - java --enable-native-access=ALL-UNNAMED -cp builddir/openslide.jar \ - org.openslide.TestCLI fixtures/small.svs + java --enable-native-access=ALL-UNNAMED \ + -cp target/openslide-java-*.jar org.openslide.TestCLI \ + fixtures/small.svs - name: Dist id: dist if: matrix.dist run: | - set -o pipefail dist="openslide-java-dist-$GITHUB_RUN_NUMBER-$(echo $GITHUB_SHA | cut -c-10)" echo "dist-base=$dist" >> $GITHUB_OUTPUT mkdir -p "artifacts/$dist" - version=$(meson introspect --projectinfo builddir | jq -r .version) - mv builddir/openslide.jar \ - "artifacts/${dist}/openslide-java-${version}.jar" + mv target/openslide-java-*.jar "artifacts/${dist}" - name: Archive dist if: matrix.dist uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/README.md b/README.md index 850af23..7327618 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is a Java binding to [OpenSlide](https://openslide.org/). ## Build requirements - JDK ≥ 22 -- Meson ≥ 0.62 +- Maven ## Runtime requirements @@ -19,11 +19,17 @@ This is a Java binding to [OpenSlide](https://openslide.org/). ## Building ``` -meson setup builddir -meson compile -C builddir +mvn ``` -The JAR will be in `builddir/openslide.jar`. +The JAR will be in `target/openslide-java-*.jar`. + +If you have multiple JVMs on your system, and Maven defaults to a version +older than 22, you might need to set `JAVA_HOME`. For exmaple, on Fedora: + +``` +JAVA_HOME=/usr/lib/jvm/java-22 mvn +``` ## License diff --git a/meson.build b/meson.build deleted file mode 100644 index 4c91882..0000000 --- a/meson.build +++ /dev/null @@ -1,69 +0,0 @@ -project( - 'openslide-java', - 'java', - default_options : [ - 'buildtype=debugoptimized', - ], - license : 'LGPL-2.1-only', - meson_version : '>=0.62', - version : '0.12.4', -) -# for FFM API -java_ver = '22' - -# Java setup -native_java_home = meson.get_external_property( - 'java_home', - '', - native : true -) -jar = find_program( - 'jar', - dirs : native_java_home != '' ? [native_java_home / 'bin'] : [], - native : true, -) - -# compiler options -add_project_arguments( - '-source', java_ver, - '-target', java_ver, - '-Xlint:all,-serial', - language : 'java', -) - -# jar -manifest_extra = configure_file( - input : 'meta/MANIFEST.MF.in', - output : 'MANIFEST.MF', - configuration : { - 'version': meson.project_version(), - } -) -built_jar = jar( - 'built', - [ - 'org/openslide/gui/Annotation.java', - 'org/openslide/gui/DefaultAnnotation.java', - 'org/openslide/gui/DefaultSelectionListModel.java', - 'org/openslide/gui/Demo.java', - 'org/openslide/gui/OpenSlideView.java', - 'org/openslide/gui/SelectionListModel.java', - 'org/openslide/AssociatedImage.java', - 'org/openslide/OpenSlideDisposedException.java', - 'org/openslide/OpenSlideFFM.java', - 'org/openslide/OpenSlide.java', - 'org/openslide/TestCLI.java', - ], - main_class : 'org.openslide.gui.Demo', -) -# https://github.com/mesonbuild/meson/issues/3070 -openslide_jar = custom_target( - capture : true, - command : [jar, '-um', manifest_extra], - feed : true, - input : built_jar, - install : true, - install_dir : get_option('datadir') / 'openslide-java', - install_tag : 'runtime', - output : 'openslide.jar', -) diff --git a/meta/MANIFEST.MF.in b/meta/MANIFEST.MF.in deleted file mode 100644 index 7ca3b03..0000000 --- a/meta/MANIFEST.MF.in +++ /dev/null @@ -1,5 +0,0 @@ -Implementation-Title: OpenSlide Java -Implementation-Vendor: OpenSlide project -Implementation-Version: @version@ -Enable-Native-Access: ALL-UNNAMED - diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9f2a163 --- /dev/null +++ b/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + 0.12.4 + + org.openslide + openslide-java + OpenSlide Java + Java interface to OpenSlide + https://openslide.org + 2007 + + OpenSlide project + https://openslide.org + + + + LGPL-2.1-only + https://raw.githubusercontent.com/openslide/openslide-java/main/COPYING.LESSER + repo + + + + + UTF-8 + 22 + 22 + + + + package + . + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + true + + -Xlint:all,-serial + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + true + org.openslide.gui.Demo + + + ALL-UNNAMED + + + + + + + + + https://openslide.org/download/#source + + + + scm:git:https://github.com/openslide/openslide-java + https://github.com/openslide/openslide-java + + + + GitHub + https://github.com/openslide/openslide-java/issues + + + + GitHub + https://github.com/openslide/openslide-java/actions + + + + + openslide-announce + https://lists.andrew.cmu.edu/mailman/listinfo/openslide-announce + https://lists.andrew.cmu.edu/mailman/listinfo/openslide-announce + https://lists.andrew.cmu.edu/pipermail/openslide-announce/ + + https://marc.info/?l=openslide-announce + + + + openslide-users + https://lists.andrew.cmu.edu/mailman/listinfo/openslide-users + https://lists.andrew.cmu.edu/mailman/listinfo/openslide-users + openslide-users@lists.andrew.cmu.edu + https://lists.andrew.cmu.edu/pipermail/openslide-users/ + + https://marc.info/?l=openslide-users + + + +