Year After Switching from Java to Go: Our Experiences

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

InfluxDB high-performance time series database
Collect, organize, and act on massive volumes of high-resolution data to power real-time intelligent systems.
influxdata.com
featured
CodeRabbit: AI Code Reviews for Developers
Revolutionize your code reviews with AI. CodeRabbit offers PR summaries, code walkthroughs, 1-click suggestions, and AST-based analysis. Boost productivity and code quality across all major languages with each PR.
coderabbit.ai
featured
  1. fx

    A dependency injection based application framework for Go. (by uber-go)

    it's really weird to see a "Dependency Injection & Context" section as if Golang's context has anything at all to do with DI.

    in particular, reading between the lines here:

    > But there are obviously work around solutions in the Go ecosystem. It uses the Context ctx, which we pass around functions in order to juggle data around in the application.

    suggests to me that they've implemented one of the Golang anti-patterns that I find most annoying - overloading the context and using it as "grab bag of pseudo-global variables"

    in this anti-pattern, you have an HTTP request handler, and want to make a database query, so you need access to the database connection pool. having a global variable for the connection pool feels wrong...so what many people do instead is call context.WithValue in their server startup code to put the connection pool into the grab bag, and then in the request handler call ctx.Value to pull the connection pool out of the grab bag.

    the Golang docs [0] explicitly say not to do this:

    > Use context Values only for request-scoped data

    the much better way, in my experience, is to make the request handler a method on a struct, and then the struct holds references to things like the connection pool. this can also be done with closures and captured variables, of course, but that tends to get unwieldy for non-trivial usage.

    if you do this, then your "dependency injection" in Golang tends to look pretty much identical to how it would look in Java, if you wired everything up by hand rather than using a framework/library. and then if you want, you can use a library such as Fx [1] for automatic Dependency Injection along the lines of Spring Boot.

    0: https://pkg.go.dev/context#WithValue

    1: https://github.com/uber-go/fx

  2. InfluxDB

    InfluxDB high-performance time series database. Collect, organize, and act on massive volumes of high-resolution data to power real-time intelligent systems.

    InfluxDB logo
  3. automemlimit

    Automatically set GOMEMLIMIT to match Linux cgroups(7) memory limit.

    > ...includes support for a soft memory limit. This memory limit includes the Go heap and all other memory managed by the runtime, and excludes external memory sources such as mappings of the binary itself, memory managed in other languages, and memory held by the operating system on behalf of the Go program"

    Of course it’s a runtime setting, it won’t affect other factors but you can’t say it didn’t solved anything “because there’s a GitHub issue open” Then Go runtime was unpredictable because of its ideology “CPU is unlimited but not Memory” and containers are kinda of a dynamic resource allocated but it did solve vast amount of problem dealing with kernel OOM and unpredictable GC cycles

    > You still need to use a helper library like https://github.com/KimMachineGun/automemlimit or https://github.com/uber-go/automaxprocs.

    I would be surprised if the Go team implemented into the runtime, because some devs would love to have there own way of handling such settings so I don’t see it as an issue

    > Forgot to add: The JVM does this for you since JDK 17 https://developers.redhat.com/articles/2022/04/19/java-17-wh...

    We can’t just compare added features if don’t compare how backwards compatible the language is at that time I don’t know much about Java, but I wouldn’t say the same from upgrading from Go 1.9 to Go 1.19

  4. automaxprocs

    Automatically set GOMAXPROCS to match Linux container CPU quota.

    > ...includes support for a soft memory limit. This memory limit includes the Go heap and all other memory managed by the runtime, and excludes external memory sources such as mappings of the binary itself, memory managed in other languages, and memory held by the operating system on behalf of the Go program"

    Of course it’s a runtime setting, it won’t affect other factors but you can’t say it didn’t solved anything “because there’s a GitHub issue open” Then Go runtime was unpredictable because of its ideology “CPU is unlimited but not Memory” and containers are kinda of a dynamic resource allocated but it did solve vast amount of problem dealing with kernel OOM and unpredictable GC cycles

    > You still need to use a helper library like https://github.com/KimMachineGun/automemlimit or https://github.com/uber-go/automaxprocs.

    I would be surprised if the Go team implemented into the runtime, because some devs would love to have there own way of handling such settings so I don’t see it as an issue

    > Forgot to add: The JVM does this for you since JDK 17 https://developers.redhat.com/articles/2022/04/19/java-17-wh...

    We can’t just compare added features if don’t compare how backwards compatible the language is at that time I don’t know much about Java, but I wouldn’t say the same from upgrading from Go 1.9 to Go 1.19

  5. tyred-java

    Typed Relational Database access in Java

    https://github.com/codr7/tyred-java/tree/main/src/codr7/tyre...

    24 of those files are under 100 lines - some of them are as small as three lines of code. and that's not a personal preference - that's mandated by Java that each type needs to be in its own file, ridiculous.

  6. fyne

    Cross platform GUI toolkit in Go inspired by Material Design

    >> Of course, Java still has its strengths, and for certain projects, it remains a solid choice. But for cloud-native applications, Kubernetes tooling, and our self-hostable software distribution platform, Go just feels like the right tool for the job.

    Yeah. I see Android app development is still mostly dominated by Java/Kotlin. Of course you can do it with Go, e.g: https://fyne.io/

  7. styleguide

    Style guides for Google-originated open-source projects

    I think the Google Go style guide is really nice and pragmatic. There are some references to the GoTips for some advanced subjects. I hope they release it someday.

    I made a PR for it: https://github.com/google/styleguide/issues/881

  8. Dagger2

    A fast dependency injector for Android and Java.

    Never really heard of Dagger before, but I love what I'm seeing: https://dagger.dev/

    On the other hand, using DI with Spring is both powerful and really annoying when things blow up due to unsatisfied dependencies, I'd much rather see that at compile time, so Dagger seems right up my alley! Thanks for mentioning it!

  9. CodeRabbit

    CodeRabbit: AI Code Reviews for Developers. Revolutionize your code reviews with AI. CodeRabbit offers PR summaries, code walkthroughs, 1-click suggestions, and AST-based analysis. Boost productivity and code quality across all major languages with each PR.

    CodeRabbit logo
  10. PIT

    State of the art mutation testing system for the JVM

    I think most of the tools on the second line are not highly applicable to a Kubernetes operator, or otherwise would just use the "Cloud Native way of doing things".

    Something like JRebel would generally be a big no-no for Kubernetes, where the container image of the operator is expected be immutable (at least in terms of the code running in there). It may or may not be okay for developing an operator, but that's certainly venturing into a bit of an unknown territory.

    VM agents and JMX are usually replaced by explicitly adding Open Telemetry support and/or a Prometheus endpoint. It's certainly more boilerplate and manual work, but so many more things are explicit in Go, that's just something you've got to buy into. If you're using Rust or Typescript this could be a lot more automated but that's not the case for Go.

    Advanced profiling is probably something you'd have to give up, but I doubt a Spring shop would be deeply into profiling. The low hanging fruit is to just throw away spring and get an immediate 200%-400% performance boost.

    But the JVM is still a more mature platform. Throughput is better on the JVM than on Go and some things are very troublesome in Go (basically anything that requires code generation).

    My personal "cool tool" that I can run on the JVM but doesn't have a mature equivalent in Go is PIT[1] for mutation testing. But not everybody will be using mutation testing, just like not everybody will be using JRebel or JMX. And it doesn't mean everybody should. If you're a Spring a shop the thing you'll be probably missing most in Go would be things like Dependency Injection, Java-like ORMs, reflection magic and Spring Configuration Server.

    [1] https://github.com/hcoles/pitest

  11. initializr

    A quickstart generator for Spring projects

    > In Java, people will pull in a 300MB+ mega-framework for a hello-world REST service. Oh and another 200MB for ORM. Another 250MB+ for nailpolish, etc.

    I just now used https://start.spring.io/ to generate a project using Spring web, Spring security and Spring data JPA (Hibernate).

    It generated a JAR that is 52MB.

  12. prime-mvc

    Prime MVC is a high performance Model View Controller framework built in Java.

    At $CURJOB, we have built a pretty good business on an app built in Java. We don't use Spring, but instead a lightweight MVC of our own creation[0]. It is open source but I don't know if anyone else is using it :) .

    I once asked the founders why they chose java; it was because it was 2015ish and they had an existing product in java and they knew it. Which makes sense to me. I think there's a lot of path dependence to language choice.

    I also think the domain matters. For database based webapps, Java can be great. Lots of tooling and knowledge around it. And modern java is pretty friendly to write. Plus, if you are interacting with something over an API and deploying it via a container, who really cares what it is written in?

    For kubernetes operators? Seems like a natural fit for golang. Anything kube really. I had a friend who ran a k8s consultancy for a while and said that they'd prototype stuff in python because it was easy, then implement in golang because that was what was consistent with the rest of the ecosystem.

    0: https://github.com/prime-framework/prime-mvc

  13. JHipster

    JHipster, much like Spring initializr, is a generator to create a boilerplate backend application, but also with an integrated front end implementation in React, Vue or Angular. In their own words, it "Is a development platform to quickly generate, develop, & deploy modern web applications & microservice architectures."

  14. Vaadin

    Vaadin 6, 7, 8 is a Java framework for modern Java web applications. (by vaadin)

  15. Spring Boot

    Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.

  16. Quarkus

    Quarkus: Supersonic Subatomic Java.

  17. Micronaut

    Micronaut Application Framework

  18. website

    Javalin website source code (by javalin)

  19. helidon

    Java libraries for writing microservices

  20. semver

    Work with Semantic Versions in Go (by Masterminds)

  21. bero

    Bero is a dependency injection container for PHP

    Dependency injection containers can be overly complex and allow complex configurations, too much magic.

    That is why I kept my container library simple, you read thru all the source in less than 15 minutes.

    What I like about it is that it is natural to use composition with classes, it encourages to create classes to divide your application into reusable parts.

    And with my library all you do is to put the dependent class in the constructor. My library can without much effort be replaced with normal factory, that is by design.

    Warning PHP https://github.com/paketphp/bero

  22. SaaSHub

    SaaSHub - Software Alternatives and Reviews. SaaSHub helps you find the best software and product alternatives

    SaaSHub logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts

  • The Tech Stack of a Cloud Computing Startup

    10 projects | dev.to | 28 Mar 2025
  • golang + sse + Data-Star for real time sys stats

    5 projects | dev.to | 24 Mar 2025
  • go-wait-for-it VS Wait4X - a user suggested alternative

    2 projects | 19 Mar 2025
  • Dependency Injection in Go: Comparing Wire, Dig, Fx & More

    5 projects | dev.to | 5 Feb 2025
  • Mastering Docker Image Management with GitHub Actions and Container Registries

    2 projects | dev.to | 27 Jan 2025

Did you know that Java is
the 8th most popular programming language
based on number of references?