In our new Java Monthly edition, we’d like to introduce you again to Markus Eisele. He was part of our Java Special Daily 3 years ago, and now he was kind enough to share his experience on 11 more Java-related questions.
Markus is a Java Champion, former Java EE Expert Group member, founder of JavaLand, reputed speaker at Java conferences around the world, and a very well-known figure in the Enterprise Java world. He works as Developer Strategist for Red Hat in EMEA. You can find him on Twitter & LinkedIn.
Java Monthly: What are the key points that we need to follow when we want to migrate from monolithic applications into the cloud-native model?
Markus Eisele: The first and most important part is to question the goals. What I’ve seen frequently is that teams throw new technologies or architectures at problems that are well solved with the existing design and really doesn’t need any modernization at all. Ultimately, cloud-native can mean a lot of things to many people. In our recent book “Modernizing Enterprise Java” we touched a little bit more on the definition and came to the conclusion that what most projects actually desire is the need to be Kubernetes-native. Meaning, to run, scale, and operate a project on Kubernetes. Well established for deciding which path to take is the so called 6-R model that describes a more general cloud migration approach. Which can be a simple replatforming or even the ultimate decision to retire an application. If the result is to rearchitecture or redesign an existing application to become Kubernetes-native you are going to embark on a full-fledged refactoring most likely to modularize your existing system and examine the service boundaries that are needed.
Java Monthly: Do you think that there are cases in which the approach of monolithic application is better?
Markus Eisele: I keep coming back to the software architecture toolbox and try to visualize how technologies, frameworks, and methodologies expanded it in the last couple of years. The basic principles stayed the same though. On the foundation of functional and non-functional requirements a team has to make a decision about what architecture style they need to solve the original business problem. Do you have to scale indefinitely and fast or are you going to build a departmental application that is going to be used by 20 people? Will you create an application that changes frequently and unpredictably, maybe because of legal requirements or a frequently changing market? Those are the hard questions to answer. Depending on the answers, you’ll quickly find what solution will work for your problem. And I strongly believe that there are many ways of architecting appropriate solutions for business problems.
Java Monthly: What are the stages and moments that people usually fail during the migration of their application? How is it possible to make our migration as smooth as possible?
Markus Eisele: I see some very common pitfalls that projects tap into. The most prominent one is to change too many things at once. Not only migrating into modules and carving out functionality but also changing the underlying framework and execution environment. The most important part to not fail is to actively manage changes in your codebase. Like with every other refactoring, try to limit and control the impact of any given change and make sure, you’re not silently rewriting the application from scratch.
Another common mistake is to make assumptions. Some projects lack the specification or interface contracts, and it is hard to even assess what functionality must be migrated and kept alive. I can only strongly recommend using a well proven migration assessment like the Migration Toolkit for Applications to not only examine individual applications but also identify technical challenges beforehand.
Finally, I personally believe that it is hard to resist the temptation to fix broken things while modernizing. Introducing a new Java version, together with a new framework and adding new test approaches all at once is the recipe for failure.
Java Monthly: What goals are achieved from being cloud-native?
Markus Eisele: I think I already mentioned some of the points above. Taking an application cloud-native is the promise for it to deliver seamless scale in cloud hosted environments. The need for applications to behave like this depends on the underlying business requirements and therefore should be the number one guiding principle for cloud-native migrations. There might be other considerations around standard target platforms or simplified infrastructure administration, but being cloud-native is supporting one of these underlying goals that are heavily depended on the project and company it’s running in.
Java Monthly: What would you like to see in Java in order to improve further the productivity of developers?
Markus Eisele: I keep saying this constantly: I like Java to make adoption easier. It already has a great user base and keeps being the industry standard development language for many business-critical applications. The recent change in pace (and the currently discussed acceleration of it) leads to a lot of challenges for companies running Java based applications. And ultimately, even if a version bump sounds simple, many companies run a Java version increase as a migration project with all the bells and whistles involved. That leads to an insanely large overhead and resistance to migrate to newer versions across the board. I think it is about time to decouple language development sprints from runtime evolution. It should be way easier to use latest language features but keep the runtime stable for a longer time. And I do absolutely acknowledge that I have very little ideas how to make this work and I am also in awe about the work that has been done on backwards compatibility in the Java space. But…
Java Monthly: One of the challenges that are faced during the transition from a traditional application to a cloud-native application is that dependencies and interdependencies may arise. What is your opinion?
Markus Eisele: I think this is called the distributed monolith. Something we all might have seen out there. There’s no good solution to it than to prevent it by questioning your modularization approach.
Java Monthly: How do containers affect the speed of application development and deployment?
Markus Eisele: Containers are the best thing since sliced bread from the perspective of application delivery and deployment. We all have been through various, adventurous, and nerve-wracking ways of packaging and delivering applications to throw them over the fence to ops in the past. Containers are almost a revelation compared to those times. Standardized images with layers that can be introspected, hardened and secured. Almost a dream come true. From an application development perspective, I do see more challenges. While Docker made it comparably easy to understand and create those container images, it still required a lot of knowledge to achieve the before-mentioned ideals. Developers used base images from all over the internet and packaged what needed to be packaged in all the ways possible. Not to mention the additional configuration. And if you add Kubernetes to the mix the productivity declines even more. Plus, there is a lot more to know and handle appropriately. Less time for productive development work in general. I think that the balance swapped over into almost an unhealthy proportion, and we do need to make sure we are re-using existing knowledge, e.g., Enterprise Java APIs and specifications, plus giving developers the right tools to manage the complexity of todays distributed kubernetes-native application development. A very good solution can be Quarkus which uses established Microprofile APIs and enriches the developer experience with a lot of convenience by adding local development modes, remote debugging, container deployment and intelligent defaults.
Java Monthly: How do containers work with different infrastructure, technologies, and programming languages?
Markus Eisele: This is an interesting question. As the new industry standard for application delivery, containers naturally are independent of the technologies running inside them, at least from an application development perspective. If whatever runs on Linux, you’ll most likely be fine. This is the incarnation of the multi-language microservices approach allowing us to choose the best tool for the job. From an infrastructure perspective things become a little more challenging quickly. Even if we can still rely on the standard itself, there’s different approaches to container execution. If you, do it securely, you’ll quickly realize that you need a lot more than just containers to be successful. Depending on what your infrastructure can handle, you’ll either end up with containers in production or with a thoughtfully planned, hybrid cloud-based deployment, monitoring and operations.
Java Monthly: One of the ways to kill developer productivity is to go on Microservices without proper tooling. Is there a set of tools that you recommend using and why?
Markus Eisele: Don’t we all wish for that one Microservices IDE? It’s probably going to take some time though. I think, what is more important is to re-focus attention on a proper tooling for developers that can hide complexity where possible. As mentioned earlier, you could profit immensely from Quarkus which operates on intelligent Kubernetes-native defaults and keeps the developer’s attention on code and not on infrastructure or deployment. Combined with magic like the Service-Binding-Operator and a developer view onto Kubernetes and the complete platform you can be productive again with Microservices.
Java Monthly: Does the transition from a monolithic to a cloud-native application necessarily have to go through microservices?
Markus Eisele: No. Remember the 6R’s we talked about earlier? Another R can be “Rehost” which basically just takes existing applications and moves them to a new (Kubernetes) infrastructure. It is also valuable and suitable to containerize existing applications without modernizing them in the first place. You will experience some drawbacks and won’t be able to pull full advantage from all the new world, but it is a solid first step for many projects.
Java Monthly: Is it considered “cloud-native” if you containerize your monolithic app and put it in the cloud?
Markus Eisele: Another No. Cloud-native explicitly refers to an application using the features that the cloud platform provides. Just containerizing an existing application is a containerized workload but not a cloud-native application.
Is there anything else you would like to ask Markus Eisele? What is your opinion on the questions asked? Who would you like to see featured next? Let’s give back to the Java community together!