15 ms·
Java Development on an Apple M1 – A One Year Review
- i386 5y agoShould be retitled s/Java/Docker/
- Nursie 5y agoI bought an Air about a year ago too. I had similar issues early on with testcontainers but once that was resolved, developing Java on the M1 has been a breeze.
- m_st 5y agoI love my MBA M1. It's the best computer I ever owned. Super fast for the kind of stuff I need it for. The battery seems to be always charged and it is immediately available when opening the lid. And it doesn't even have a fan. Best Mac ever.
- murrayhenson 5y agoI just bought an MBA M1 with 16 GB of RAM. I had to check to make sure that it was actually going into sleep mode because the system seems to instantly turn on and unlock when coming out of sleep mode. It's also cold most of the time; it takes ages to get up to what feels like "room temperature". I'm besmitten.
- vbezhenar 5y agoMy issue is that our company uses Gitlab for CI builds and Gitlab doesn't have ARM runners. And I'm the only guy with Macbook, so using some Mac Mini for Gitlab CI runner is not possible. I'm rebuilding images for myself that I'm currently working on, but that's tedious and not very productive spending of time. Another alternative that I'm currently considering is to rent some VPS in my city and use it as docker host. I'll be dependant on the Internet, so that's not very nice, but might be an option to consider. I wish Apple would extend Rosetta to VM support. That's really missing piece of puzzle when it comes to migrating to ARM. qemu is not good enough.
- easton 5y agoIf you have a AWS (or Oracle Cloud has it too) presence, they have ARM VMs you can get. You could probably self-host a build agent on one of those to do your ARM builds.
- mindwok 5y agoGitlab has ARM binaries for Gitlab runner. I can’t speak for the shared runners you get access to on Gitlab.com but you could always run your own runner and connect it to your Gitlab.
- nkristoffersen 5y agoWe are running gitlab-runner on an M1 Mac Mini now for iOS builds. Runs fine, was a little complicated getting React Native/Fastlane to compile the app but eventually got it running and is creating new builds almost every day. And we are using the Scaleway M1 machine so we can easily do remote management.
- random_kris 5y agoCheckout gitpod. This is my usecase for using them
- dindresto 5y agoYou don't need an ARM runner to produce ARM images. Docker buildx supports building for more than one architecture through qemu: https://github.com/microsoft/azure-pipelines-tasks/issues/12035#issuecomment-572144194 https://github.com/microsoft/azure-pipelines-tasks/issues/12...
- qwertox 5y agoI thought building an ARM64 docker image with qemu on a Ryzen 9590X would be a good way to offload building docker images from my Raspberry Pi 4. My benchmarks in building an ARM64 Nginx image was the following: Ryzen 9590X: 20:09 (20 min 9 sec) Raspberry Pi 3: 15:46 Raspberry Pi 4 8GB: 4:34 That settled it for me.
- 5y ago
- jurmous 5y agoI got the MacBook Pro M1 16GB when it was launched in November 2020. I was losing my previous provided laptop by leaving my previous job and needed to buy one to join a startup program. It was a big gamble but I am the kind of early adopter guy that did not want to miss out on this new CPU fun. It meant for me that in the beginning IDEs, Java and things like node ran all in Rosetta mode and were very slow. I was almost starting to regret my choice. Sometimes there were Arm fixes committed for things like NodeJS but they were not yet released so I needed to build my own version. Same issues with the JVM to find something able to run smoothly. (Felt that the slowdown was extra painful for JIT like languages) Also for Docker it meant waiting for some months to have something that would work properly but luckily I could manage without at the start. I was happy to see that major blockages improved in some months and for some lagging dependencies I was pushing some fixes myself. At this moment almost 1.5 years later everything works smoothly. The IDE, Java, Node etc. I still had to navigate around some specific dependencies but the fully native M1 development flow is so smooth compared to my previous Intel MacBook. I am quite happy.
- m_st 5y agoYou wrote "and were very slow". And is it faster now? Asking because Rosetta seems to be very fast.
- pilif 5y agoRosetta is fast unless any kind of JITed code is involved. A lot of Java development is happening with tools written in Java for the JVM which is relying a lot on JIT compilation. The JetBrains IDEs were bordering unusable under Rosetta. They would speed up over time as Rosetta did its work, but it was multiple tens of minutes of slow as molasses until things got better and after each IDE restart you were back at square one. Thankfully, JetBrains released updates to their products to run on a bundled ARM JVM very quickly
- jurmous 5y agoVery true! I received my MacBook on November 23rd 2020 and Jetbrains released an ARM optimised version of IntelliJ December 30th 2020. I may have used an EAP version some days/few weeks before release. https://blog.jetbrains.com/idea/2020/12/intellij-idea-2020-3-1/ https://blog.jetbrains.com/idea/2020/12/intellij-idea-2020-3... I remember that first month as being very painful to use the IDE. It was really dramatically slow.
- voyager1 5y agoProtip if you have good internet and don't want to configure everything locally: Jetbrains Gateway [1]. At the last company we had Docker, Java 8, Wildfly 10, Gradle 4 and I didn't manage to make it run locally on M1. I was pleasently surprised with how smooth it was to connect to Ubuntu VM with Jetbrains Gateway. You use native Jetbrains app on your computer (Intellij Idea in my case), but everything is executed and compiled on the remote machine (Ubuntu VM). Another huge upside is that Docker is running on Ubuntu, which is a lot faster than on OSX. Downside is that your are dependant on the Internet ofcourse. Officially the product is still in Beta, but it worked good enough for me. [1] https://www.jetbrains.com/remote-development/gateway/ https://www.jetbrains.com/remote-development/gateway/
- matsemann 5y agoAh, very cool. For java dev I haven't yet felt the need to containerize anything, normally mvn clean install works and does everything needed. But for Python I've used remote interpreters through docker in PyCharm lately (since getting a python env installed with wheels & stuff properly is sometimes almost impossible). VSCode have had some more luck with their frontend/backend architecture making it easier to pull off, glad to see jetbrains is on the move, as I prefer them.
- eropple 5y agoYMMV, but I've had very good luck just using asdf for...pretty much everything, Python included. In a normal week I'll probably touch half a dozen environments--Node, PHP, Python, Java, Ruby, Golang, maybe sometimes dotnet-core--and asdf not only Just Works for me, but has done so without thinking about it for going on three years or so, when stuff like rvm/rbenv changed rapidly enough as to necessitate changing it up to stay on the same page as my teammates. No relation, just a super happy user.
- matsemann 5y agoOur experience is gcloud and some other commands get messed up :/ Probably not asdf's fault, though. I've had multiple issues with gcloud not being compatible with my setup, spamming errors like /tmp/_MEIRZ3igG/libssl.so.1.1 But what asdf doesn't solve, though, is the setup for new devs. Python projects can sometimes take days to get running properly on a machine because of various differences, asdf solves some of it but replaces it with other installation steps instead. That's what I like about a dockerized setup, if it works one place it works for everyone (almost, nix is probably better).
- andybak 5y agoThe promise of Docker was "develop on the same configuration you deploy on". Is swapping Intel for Arm64 transparent enough to preserve the peace of mind back-end developers need, here? Maybe with Java the answer is yes, but how about non-java environments?
- keyle 5y agoTransparent here... No Java though.
- coder543 5y agoDocker's promise was never about processor architecture. In most cases, I would say developers have been working with Docker locally on a different processor architecture than what they deploy to in production. Their local machine might not have AVX-512 instructions, but the production machine might... or any number of the small variations of AMD64 that exist. If you're not careful, you can end up compiling binaries that work on your machine, but don't work in production, all on AMD64. These days, Docker supports multiarch images, so it's fairly trivial to build one image that supports with AMD64 and ARM64 transparently. CI tools like CircleCI support runners for AMD64 and ARM64, so you can even run your test suite on both architectures for additional confidence, if needed. For me, Docker containers have always been about reproducibility of builds (which some people will argue about, but it does a good job 99% of the time) and consistency in deployment. You don't need to have an artisanal deployment methodology for each application... you just need to have a way to deploy docker containers. Even for single static binaries like Go projects often produce, wrapping them in a docker container just makes it easier to abstract away the deployment problems across projects. For more difficult to deploy languages like Python, you get similar benefits to having a single static binary by wrapping all the dependencies up into a neat little container. Plus, once you have a standard unit of deployment like a docker container, you gain access to the broader ecosystem of container tools with minimal effort, such as running each container within a Firecracker microVM if you need isolation.
- simongray 5y agoThanks for saying what needs to be said. I can't stand the greybeards arguing about Docker whenever it's mentioned.
- danw1979 5y ago> All other development tools that we use on a daily basis either provide an arm64 build or the emulated x64 version works fine: IntelliJ IDEA, Visual Studio Code, Slack, Notion, Docker for Mac, Spotify, Firefox, Microsoft Teams, Postman. I had a little chuckle at Spotify being in the list of developer tools. I feel the same. No techno, no code.
- rieckpil 5y agoNo good code was ever written while not listening to music :D
- saurik 5y agoI mean, the study I remember (from when I was in some class 20 years ago or something, where we would have analyzed this sort of paper) showed that developers listening to music 1) completed the tasks at the same rate as the developers who were not listening to music, 2) reported the task being less boring than the developers who were not listening to music, and... 3) were much much less likely to notice that the code they had been asked to write was an elaborate maze of math that could be replaced with "return 0"; I thereby only listen to music while coding when I need to keep my morale up typing something I already pre-planned myself.
- danw1979 5y agoYeah I believe that could be true for the wider population, but the empirical evidence from my personal study into this shows that I’m completely incapable of any kind of extended concentration without entraining my neurons with repetitive beats. n = 1.
- saimiam 5y agoSomewhat matches my experience as well. I can listen to music while coding only up to a point after which flow states takes over and I need to quiet.
- 5y ago
- cedricziel 5y agoI'm a bit surprised nobody mentions the `--platform` argument that docker accepts to emulate a different architecture per container. It's a very smooth experience if you're reliant on 3rd party images. Available through compose as well.
- spyremeown 5y agoI worked with cross-compiling containers. The compiling times were... bad. Our x86 build took like, two minutes (this was a very small and lean C++ application). The arm32v7 ones took upwards of 30 minutes.
- the_svd_doctor 5y agoSame experience. Beefy machine, takes 45 minutes to compile cmake using a ppc64le container on an x86_64 host.
- heffer 5y agoWorks the other way around as well: Compile platform independent code (such as Java) on --platform=$BUILDPLATFORM in a build stage and then copy into containers that are --platform=$TARGETPLATFORM. That way your build only runs once, natively, but you can produce the correct runtime containers for each architecture rather quickly.
- fancyfredbot 5y agoWas nobody else surprised that this article about Java development focuses so much on CPU architectures? I realize it's mostly talking about testing infrastructure rather than Java code but it feels sad that we end up here - I remember Java's top selling point being "write once run anywhere" and I genuinely believed the JVM would shield you from most issues with CPU architectures. But it seems like they managed to sneak back in through the back door.
- pearjuice 5y ago95% of the article is about getting Docker to run properly on M1 - not Java. The JVM works fine.
- jurmous 5y agoIt seems that quite some dependencies like for networking, databases etc use natively build code internally using JNI. If those new targets like Mac arm64 are not added, those dependencies don't load. I can remember for example the Google Protobuf JVM package which uses the C++ written Protobuf library internally. It took quite some time before people inside Google had M1 machines and were building the JVM library too for M1. It seems that those CPU architectures indeed sneak back through a back door... The same on Android, there you have also many libraries which need to be build and published for specific architectures. But luckily new architectures are not added regularly.
- pulse7 5y agoYet another Java criticism here on HN? For every new supported CPU architecture you need time for "things to stabilize"...
- rvz 5y agoJudging from the comments here and the article, it reads to me that perhaps staying on Intel Macs, waiting for the developer ecosystem to catch up and skipping the early M1 models (November 2020) was a very smart decision to make rather than spending months fighting with your tools. Unless you want to wait 6 months or even a year to do any work reliably without these 'issues'. Even by then a more faster machine would be worth buying anyway.
- foobarbaz33 5y agoAgree, waiting has paid off for late M1 adopters. The software ecosystem has smoothed out most of the hiccups. And now there is the mac studio, M1 ultra, 128GB ram, 64 cores. An absolute beast of a machine. Fits in a backpack, so it's just as portable as a laptop assuming you work from docking stations anyway.
- lowbloodsugar 5y agoI have an M1 Max, with only 64GB and only 10 cores (the 64 cores in the Ultra are GPU cores, not CPU cores). For a software developer, it is probably fast enough, and I can use it anywhere. I build Rust, and build times aren't a problem. Certainly better than my i9 Intel MBP.
- jlengrand 5y agoOne thing that I haven't seen mentioned in the article, which I find a great news is that GraalVM support is also finally coming any time now : https://twitter.com/alina_yurenko/status/1506192755235696644 https://twitter.com/alina_yurenko/status/1506192755235696644
- pjmlp 5y agoHere is the thing, maybe you don't need Docker to use Java, which was invented exactly to abstract the underlying OS and CPU architecture (and isn't the only one at that game). Even worse, given that Docker and Kubernetes basically take Java/.NET application servers to other programming languages. Talk about fitting square pegs into round holes.
- vbezhenar 5y agoYou don’t “need” docker at all. But it makes things easier. You can build any application as a self-contained executable or directory with executable and related files. But it turned out it was not enough.
- pjmlp 5y agoIn 99% of the cases a EAR file + JDBC connection is enough.
- sixbrx 5y agoThat leaves the whole setup of the application server that the EAR file needs out of the picture though. That stuff is not specified declaritively anywhere in the EAR, so it's just a wildcard that can make your application work or not work depending on version and configuration.
- smrtinsert 5y agoAre you trolling? The last time I heard EAR files mentioned was 10 years ago.
- pjmlp 5y agoApparently those advocating stuff like Docker for OS agnostic languages never saw them in first place, probably busy in kindergarten and now pushing for Docker + WASM instead, 10 years later.
- 5y ago
- layer8 5y agoThe article is more about docker than about Java.
- tytrdev 5y agoJava for old folks I guess their abacus broke This is a haiku
- Koshkin 5y agoToo funny, this. (I still consider Java, and Javascript along with it, a new kid on the block. The language is still evolving at a rapid pace - unlike C, for example - with the kinks still being worked out.)
- vincent-manis 5y agoYes. I am considering moving from Fortran II to Fortran IV. Don't want to be rushed about making a decision, though.
- AtlasBarfed 5y agoThe Big JS Lie We Fixed it in this release Worse Worse Is Better
- tytrdev 5y agoOld one reads poem They're angry, a lack of Ken Clicks downward arrow
- exabrial 5y agoJust want to say thanks for writing this up!
- MandieD 5y agoOr you could run your containers on BlueMix… Tasteless jokes aside, great seeing you writing useful stuff for the world in your post “large, Franconia-based manufacturer” life!
- morpheuskafka 5y agoI remember last fall (when I got an M1 MBP for the first time, but the chip itself had been out for a year and sold through the school's laptop program) in a CS class I was the only one who could figure out how to make the JavaFX assignments work on M1. They would all load the GUI okay but crash as soon as anything was clicked. The error message was from the native JDK code, so was not very useful, I just gave up and searched the bug tracker for "M1" until I found something that looked close. IIRC it was some weird error caused by code that was objectively wrong for several years, but the race/error condition had never been observed on an Intel machine, if I remember correctly. Thankfully it was in an EA build of OpenJDK, otherwise I probably would have given up and thrown up a VM in the cloud to run it in.
- nick_ 5y agoI suspect a huge number of these kinds of bugs exist in production software, and will be brought to light by the "weak"(er) memory model of aarch64.
- dlivingston 5y agoI'm curious, can you expand on aarch64's 'weaker memory model'?
- CaliforniaKarl 5y agoHere’s the info directly from ARM: https://developer.arm.com/documentation/den0024/a/Memory-Ordering https://developer.arm.com/documentation/den0024/a/Memory-Ord... And here’s a post talking about it in the context of C++11: https://www.arangodb.com/2021/02/cpp-memory-model-migrating-from-x86-to-arm/ https://www.arangodb.com/2021/02/cpp-memory-model-migrating-...
- nick_ 5y agoThere is more nuance to it than this, but basically in x86 all memory writes are available to all cores via main memory, whereas with aarch64 they do not. On x86, a write by core A to memory will be available to core B if core B reads from main memory. On aarch64, a write by core A will not immediately get published to main memory (will likely stay in cache (L1, L2, etc.), so even if core B tries to read from main memory it won't see the value from core A. Ultimately aarch64's "weak"(er) memory model is more efficient as the programmer/compiler can make more efficient memory accesses. This results in fewer cache invalidations between cores. The problem in practice is that tons of production code has been written which assumes the x86 memory model. It may also just be a concurrency bug which doesn't manifest on x86 but does on aarch64 like in the post. Again, this is a simplification of what happens but I think it illustrates the difference to some degree.
- mark_l_watson 5y agoUseful article, thanks for writing it. I have had an M1 MacBook Pro for over a year and it did take extra work building SBCL Common Lisp from scratch, setting up brew for M1 architecture, and experimenting what would work for me on Docker. M1 Macs are awesome, I love mine, but I understand devs who want to stick with Intel. One of the reasons M1 is easy for me is that I do a lot of dev using mosh/ssh, tmux, Emacs on Intel VPSs.
- lowbloodsugar 5y agoTLDR: 90% of article was docker issues. Java works fine. Some deps use JNA (native code) and (surprise) you need the right arch for them.
- smrtinsert 5y agoI've been enjoying my 2020 m1 as my local node, spring boot and some jupyter playground. It's a wonderful device. I've noticed there's a lot of momentum to supply m1 related fixes, for example, I think a kafka admin tool I was using just provided an update for it, so things are moving along. I think around next year I might considering asking for an m1 upgrade for my aging mbpro.
- jwr 5y agoAs a Clojure developer, I'm very grateful for this information. Thank you! My development environment is OpenJDK plus a bunch of Docker containers (I use Docker extensively to contain/freeze various dumpster fires like projects that use npm and thus restore sanity to long-term development). I'm still afraid to make the jump to M1.