Skip to content
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

Add module description for java 9+ compatibility #206

Closed
tobiasdiez opened this issue Jul 27, 2019 · 1 comment · Fixed by #827
Closed

Add module description for java 9+ compatibility #206

tobiasdiez opened this issue Jul 27, 2019 · 1 comment · Fixed by #827

Comments

@tobiasdiez
Copy link

tobiasdiez commented Jul 27, 2019

It would be nice if you could add a module-info file describing the modules that ArchUnit exports. This would make it easier to use ArchUnit in a modularized application and would prevent split package problems.

For example, the gradle configuration

    testRuntime 'com.tngtech.archunit:archunit-junit5-engine:0.10.2'
    testCompile 'com.tngtech.archunit:archunit-junit5-api:0.10.2'

leads to the following errors on runtime (with java 11)

Modules com.tngtech.archunit.junit5.engineapi and com.tngtech.archunit.junit5.api export package com.tngtech.archunit.junit to module org.assertj.core
@codecholeric
Copy link
Collaborator

Version 1.0 would be a good time to break the API here, I think (because this will likely move some classes around that might cause compile errors. But maybe it is good enough the just transparently move the engine classes to a different package and adjust the service loader descriptor file.

@codecholeric codecholeric added this to the 1.0.0 milestone Apr 9, 2020
codecholeric added a commit that referenced this issue Apr 22, 2022
So far, even though we added `Automatic-Module-Name` to the `MANIFEST` 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 modules `archunit-junit5-api`, `archunit-junit5-engine` and `archunit-junit5-engine-api` export the same package `com.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

* API stays the same, i.e. toplevel `c.t.archunit.junit`
* Engine and shared internal infrastructure are moved to `c.t.archunit.junit.internal` (this causes no problem, because engine dependencies were always only transparent runtime dependencies via `ServiceLoader`, never compile time dependencies)
* Engine-API is moved to `c.t.archunit.junit.engine_api`. This is a breaking change, however the `engine-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 (like `ClassCache`) 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 of `internal` 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants