Make ArchUnit JUnit 5 support Java Modules compatible #827
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
So far, even though we added
Automatic-Module-Name
to theMANIFEST
to make it compatible with Java Modules, ArchUnit's JUnit 5 support could not be used on the modulepath. The reason is that all three modulesarchunit-junit5-api
,archunit-junit5-engine
andarchunit-junit5-engine-api
export the same packagecom.tngtech.archunit.junit
.We now fix this by splitting the three modules into separate packages. This is a little tricky since there is also code that is shared with ArchUnit JUnit 4 support and we want to keep as many internals package private as possible. I tried to find a good compromise between backwards compatibility and public surface, the result is
c.t.archunit.junit
c.t.archunit.junit.internal
(this causes no problem, because engine dependencies were always only transparent runtime dependencies viaServiceLoader
, never compile time dependencies)c.t.archunit.junit.engine_api
. This is a breaking change, however theengine-api
is a very specific artifact that is only needed for frameworks to integrate with JUnit Platform. So it should only affect a very limited number of users.Unfortunately the JUnit 4 design makes it very hard to cleanly split API and implementation. I.e. by making the
Runner
type public API (having to explicitly declare it as@RunWith(..)
) tends to cause a chain reaction pulling more and more into the public scope. In particular if now the classes that are used internally (likeClassCache
) don't reside in the same package anymore. I tried to find some compromise by creating an internal delegate that is loaded via Reflection. This way we can keep the things inside ofinternal
conceiled with package-private scope. Hopefully this will not cause any problem in the long term.Note that it will still not possible to put both JUnit 4 and JUnit 5 support on the modulepath together, but I also don't see any reason why anybody should want to do this, since they serve exactly the same purpose and JUnit 5 support is just more future proof.
Resolves: #206