Gradle multi-modules: best approach to break or resolve circular reference between two projects


(Manuel Jordan) #1

Hello Developers

I am with the following situation, I have project working with multi-modules based on Gradle

in module-domain I have the following:

@Entity
@Table(name="person")
@DateDeath(groups={PersonDeathCheck.class})
public class Person implements Serializable {

See that Person class uses or depends on DateDeath annotation

Now, in the module-validation I have

@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy=DateDeathValidator.class)
public @interface DateDeath {

Here DateDeath depends on DateDeathValidator class, where DateDeathValidator is:

public class DateDeathValidator implements ConstraintValidator<DateDeath, Person>{

Therefore observe DateDeathValidator depends or uses:

  • DateDeath class and it is located in the same module: module-validation
  • Person class and it is located in a different module: module-domain

Here we have circular reference between these projects.

project(':web-27-domain') {
	description 'domain'
        dependencies {
 	   compile project(':web-27-validation')
	}
}

project(':web-27-validation') {
	description 'Validation'
        dependencies {
 	   compile project(':web-27-domain')
	}
}

Exists a way to break in someway this circular reference? I want avoid merge the code from web-27-validation into web-27-domain (it is my worst scenario)

Thanks in advance.


(Dimitar Dimitrov) #2

Having the validation and modules in different domains makes little sense, especially when using a technology that couples them in both directions. To exaggerate the point, would you create a module for Exceptions, or String constants?

You may instead choose to split a large domain (including data structures, validations, etc.) in multiple self-contained packages - for example a smaller one for use on the client side and some extras for use on the server side.

Here is a good read on the topic of modularization: Common Closure/Reuse Principle and others


(Manuel Jordan) #3

Thanks by the reply

Having the validation and modules in different domains makes little sense, especially when using a technology that couples them in both directions

Mmmm, I think or see each module in other way such as how centralize something (utils, role, technology), but I see your point, therefore you will take the approach about taking the module-domain including the packages/classes about validation JSR-349

To exaggerate the point, would you create a module for Exceptions, or String constants?

Good point, to be honest was in my plans create one for the Exceptions and for the second I have a module named module-support where it includes String constants and other utils classes such as transformers (xml, json) and formatters, all of them are for support…

When I have a class used in many points, such as a Domain class such as Person where is used in a Repository, Service and layer, well I proceed to create a module. I think if we have our own Exception of type RuntimeException I have the temptation to create a new module because it is used at least in two layers (web and service). But I see your point… I create a module thinking in centralization of something such as domain, repository and service it for API and implementations, controller, etc…

You may instead choose to split a large domain (including data structures, validations, etc.) in multiple self-contained packages - for example a smaller one for use on the client side and some extras for use on the server side.

Well, seems I have taken both, I mean modules + packages.

Thanks by the links, the second targets to the same than the first, therefore is repeated.


(Flurbius) #4

Its been a while but I have solved these kind of issues in the past by using Interfaces, I have used a module that simply contains interfaces to all the data classes in your case (I)Person and (I)DateDeath, then any modules can refer to that in blissful ignorance of who else needs it