Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Platform Shaded Jars #881

Open
solonovamax opened this issue Nov 19, 2024 · 9 comments
Open

Create Platform Shaded Jars #881

solonovamax opened this issue Nov 19, 2024 · 9 comments

Comments

@solonovamax
Copy link

Create Platform Shaded Jars

It would be nice if you could create a platform-dependent shaded jar, to avoid needing to download javafx for the platforms you're not on.
This will substantially decrease the size of the resulting jar.

Here's a project I made which does this:
https://github.com/PolyhedralDev/BiomeTool/

the TL;DR of what I did is, I added 3 new configurations:

  • linuxImplementation
  • windowsImplementation
  • osxImplementation

then, I just loop through all the javafx modules I want to add and add the specific platform version of each one:

for (javafxModule in javafxModules) {
    val mavenCoordinates = "org.openjfx:javafx-$javafxModule:${javafx.version}"

    linuxImplementation("$mavenCoordinates:linux")
    windowsImplementation("$mavenCoordinates:win")
    osxImplementation("$mavenCoordinates:mac")
}

and lastly you just need a shadow task for each one:

val shadowJarLinux by tasks.creating(ShadowJar::class) {
    archiveClassifier.set("linux")
    configurations = listOf(linuxImplementation)
}

val shadowJarWin by tasks.creating(ShadowJar::class) {
    archiveClassifier.set("win")
    configurations = listOf(windowsImplementation)
}

val shadowJarOSX by tasks.creating(ShadowJar::class) {
    archiveClassifier.set("osx")
    configurations = listOf(osxImplementation)
}

val shadowJarAll by tasks.creating(ShadowJar::class) {
    archiveClassifier.set("all")
    configurations = listOf(linuxImplementation, windowsImplementation, osxImplementation)
}

you can check out the buildscript for all the other stuff it does

@Amejonah1200
Copy link
Contributor

Java's "build once, run everywhere" in shambles.

@solonovamax
Copy link
Author

solonovamax commented Nov 19, 2024

Java's "build once, run everywhere" in shambles.

it cuts the jar size by quite a bit iirc

@Amejonah1200
Copy link
Contributor

Amejonah1200 commented Nov 20, 2024

But aren't JavaFX dependencies downloaded for the platform later on anyway? Using the launcher and even back then in 2x/3x versions.

@Col-E
Copy link
Owner

Col-E commented Nov 20, 2024

For context, the current plan is to provide the base jar with no JavaFX and either:

  1. Let technical users like the Linux people grab those and figure out a launch mechanism they like.
    • I have seen several requests to distribute Recaf in varying forms, with varying launch behaviors so giving out a bare minimum template seems like the way to satisfy these populations
    • There is no built in updater, no requests to the Github API, etc. Its ideal for strictly offline use where even small requests make people put on tinfoil hats.
  2. Let non-technical users have a launcher which grabs the right stuff for them any ideally keeps them up-to-date.
    • Because we can now launch Recaf from a separate process, we can have more control over environment problems that end-users may have. We also can have FX updates for things like platform bugs come independently of Recaf releases
  3. This approach is dead simple for CI

It would be nice if you could create a platform-dependent shaded jar, to avoid needing to download javafx for the platforms you're not on. This will substantially decrease the size of the resulting jar.

I don't follow this logic. FX is not in the jar, so why would platform-shading lower the size? The resulting jar would be bigger because it has shaded content in it, right?

Java's "build once, run everywhere" in shambles.

I'm still salty that the JavaFX artifacts have native library path conflicts between platform classified artifacts.... LWJGL figured this out ages ago. If it weren't for that, a single fat-jar could work. You can still fat-jar now, but you'll have a build that wont link to certain supported systems just because of this shading problem.

@solonovamax
Copy link
Author

For context, the current plan is to provide the base jar with no JavaFX and either:

  1. Let technical users like the Linux people grab those and figure out a launch mechanism they like.
    • I have seen several requests to distribute Recaf in varying forms, with varying launch behaviors so giving out a bare minimum template seems like the way to satisfy these populations
    • There is no built in updater, no requests to the Github API, etc. Its ideal for strictly offline use where even small requests make people put on tinfoil hats.

if that's the goal, then maybe add like a --no-launcher flag which bypasses the other stuff, as well as a jar which includes javafx stuff

It would be nice if you could create a platform-dependent shaded jar, to avoid needing to download javafx for the platforms you're not on. This will substantially decrease the size of the resulting jar.

I don't follow this logic. FX is not in the jar, so why would platform-shading lower the size? The resulting jar would be bigger because it has shaded content in it, right?

it's not? because the jar I have from the AUR includes javafx, though I'm a few versions out of date.
I was under the impression that it was shaded. though I could be wrong.

Java's "build once, run everywhere" in shambles.

I'm still salty that the JavaFX artifacts have native library path conflicts between platform classified artifacts.... LWJGL figured this out ages ago. If it weren't for that, a single fat-jar could work. You can still fat-jar now, but you'll have a build that wont link to certain supported systems just because of this shading problem.

afaik you can build it in a way that works for all platforms?
the project I linked produces a -all jar which supports all platforms. albeit, I haven't tested it on every platform, but it does launch. and iirc windows users have had it launch successfully. unsure about macos users.

@solonovamax
Copy link
Author

solonovamax commented Nov 20, 2024

But aren't JavaFX dependencies downloaded for the platform later on anyway? Using the launcher and even back then in 2x/3x versions.

huh, they are?

I had a friend who downloaded the latest jar from CI, and got this error:

java.lang.ClassNotFoundException: com.sun.javafx.runtime.VersionInfo

though, this class did exist in the jar of the version I built from the AUR -git package, so dunno. (but, again, many commits out of date)

@Amejonah1200
Copy link
Contributor

Amejonah1200 commented Nov 21, 2024

Does AUR package even use 4.x version? Likely not. If the version is 2.x, then it is EoL.
(Notice: AUR package is not maintained by Col-E)

@Col-E
Copy link
Owner

Col-E commented Nov 21, 2024

if that's the goal, then maybe add like a --no-launcher flag which bypasses the other stuff, as well as a jar which includes javafx stuff

The launcher is separate. Here we only publish the jar without FX and either you use the launcher (targeting end users) figure it out for you, or you know how to use your environment tools to put FX on the path when you run Recaf yourself (linux and AUR maintainers)

it's not? because the jar I have from the AUR includes javafx

I don't maintain the AUR release

afaik you can build it in a way that works for all platforms?

No, let me illustrate the point again with this graphic

pic

@solonovamax
Copy link
Author

Does AUR package even use 4.x version? Likely not. If the version is 2.x, then it is EoL.
(Notice: AUR package is not maintained by Col-E)

I'm using the -git version which is on the latest 5.x versions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants