Recently I have switched from using C# to Java at work. This is a move that bewilders some people. I’ve used .NET at work for over 6 years and a little more before that, so it’s understandable that going for something different after so much time raises eyebrows. In this short article I’ll try to explain my rationale behind doing so. I’ll also describe the process itself. Bear in mind that, given the topic, many things that you’ll read are my personal opinions or speculations.
The first question that comes to mind is why I did it. Why did I abandon the, arguably better and more modern, language for an older one that is known for it’s notoriously slow evolution pace? I’d say, that C# vs. Java was the last thing that I was concerned with. From my point of view, C# and Java are similar to the point of being almost interchangeable. When compared to truly different languages such as Haskell, Erlang or Lisp, the gap between C# and Java appears silly. There are three reasons to why I switched:
The first reason is simple – I want to have experience with more than one platform. JVM has the benefit of coming with a language very similar to C#. Thanks to that, I could focus more on the differences in the platform, tooling, mindset and so on. This means that I could relatively easy gain a very marketable skill, as Java is also one of the most popular languages on the planet. Add to that the host of other interesting JVM languages (Scala, Kotlin, Clojure, Frege etc.) and the fact that I could fairly easily transfer to a Java team and you’ll see why this decision was no-brainer for me.
The second reason is the OS that is used for the development and for runtime environments. This is a matter of personal taste – I prefer Linux to Windows and in my humble opinion Linux and it’s tooling are better suited for software development and operations. Of course, in the wake of .NET Core (and Mono before that) it’s more and more feasible to use Linux for .NET development and it was always possible to use Windows for Java, but let’s face it – the demarcation line between the OSes is well aligned with the technologies used.
The third reason is a social one – the community around .NET and JVM. I am under the impression that the community around JVM is more vibrant and produces/adopts more interesting things and tools than the .NET community. For some reason, that I could speculate on (but I won’t) the JVM community gives far more to the open source movement. This disparity will, in my opinion, diminish in the near future (thanks to the shift in MS strategy) and it seems that .NET should pick up the pace.
How did it go?
A switch from C# to Java (as in “the Java language”) is not the most dramatic thing in the world – as I’ve said, the languages resemble each other very much. Because of that, I won’t elaborate on the languages themselves.
On the other hand, going from .NET to Java SE (as in “the Java Platform”) and from CLR to JVM is a bigger step. As some things are bound to be similar, it is in fact a completely different set of APIs which is organised differently as well. Add to that the fact that I went from working on monoliths, to working with something going in the direction of a microservice architecture, so to the language and the platform themselves you also have to add the OS, the tools (e.g. Docker) and the inherent difficulties of distributed systems.
Let’s begin with the platforms and virtual machines. Sincerely, I doubt that I could make the switch if I didn’t use Java for my personal projects. I have made a decision to not use .NET at home, so I had different (albeit similar) skills up my sleeve and that’s something that I would give as an advice to anyone – while you’re at home, don’t use the language that you’re using at work. The only exception to this rule would be building something that is meant to earn you money, so you’d want to use something familiar, but isn’t that “work”? When playing or learning some other aspect of software development (e.g. algorithmics) use something new. In my case, it meant that I was already relatively comfortable with Java Platform when joining the team. Of course, I have to check something basic quite often, but I’m productive and in my book that’s a win.
Main challenges here? I suppose that would have to be the multitude of libraries/frameworks that do the same things and the set of Java APIs that try to harness some of the mess. It’s really confusing when moving from a .NET universe, which is simpler in that very regard (i.e. for many things there’s a clear choice of tool).
The second thing is the OS. I doubt that someone who used Windows for the entire life could switch to software development on Linux just like that. Luckily, most of us got the experience with some Linux distro while studying atthe university. Since I studied Mathematics, I almost didn’t. Fortunately, I’ve used Linux (Ubuntu, Debian and Gentoo) on my personal machine and have been using it, with short pauses, for a couple of years. But even despite that, some things caught me by surprise when I started using it for work, e.g. a colleague of mine was very surprised that I didn’t know about SSH tunneling. Here, the advice is simple – expose yourself to different things, if you’re using Windows at work use Linux at home, even if it means only browsing the Internet and watching movies, you’ll learn a lot.
The final category of difficulties is a mix of things related to systems design and deployment, especially if the system is distributed. I’d say that this is the most challenging part of all, the rest pales in comparison. While you can get away with not knowing much about networking while working on monoliths, the knowledge suddenly becomes indispensable when you have a network boundary inside your system. Failure modes become non-trivial and a simple transaction becomes one of the hardest problems when it needs to be distributed across services. Good context boundaries gets promoted from something that’s nice to have to something that is crucial for creating a working system. This aspect is, of course, completely unrelated to .NET or Java – what I want to stress here is that the language and the platform matter only to a point and there are challenges far greater than that.
People react in different ways when they hear about switching technologies. From my point of view, many assign far too much importance to languages, platforms, tools and not enough to practices and plain old Computer Science, which is especially silly in the case of Java vs C#, as it would be hard to find a pair of more similar programming languages than those two.
I often hear the ‘experience’ argument – why change the technology if, given that all else is more or less equal, you have years of experience under your belt? Let me counter that with another question – how confident are you that you’ll be able to learn something new and switch platforms when the time comes? How do you know that you’ll cope, if you’ve never done this before?