"We're a Java shop" or "we're a .NET shop". We hear it all the time. And I get it. Developers identify with their languages. On the hierarchy of needs, being part of a group, like “Java developers”, falls somewhere below self-actualization and above wifi.
Reality isn't that neat and tidy. If you work for an enterprise, acquisitions are inevitable. Lately, there's been a lot in healthcare, but banking, retail, insurance, etc.—they all have to deal with integrating acquisitions. And that means integrating not just the technology stacks, but the people that go with it.
Take the example used by my colleagues, David Dieruf and Ben Wilcock, at Microsoft Build last month. A large bank that's mostly .NET makes a critical acquisition of a loan approval service… that's written in Java. On the surface it seems like a catch 22. If you force the acquired Java team to re-write into .NET, you'll stall the value from the acquisition and drive away the human talent you acqui-hired. But if you try to force the acquiring team to adopt Java, you'll alienate a much larger, critical .NET team powering your company. In practice, no one ends up actually re-writing anything, teams keep doing what they’ve been doing, integration is slow and painful, and operations teams end up supporting two sets of infrastructure.
When you're digesting acquisitions, it’s like two divorced parents getting together. You're blending families and you can't pick favorites. You have to make it work. You want “happy families,” and quickly.
In this post, I'll recap some key lessons from Ben and David's talk, along with pointers for how you can get started.
Polyglot platforms: Striking a delicate balance
Offering a polyglot application platform isn't just about striking the balance between developers using different languages. It's about helping them ship code to production. After all, you can offer your developers a runtime on different types of virtual machines or even a kubernetes dial-tone and technically be called polyglot. But it does nothing for developer productivity. Developers are left with getting middleware installed, sorting out logging, load-balancing, SSL termination, etc. And then there’s the poor operators supporting this infrastructure. These folks have twice the operating systems and twice the runtimes to support.
In contrast, there are single language platforms out there tuned for developer productivity on a particular stack. That doesn't help "blended families". It just creates an unnatural thing to support, and perpetuates siloed infrastructure and operations.
"We'd like some things to remain the same, like our languages, but at the same time we want a lot of things to change. Like we want to be able to commission our own databases as a developer without raising a ticket," David summarized.
In their talk, David and Ben enumerate several requirements for a polyglot platform that supports high developer productivity:
- Multi-cloud, including on-premises
- Runs Windows and Linux
- First-class support for Java and .NET
- Unified user experience for developers
- Multi-tenant efficiency
- Marketplace of self-service offerings for developers
In this case, the polyglot application platform selected was Pivotal Application Service (PAS), where developers spend more time focused on coding in their tools and language of choice and infrastructure folks see virtual machines as cattle not pets. Now the fun begins! It’s time to combine two different applications on two different runtimes together, and head on to production.
Externalizing Configuration
Getting these two applications to work in multiple cloud environments – dev, test, staging, production—without recompilation offered an opportunity to modernize. Why is externalizing configuration a useful modernization effort? According to the 12 Factor manifesto:
This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.
What this means is any application setting—connection strings, credentials, hostnames of dependent web services, or business rules—should be stored separately from the application code. These configuration settings vary across environments while the application code remains the same. Externalization makes it easier to change settings without changing the code.
What's better than being able to change your environment variables without changing your code? Changing those settings without having to restart your application! In Java, you can use Spring Cloud Config Server to dynamically resolve configuration at runtime. Config Server is based on software developed and open sourced by Netflix and is used heavily with microservice architectures. On the .NET side you have the Steeltoe Framework. Similar to Spring Cloud, the Framework enables an application to refresh configuration values and never restart.
Voila! Both your Java and .NET developers have a similar experience in externalizing configuration. After the config service is created, the same four-step process applies to set up each client application:
-
Add the dependency to the application
-
Set the application's Name
-
Add your external configuration in Git
-
Add your configuration code
Figure 1: Extremely similar setup between Java and .NET
As David and Ben illustrated, these configuration settings can actually include some business logic. For example the ‘maximum loan limit’ and ‘loan applicant naughty list’ provide values to the applications, to make a business decision on approving a loan. This opens up a lot of interesting possibilities for how to use the Config Server.
Cross-language service discovery
When you look at modern microservice architecture, it’s very common to see service discovery. Think of it as an address book holding the name and uniform resource identifier (URI) of different services through the enterprise. Services use this address book to help find and connect to one another, removing the need to hard code network address within an application.
There are two factors that make service discovery critical when modernizing applications. First, as you adopt a microservices architecture, the services need to find each other by logical name – not URI. Second, as you treat your infrastructure as code, you need to physically move your services around within that infrastructure. These factors combined make a dynamic address-book of service locations critical.
"We wanted to have a registry because we want our microservices to behave well in the cloud," noted David. The Spring Cloud Service Registry addresses the need. It's another service adopted from Netflix and extended to .NET with Steeltoe.
Unlike the Config Server, however, differences in Spring and .NET make setup in each more unique. Nonetheless, the two applications can share the same Service Registry in the final architecture. The Loan Application service can find the Loan Checker service to verify the applicant is not on the naughty list. Respecting each apps’ business domain and enabling them to accomplish an overall goal. Integrating each piece of software with their language choices intact is achieved.
Getting started
Ben and David go on to walk through build pipelines and touch on other production and cloud-native design improvements. They've offered a great starting place for bringing your Java and .NET software together. Here's how you can try it out, using their demo application:
-
Add the Azure Service Broker to use Azure DB (as David and Ben presented)
-
Set up the Config Server
-
Set up the Service Registry
Figure 2 : Final architecture using PAS on Azure with Config Server and Service Registry
During an acquisition blending Java and .NET families is bound to happen. Your company's acquisition strategy (the reason for buying another company) and your technology strategy (how these two can accomplish goals together) should reflect each other. Just like a modern, blended family, a merger is an opportunity to change some things, to be better, to be happier. But you shouldn’t give up the things that you identify with, like your programming language.
Select a platform and architecture that support both software stacks. Let developers continue to use the tools that make them successful, while removing lower-level concerns. This approach let’s developers quickly focus on creating accretion to the combined business.