3 ms·
From the outside it looks like an understandable shift away from desktop applications (the devs and money isn't there). I made an desktop app used Clojure + CLJ
by geokon 6y ago
From the outside it looks like an understandable shift away from desktop applications (the devs and money isn't there). I made an desktop app used Clojure + CLJFX and I got a ~25MB JAR. It then balloons to ~65MB jlinked packages. I ended up just releasing the JAR and telling people to install a Java 11 runtime (though I may revisit this at some point)
I think what it boils down to is that b/c of Java's reflections you simply can't get rid of unused code/dependencies and things constantly bloat very fast. Small apps that should be 2MB are >20MB and are "un-emailable". On the server side this is a nonissue but to me it makes the ecosystem unsuitable for user-facing applications. There is a reason you don't see people making lil JVM desktop applications anymore.
I love writing Clojure, writing the app with CLJFX was fantastic and fun but if I wanna make a quick app to crunch some data and make some plots I'm now very hesitant to reach for the JVM. I'm hoping with GraalVM the situation will change (b/c I don't think it supports reflections/RTTI and it can prune dead code/dependencies) but last I checked it didn't work with JavaFX.
PS: I manually pruned the dependencies in `deps.edn` with `:exclusions` which helped a lot. Otherwise the app is in the ~200MB range.. But it's a manual process and tedious. The toolchains can't guarantee which code is unused.
https://github.com/geokon-gh/corascope/blob/master/deps.edn https://github.com/geokon-gh/corascope/blob/master/deps.edn
- usrusr 6y agoAs a former servlet API guy switched over to android I'm getting good results using proguard for pruning unused dependency parts from an ancient desktop app I'm maintaining on the side. Surely a hit on build times and on sanity as well whenever you use a library that relies on reflection internally, but it completely changed the way I deal with the convenience/download size tradeoff when deciding on dependencies.
- geokon 6y agoYeah, it's not a bad idea. I did try proguard at one point.. but it's such a baroque tool. It's likely something I did wrong, but I never managed to get proguard to remove anything properly. Either nothing was removed or it'd remove too much and kill the program. It's been a while, but something about it gave me the impression it didn't play with Clojure I wonder if you can then jlink the result
- usrusr 6y agoBaroque it is. Clojure might be a death sentence for the proguard approach, considering how deeply the terms clojure and invokedynamic seem to be connected. But if you happen to depend on some deep library stacks only for some minor scraps of it's functionality it might still be worth it, define a blanket exception for your own code and, if not picked up automatically, for the few entry points where you call from clojure into the java world. If you don't mind keeping twice as much as strictly necessary, kicking out some low hanging fruits shouldn't be that hard. (but in combination with build times and future friction a division against proguard might still be very, very rational)
- geokon 6y agoRight, yeah. That was exactly the issue. Tons of garbage gets dragged in when you use a little corner of a huge library. And I'm mostly leaning on Java libraries. Yet it seems it somehow couldn't figure out which parts I was using and which I wasn't. I'll try to give it another shot eventually. Thanks for the tips :)
- thu2111 6y agoPeople generally can't email apps anyway though. Or do you mean you just feel a general sense that desktop apps should be a few megabytes in all cases? That is achievable when you depend heavily on the operating system to supply functionality, but is a lot harder to achieve when writing to portable toolkits. Bandwidth and disk space make this less of an issue these days though.