Fork me on GitHub
Mark Wardle16:02:28

Hi all. I need to switch between java versions and architectures on my new Macbook Pro. Most automated systems such as sdkman, jabba and jenv seem to support versions very easily, but don't make it clear about switching between architectures, simply displaying version names/numbers. This is an issue on an M1 chip which can run ARM natively or X86 using rosetta. I have some projects using native code that don't yet support ARM, so want to run using an x86 jvm for those, but switch back to ARM for those in pure java. Any suggestions or do I need to hack up something manually?


For sdkman you have to change a line in a config. You could write a shell script to sed replace it and it might appear seamless. I am in a similar boat and I want to understand how to properly do this myself and use “JAVA_HOME” but I've been unable to find actual documentation on how to manually configure a jvm

👍 1
Mark Wardle17:02:42

Thanks @dpsutton - I may just stay using an x86 jvm for the time being - as it is still very fast. To be fair, IntelliJ makes it quite easy on a per-project basis to choose jvm version, so I only mainly have the issue for running stuff from the terminal. But now with the clj command-line tooling, I do that quite a lot. But.... it would be nice to run at full speed :)


I’ve been using SDKMAN for years, and when I got my M1 MBP a year ago, it was a little tough sledding for a bit. For awhile, I was using the M1 JDK that IntelliJ shipped. 🙂 M1 support is very good now. I use the Azul JVM for M1, and the Graal JVM for x86, which I installed when I was experimenting with native-image builds. I use it every once in awhile for XTDB, which requires rocksdb, which only has x86 JNI bindings. In short, sdkman works well for switching between x86 and M1. I highly recommend using ARM JVM — startup time goes from 10s to less than a second, and execution speed seems at least 50% faster, and memory usage is lower, too.


I use 21.3.0.r17-grl for x86 and 17.0.2-zulu for ARM.


@U6VPZS1EK how do you switch between the two?


commands like sdk use java 17.0.2-zulu. Or in IntelliJ, Alt-;, and then select JDK in project. Super easy. You’ll know whether you’re running an ARM JVM, because it’ll be so fast, you’ll find it quite difficult to go back to x86 emulation. 🙂


(`sdk` is a bash function, not an executable, so you can’t run it in a makefile — you’ll have to use the JAVA_HOME suggestion, as @dpsutton mentioned. I haven’t done that yet, but it’s something I’ve meant to do.)


so you use sdkman to install the jvms and then manually switch between them?


yep! sdk list java, sdk install java ____, sdk use java ____. It puts them all in ~/.sdkman directory, packages them up, you can uninstall. Highly recommended!


i see. that’s helpful. So edit that config file to allow ARM jvms, install a few, and then switch back to the x86 version and you can see all of the installed jvms, both x86 and ARM?


Yep. I’d install 17.0.2-zulu, try it out, and dow what it takes the huge speedup. And then regret every time you have to go back to x86 version. 🙂

🙏 1

Very helpful. Thanks!


it should take you 10m — maybe 30m tops. Let me know how it goes!

🙏 1
Mark Wardle19:02:04

Thanks both. That's really helpful. When I looked at this, I found it difficult to remember which was x86 and which was arm - as you say, once lmdb and rocksdb support arm, this won't be such an issue. Thanks! PS. Love the books and your work @U6VPZS1EK

🙏 1

@U013CFKNP2R Funny — that’s why I’m using Graal, because I know it can’t be ARM. 😆 I wish java --version showed the architecture/instruction set — if you know how to display that info, do let me know!

👍 1
Mark Wardle19:03:52

Well I got some results from executing uname -p. that I didn't expect... presumably because the shell command is forked from an owning x86 process... Here is what is looks like from within a REPL running in a x86 JVM: ( "uname" "-p") => {:exit 0, :out "i386\n", :err ""} And this is what it looks like from my other java environment: mark@jupiter pc4-server % clj -e "(require '[]) ( \"uname\" \"-p\")" WARNING: Implicit use of clojure.main with options is deprecated, use -M {:exit 0, :out "arm\n", :err ""}

Mark Wardle19:03:21

I have a x86 jvm running via intellij so that is the REPL result. I have an ARM jvm as default in my terminal so that's the terminal result. I wonder if there is a way to do this without forking a shell?

Ben Sless18:02:49

This isn't really other language related, just a vent, how do people find Rust readable? 😕


By switching to it from C++ with boost, probably. :D

😆 1

Rust seems lovely to me. Especially the tooling when loaded up in vs code or some other tooling aware editor. The culture of documentation and the better tooling means it is quite discoverable compared to some c project with tons of pragmas and weird non standard tooling

👍 2
Ben Sless20:02:35

I find the information density is just too low to be able to construct a mental model of how data flows through the code


> I find the information density is just too low to be able to construct a mental model of how data flows through the code I agree, I don't find Rust readable / expressive at all. The same with Go, there is just too much code, that trying to "read" it, means running a fairly complicated interpreter in your head. Some people seem to find that works for them though! e.g. People at work find the attached Go "readable": It's just for loops and if statements, they can run through these 20 lines of code and figure it out. But the same time the same people will say the clojure is totally unreadable (they have to understand a bit of set theory):


This came up recently when we were deciding on what language to go forward with for upcoming work, and we chose Go because it's basically just for loops and if statements. It doesn't matter if you have to write 100s of lines of code to do simple things, people find those 100s of lines of code readable. It's just for loops and if statements! They've been using those structures all their career. They don't need or want to learn anything else (this is why we decided against Rust)

facepalm 1

Choosing anything other than Go was seen as having to big a learning curve, and a mixture of "if statements and for loops is all you need", and "people have no time to learn new stuff". Go ended up being the obvious choice. I think they've made a mistake, but no one listens to me

❤️ 1
Ben Sless05:02:14

This quote is eternally relevant: "you can teach someone LISP in a day, or three days if they know ALGOL"

Ben Sless06:02:16

It's also frustrating to have to work with types and not data

Ben Sless06:02:22

No generic operations


IDE helps a lot. There is some special syntax you need to get through through.

Ben Sless18:02:23

I have LSP hooked up to Emacs, didn't help much. Is it a reasonable expectation for a language to be unusable without a ide?


For some, yes. I've worked on c# project where it was about 5.5 million lines of code split over 400+ csproj files, and thousands of .cs files, navigating without an IDE would be just impossible.


Seems valid for Kotlin as well. Would be pretty hard with just a text editor.


It also depends on who's writing the code. I try to use modules much the same way as I would Clojure namespace. So have each abstraction layer in its own module. Only set public(crate) what other modules need.


Yeah, I mean if you want to refactor a class name or something and it's used in 500+ places, you really need to know you can just rename and let the ide update all the usage. Or you are using a class, want to know what it exposes and it's the class itsekf is 30k+ lines. You really need an IDE to show you what's callable when you press .

Ben Sless18:02:46

Reminds me of that Kevlin Henny talk. Operating systems have less lines than that. How come they do more with less?