0

I have a Spring project which contains ~50 components. Unfortunately, one of the classes caused an issue of cyclic dependency in Maven. Here's the story:

I added a new component to my Spring project. Let's call it Apple for now. It has a @Bean called AppleWatch. One of the implementations was that Apple lived (depended) on another component: Foxconn, so that AppleWatch could call a method in a Bean called CheapLabor.

At the meantime, CheapLabor depended on another component: Corning. It needed GorillaGlass to be able to work overtime.

Things were pretty good until the moment Corning realizes that it wants to save money by making the similar amount of glasses according to the Apple's market need. So it tries to call a method getCurrentMarketOrders() in AppleWatch. To do so, I autowired the bean AppleWatch into the class GorillaGlass.java. Then...

Boom! Cyclic dependency error!

So, any suggestion on what should I do for Apple and/or Corning?

Jerry Yeh
  • 61
  • 1
  • 3
  • The usual advice would be to depend on interfaces rather than implementations--I suspect that would help here. Also, think about the direction of your dependencies..for example, I can see a watch depending on a glass crystal, but not the other way around. It kinda sounds like your GorillaGlass class somehow depends on AppleWatch--makes me scratch head, but maybe I just misunderstand the issue. – unigeek May 18 '16 at 20:05
  • Is this a build time error or a runtime (including unit tests) error? – Steve C May 19 '16 at 01:25
  • @unigeek I agree. Re-designing the structure of project accordinglysurely solves the problem. But it turned out that I couldn't change the structure without driving my boss/colleagues crazy. There are many approaches to solve cyclic dependency issues. I came up with this after all: moving the logic that `Corning` depends on `Apple` to be a part of `Apple`: instead of getting needed info from `Apple`, `Coring` now gets those information from `Foxconn`, which calls the method from `Apple`. It break the circle to `Apple` -> `Foxconn` -> `Corning`. Not the best move but it worked. – Jerry Yeh May 19 '16 at 14:17

1 Answers1

0

As mentioned by @unigeek, interfaces are your friends in this case. And in context of structuring your maven project this means separating interfaces into separate API maven modules.

Soon Corning will realize it also supplies GorrilaGlass to Samsung, not just Apple. So now it needs to call getCurrentMarketOrders() not only on AppleWatch, but also Gear2. The solution becomes more clear at this point: introduce an API module with Marketable interface that both Apple and Samsung depend on, allowing both AppleWatch and Gear2 implement Marketable. Then Corning simply depends on this new API module, without having direct dependencies on either Apple or Samsung, while the latter both provide their own implementations to this interface.

Anton Koscejev
  • 4,603
  • 1
  • 21
  • 26