Domanda

I am trying to come up with a solution to replace joda-time with java 8 time in our product. The code-base encompasses many projects of which some import joda-time directly and some transitively. To limit regression and to allocate multiple developers for the task an iterative approach of library swapping is required. What would be the best practices for this type of task?

By intuition I would start moving down from the top of the dependency tree towards the root in groups of 3-5 projects whilst writing temporary wrappers for the lowest project. Next, run integration tests and on success take another set of projects, remove the temporary wrapper and repeat.

What other options are there?

È stato utile?

Soluzione

Unfortunately, the design of the Java language does not make it easy to swap out dependencies. While you could wrap external dependencies with interfaces and do some dependency injection, you can't use simple type aliases.

Ideally, you can do a lot of the migration by doing search and replace across the project. Because this is comparatively easy you might want to at least try if that works without using an iterative approach.

Otherwise, look at your dependency graph of the components you control and see which parts are fairly isolated and easy to migrate. You will have to convert between the time libraries at the API boundaries:

  • you can keep the old API and convert any arguments/return values within the methods
  • you can change the API and do the conversion at the call location
  • you can sometimes do both: migrate the methods to a new API but offer compatibility wrappers with the old API

Which approach to use depends:

  • if a method is used in many places it may be easier to use the compatibility wrapper approach so that you can migrate one call site at a time
  • if you don't want to touch other components in this iteration, keep the old interface – but that means you will have to touch this code again in a second step
  • otherwise, just do what you need and fix the call sites until it works without errors

Both a top-down or bottom-up approach can be fine. The above view of API boundaries has a bottom-up viewpoint, but the same principles apply in either case. I think that bottom-up integration will result in having to write fewer compatibility wrappers that you will have to delete later. However, this is very much a judgement call that you have to make.

If some components are tightly coupled, it can make a lot of sense to migrate them together.

In any case, you will likely want to write an utility class that helps with conversions between the two representations.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top