JReleaser: quick and effortless way to release your project

(jreleaser.org)

113 points | by saikatsg 19 hours ago ago

28 comments

  • pitah1 an hour ago

    This looks really cool. I'm surprised I didn't find this before when I was searching for something like this. I've been using jpackage[1] for a while now but this seems like it would be easier for me to manage using JReleaser given there is support via Gradle.

    Would this be a simple lift and shift job to move to JReleaser (as it seems like it just uses jpackage behind the scenes)? With jpackage, if you want to create a Windows exe, it needs to be built on Windows. Similarly, build dmg on Mac and deb for Linux. Does Jreleaser also require this?

    [1] https://docs.oracle.com/en/java/javase/22/docs/specs/man/jpa...

  • nja 12 hours ago

    I just built a library on jReleaser!

    https://github.com/NJAldwin/maven-central-test

    I wanted to release a jvm lib on Maven Central -- which no longer requires opening a jira ticket for a new package! Instead, simple DNS TXT verification is all that's needed. However, the caveat is that it's the new Maven Central service, which doesn't have as much support in build tools as the older sonatype one. jReleaser is one of the few tools which supports it.

    So I hacked together a fully self-contained minimally reproducible example of a Gradle library, built and published in GitHub using jReleaser.

    There were several things that had me scratching my head with jReleaser, and the docs are strangely organized IMO (it comes from supporting so many facets, I believe), but it ended up working well enough!

    I ended up adding a doc build and some other stuff to the repo too. Now I have a full example that I can use to trivially publish new libraries (such as in-progress https://github.com/NJAldwin/ambient-consumer ).

    (Why Maven Central? Since the demise of jFrog/jCenter/BinTray, there's not been an easy way to widely publish jvm libraries. At work I've used GH packages, but that requires a GitHub login even for public packages, which is a significant barrier IME. JitPack is one option, but it does on-demand builds linked closely to the origin repo, whereas I wanted the classic immutable build published on release.)

  • gunnarmorling 16 hours ago

    Very nice to see JReleaser here on HN! I'm very happy with it, using it for publishing releases of kcctl (a command line client for Kafka Connect written in Java, compiled and published as native binaries for Linux/MacOS/Win via GraalVM). Here's the config, in case folks are looking for an example: https://github.com/kcctl/kcctl/blob/main/pom.xml#L430-L530. Releases are triggered by running a parameterized workflow (taking the version to be released) on GitHub Actions.

    A big shout-out to Andres Almiray, the maintainer of JReleaser, who has always been super-fast to answer any questions and help to sort out issues when I ran into them.

  • whartung 16 hours ago

    When I released my last Java project, I came out with a MacOS DMG, a Windows EXE installer, a Windows MSI installer, and a Fat Jar for Linux.

    Now we have MacOS ARM, MacOS x86, Linux ARM/x86, Windows ARM/x86.

    Even for a basic "cross platform" Java program (that bundles the JRE), that's 6 installs, which ostensibly need to be built on their respective platforms. Add on to that if you using something that includes a binary (like, say, SQLite, much less JavaFX which I work with).

    The release burden is, well, frankly, daunting for a small project.

    My honest thinking for my next project release is simply to tell folks to install the JDK, download the source code, and have them run:

      ./mvnw javafx:run.
    
    (Or they can run go.sh/go.bat which essentially does the same thing.)

    That'll download all of the stuff it needs including the Maven runtime and all of the libraries, as appropriate, build the project, and run it. It's Fast Enough (maybe it's awful on a small RPi, I dunno).

    When I get more than 5 downloads, folks can vote as to which installer to work on.

    Creating the executables was quite the black hole. I didn't create one for Linux because I honestly didn't know what packaging scheme to use.

    In theory, the CI infrastructure on GitHub will let you build on different platforms, yet another black hole of time to sink into.

    So, yea, at least initially, I think the maven wrapper will be my "release model". SHOULD be pretty simple.

    • aalmiray 8 hours ago

      This burden is what prompted me to create JReleaser in the first place as I also wanted to release a JavaFX application without instructing people to clone a repository and build the app themselves.

      Because JReleaser is a release tool and not a build tool you are free to build however it’s needed, collect all artifacts and release them. I do this for the Ikonli JavaFX browser: build the app with Gradle which bundles platform specific JARs, then release them with JReleaser.

      https://github.com/kordamp/ikonli Shows how it can be done. Requires building with GH Actions in multiple platforms.

    • koito17 16 hours ago

      Distributing a single uberjar, whenever possible, is generally a good idea IMO. One major reason I like the JVM as a platform is that I don't need to mess with containers or native images. To reduce burden of deployment, native images are out of the question. Thus the choices are "force user to have Java runtime installed" or "force user to have container runtime installed". Double-clicking a JAR file (or running "java -jar ...") tends to be easier than debugging Mac / Windows quirks with Docker.

      Presumably the major issue in distributing JavaFX applications (or most Java 9+ applications in general) is dealing with jlink. That leads to the problem in question: having to create N * M executable blobs, where N = # of operating systems and M = # of CPU architectures.

      • whartung 16 hours ago

        I absolutely agree on the JVM platform, an uber jar file is really quite easy to use and deploy.

        You don't need to do JLink for JavaFX. FX requires binary libraries, but you can make "platform specific" uber jars (and, probably, generic uber jars) that bundle correct libraries.

        SQLite bundles all of the platforms into a single jar file, for example.

        But that's another reason, at least for me, to look at the maven wrapper. Maven will "download the right thing" and not "burden" folks with copies of libraries they don't need. FX binaries can be quite big, particularly if you include WebKit (which I do simply for easy in app documentation, it's just a fat pig of a dependency though).

      • diggan 16 hours ago

        > Distributing a single uberjar, whenever possible, is generally a good idea IMO.

        Yeah, seems to work for games well enough. Ship uberjar + small wrapper shellscript for Linux/macOS, .bat for Windows. Should work everywhere*

    • JanisErdmanis 3 hours ago

      > The release burden is, well, frankly, daunting for a small project.

      With its large user base, I would have expected Java to have figured out all the details and offered users a single command-line tool that automatically builds the project into installers. I had adventures with relatable pain points when figuring out how to distribute Julia's GUI applications.

      Another upcoming difficulty is transitioning to distributing applications that run in the sandbox. Windows has MSIX, Linux has Snap and Flatpack, and macOS has DMGs signed with entitlements. Each has its way of configuring and how it is expected to work, and debugging sandboxing issues is no fun.

      I made an application bundler specifically for Julia's MSIX, Snap, and DMG applications, which allows the use of the underlying configuration files when configuring the sandbox via a simple recipe system. Unlikely one would change languages, but perhaps some inspiration can be taken from my project:

      https://github.com/PeaceFounder/AppBundler.jl

    • mike_hearn 4 hours ago

      I faced similar problems some years ago, and frankly even if you use Electron the tools aren't that great. So I made a new tool (Conveyor) along with a company (Hydraulic):

      https://hydraulic.dev/

      Conveyor is free to use for open source projects and works how you'd hope it works: it's a signup/account-free downloadable CLI tool. You run a single command from your dev laptop (or a cheap Linux CI worker) and it builds/signs all the packages for every target OS and CPU architecture in one go, uploads them, and integrates the app with a native auto update engine. Sparkle on macOS, MSIX on Windows, an apt repository for Debian/Ubuntu users. It'll even make a download HTML page for you that detects the user's platform and gives a big green download button.

      There's a bunch of sample apps showing how to integrate it into your {Electron,JavaFX,Compose for Desktop,native} app. "conveyor generate javafx my-sample-app" will spit out scaffolding that uses Gradle, and there's a Gradle plugin to import all the build info into Conveyor too. End result is you do:

          ./gradlew jar && conveyor make copied-site
      
      And a new version of your app is released, existing users will start to update. That's all there is to it. It'll use jlink, jdeps and so on to make an optimized bundled JVM for your app. The big remaining pain is still code signing - Conveyor understands all the signature formats and protocols natively and will handle all that, but you do need to buy certificates. If you don't it'll make self signed apps which can be distributed and used but which will require the user to bypass various warnings.
    • winrid 7 hours ago

      I create all those binaries automatically for my javafx project using GitHub actions, jlink, and jpackage, works well so far.

    • invalidname 13 hours ago

      Did you look at https://www.jdeploy.com/ ?

      • jeffreportmill1 12 minutes ago

        I'm a huge fan of JDeploy - deployment used to be my biggest headache. Now I just run 'jdeploy' in the command line, change the version in the UI app and hit the 'Publish' button.

        SnapCode: https://www.jdeploy.com/~snapcodejava

      • whartung 12 hours ago

        I did, but at the time it was touted more as a centralized service that I wasn’t really interested in. Maybe it’s better now.

        • shannah78 3 hours ago

          What do you mean be centralized service? It allows you to publish to GitHub releases or npm. Do you mean "central" like "GitHub"?

  • brunoluiz 18 hours ago

    Is it somehow related to GoReleaser? I saw GoReleaser supports multiple languages now as well

    • caarlos0 15 hours ago

      GoReleaser author here.

      I think jRelease was based on some of GoReleaser's ideas.

      GoReleaser just recently started adding support for more languages.

    • loginatnine 14 hours ago

      It's inspired by it. It's mentioned here[1].

      [1] https://jreleaser.org/guide/latest/index.html#_acknowledgmen...

    • ashishb 15 hours ago

      I love go-releaser. I believe it is a great choice for Go-based projects. I use it for multiple side-projects of mine (that are written in Go).

    • kbd 16 hours ago

      Had the same question, surprised it's not addressed in the faq.

      • aalmiray 8 hours ago

        JReleaser author here.

        Yes, GoReleaser served as an inspiration to get started with the tool. The guide does mention this connection. I can certainly add one more entry to the FAQ to make it easier to find.

        Regarding multi-language support, it’s available since day 1. Recently it became better https://andresalmiray.com/multi-language-support-in-jrelease...

  • buremba 15 hours ago

    Is there a doc for Python apps?

    • aalmiray 8 hours ago

      Technically it already works as long as your app is published to GH releases and/or the currently supported package managers.

      Support for explicit Python ecosystem tools and services (pypi, .whl files, etc) is forthcoming.

  • layer8 17 hours ago

    This doesn’t seem to address building installers, unfortunately.