-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow nested packages for @Modulith(sharedModules) #524
Comments
There simply is no such thing as nested modules, yet. In other words, if a module named Can you take a step back and elaborate why you think you'd need to list that nested package in the first place? Shared modules are automatically included in integration test executions and effectively lead to the component scanning to include the package of the shared module. That means that declaring |
Thanks for getting back to me so quickly! I am VERY new to modulith concepts so appreciate your input and guidance.
I have a set of common classes in 3 packages that will be used across all modules, e.g. exceptions.*, response.* and util.*. The only way I could get the .verify() to work was to add a sharedModules annotation for each fully qualified package. Ideally, from my perspective, I would be able to have these packages in the same hierarchy (com.app.core) and just use it in the sharedModules annotation.
Is there another way to indicate that a class is shared across modules?
…________________________________
From: Oliver Drotbohm ***@***.***>
Sent: Friday, March 8, 2024 8:17 AM
To: spring-projects/spring-modulith ***@***.***>
Cc: Timothy Vogel ***@***.***>; Author ***@***.***>
Subject: Re: [spring-projects/spring-modulith] Allow nested packages for @modulith(sharedModules) (Issue #524)
There simply is no such thing as nested modules, yet. In other words, if a module named com.app.core exists, no module com.app.core.exception can exist at all. Note, that the attribute is sharedModules, not sharedPackages. That the module names look like packages is a side effect of the setting to enable qualified module names.
Can you take a step back and elaborate why you think you'd need to list that nested package in the first place?
—
Reply to this email directly, view it on GitHub<#524 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACBEBVWIBDWGL7EICZKX5ZLYXG277AVCNFSM6AAAAABELN2L4SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBVGY4DAOBVGI>.
You are receiving this because you authored the thread.
|
No worries. I am a bit surprised you state that you could get this to work, as the shared modules definition is not even considered during the verification. The Javadoc of the attribute clearly states that it's used to define modules that are supposed to be included in integration test executions (using As documented here, nested packages of application module base packages are considered internal and other modules are not allowed to refer to code within those by default. I.e., it is not surprising that references to those would break the verification. To expose such types to other packages, the package they reside in needs to be declared a named interface. We generally discourage the use of packages to group types by their stereotype (exceptions, controllers, services etc. getting their own package) as that fundamentally subverts the encapsulation effects of packages. That said, Spring Modulith 1.2 will ship with the notion of an “open module”, which would also expose its externals (in other words: all nested packages) to other modules. If you find the time, it would be helpful to look at a reproducer as that allows us to find out what we're really talking about here. |
1. As you indicated, sharedModules did in fact NOT enable me to use nested packages. The test was green b/c I made them top level packages therefore modules (duh on my part).
2. After a bit of time to RTFM, what I need is @NamedInterface to make my original package layout work.
3. WRT grouping types by stereotype, I have top-level packages, i.e. modules, named with Domain model names. Within those top-level packages, I was grouping by stereotype. Is that also discouraged? If so what sub-package approach do you recommend?
…________________________________
From: Oliver Drotbohm ***@***.***>
Sent: Saturday, March 9, 2024 9:25 AM
To: spring-projects/spring-modulith ***@***.***>
Cc: Timothy Vogel ***@***.***>; Author ***@***.***>
Subject: Re: [spring-projects/spring-modulith] Allow nested packages for @modulith(sharedModules) (Issue #524)
No worries. I am a bit surprised you state that you could get this to work, as the shared modules definition is not even considered during the verification. The Javadoc of the attribute clearly states that it's used to define modules that are supposed to be included in integration test executions (using @ApplicationModuleTest) but it will not change anything about the outcome of a AppplicationModules.of(…).verify().
As documented here<https://docs.spring.io/spring-modulith/reference/fundamentals.html#modules.advanced>, nested packages of application module base packages are considered internal and other modules are not allowed to refer to code within those by default. I.e., it is not surprising that references to those would break the verification. To expose such types to other packages, the package they reside in needs to be declared a named interface<https://docs.spring.io/spring-modulith/reference/fundamentals.html#modules.named-interfaces>.
We generally discourage the use of packages to group types by their stereotype (exceptions, controllers, services etc. getting their own package) as that fundamentally subverts the encapsulation effects of packages. That said, Spring Modulith 1.2 will ship with the notion of an “open module”, which would also expose its externals (in other words: all nested packages) to other modules.
If you find the time, it would be helpful to look at a reproducer as that allows us to find out what we're really talking about here.
—
Reply to this email directly, view it on GitHub<#524 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACBEBVUJKABGNIQLUJOM5D3YXMLVRAVCNFSM6AAAAABELN2L4SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBWHA3TAOBQGA>.
You are receiving this because you authored the thread.
|
Hello @odrotbohm, Firs thanks for your work on Spring, it's always a great pleasure to work with it. We started using Modulith on a project and it allows us to detect invalid dependencies. But the nested item is not clear for me. Regarding your comment "To expose such types to other packages, the package they reside in needs to be declared a named interface." You reference this:
I have 2 questions:
Thank you, hoping my questions are not too stupid. |
Current Behavior
The
sharedModules
parameter of the@Modulith
annotation does not allow nested packages, even when the nested packages are explicitly listed.package structure - com.app.core.exception
@Modulith(sharedModules={"com.app.core"}, useFullyQualifiedModuleNames = true)
and@Modulith(sharedModules={"com.app.core", "com.app.core.exception"}, useFullyQualifiedModuleNames = true)
result injava.lang.IllegalArgumentException: Module com.app.core.exception does not exist!
@Modulith(sharedModules={"com.app.core"}, additionalPackages = { "com.app.core.exception"}, useFullyQualifiedModuleNames = true)
results inModule 'com.app.user' depends on non-exposed type com.app.core.exception.EntityNotFoundException within module 'com.app.core'!
Desired Behavior
Allow for wildcard(1) or explicitly listed(2) sub-packages to be referenced within all modules.
1
@Modulith(sharedModules={"com.app.core.*"}, useFullyQualifiedModuleNames = true)
2
@Modulith(sharedModules={"com.app.core", "com.app.core.exception"}, useFullyQualifiedModuleNames = true)
Workaround
change package structure to
com.app.core
andcom.app.exception
with@Modulith(sharedModules={"com.app.core", "com.app.exception"}, useFullyQualifiedModuleNames = true)
The text was updated successfully, but these errors were encountered: