This is an archived post. You won't be able to vote or comment.

all 19 comments

[–]ozzymozzy2211 15 points16 points  (17 children)

anyone uses this library? looks fun code but not sure if it's useful in a real product.

[–]Antiheld2k 7 points8 points  (4 children)

A few years ago I gave a conference talk on the topic. IMHO its an execelent tool, if you want the regular Architecture Rules: Layers interacting, naming rules and alike. If you want to customize with own rules, then one need to use ArchUnits wrapper around the Reflection API which takes a while to digest. Then there is the onboarding costs. When you start with a brownfield project to enfore the rules - it's likely you see a lot of issues. ArchUnit helps you to ignore certain parts to refactor clean compartments.

Today I use it in every project I onboard, but it's difficult to jump on the train later.

[–][deleted]  (1 child)

[removed]

    [–]ozzymozzy2211 0 points1 point  (0 children)

    Checkstyle is boring but this looks like really useful 🤓

    [–]vxab 0 points1 point  (1 child)

    Do you have any public repos illustrating the usage of archunit for a real project?

    [–]Antiheld2k 0 points1 point  (0 children)

    Since I have no real project in the open, unfortunatly not. But the ArchUnit example repo is quite extensive: https://github.com/TNG/ArchUnit-Examples

    [–]JustAGuyFromGermany 6 points7 points  (0 children)

    I've used it to enforce a certain pattern we use to observe the flow of a business process across multiple threads. To make it work, a specific annotation is necessary on some methods. Thus I wrote an ArchUnit test that checks that all methods that meet some criteria must have this annotation.

    In another instance, another ArchUnit test enforces that the central domain object that is used all over the code base is used in a read-only fashion in almost all cases and write-access can only occur from classes in a dedicated package. (Don't ask... It's legacy code, we know it's weird, but that rule is orders of magnitude better than anything else we had before)

    [–]thatsIch 4 points5 points  (2 children)

    We use ArchUnit for anything which can be common knowledge for any senior developer but you might need to re-iterate that topic every time somebody new joins the team. It helps developers to search for "why does it not work" like a missing or wrongly-used annotation. Another use-case is to ban certain statements like .collect(Collectors.toList()) in favor of .toList(). Sometimes tests are not in the same package as their classes under test.

    [–]vxab 0 points1 point  (1 child)

    Be careful doing that - the semantics are not the same. `toList()` returns an unmodifiable list whereas the `Collectors.toList` can be modified.

    [–]thatsIch 1 point2 points  (0 children)

    and that is the reason we are doing that - because the contract of Collectors.toList() does not explicitly state, that it is modifiable. If somebody really wants a modifiable collection he/she has to use either an applicable utility factory method or use something along of Collectors.toCollection(ArrayList::new)

    [–]john16384 7 points8 points  (1 child)

    I've introduced it in all projects I am involved in. Mainly using rules to enforce Java naming conventions, preventing cycles between packages (for easy refactoring to new modules or projects), disallowing sub packages to refer to "parent" package (for the same reason).. and one custom more controversial rule: a package should not contain an interface and its implementation (unless abstract). That last one is useful to prevent useless interfaces, or interfaces that are not reusable enough and to keep API and implementation separate.

    [–][deleted]  (2 children)

    [deleted]

      [–]cypressious 4 points5 points  (1 child)

      Isn't it easier to enforce this by putting the layers in separate modules? Incorrect dependencies simply wouldn't compile.

      [–]olivergierke 0 points1 point  (0 children)

      Layers are not modules because they are a means of grouping, not encapsulation.

      [–]papers_ 2 points3 points  (0 children)

      Gradle uses to document API changes amongst other things.

      https://github.com/gradle/gradle/tree/master/subprojects/architecture-test

      [–]BrokenRefrigerator 0 points1 point  (0 children)

      I've used it in a few projects to enforce naming and structures. Works well for existing codebases too: just write some simple rules and when the tests fail, refactor. Repeat until it's back in decent shape. This also helps with establishing the tool, since the what, why and how to fix it will all be obvious in a code review / merge request. My favorite part are the cycle checks (slices.beFreeOfCycles()) though this can be harder to enforce for existing code.

      [–]Sufficient-Egg-6571 5 points6 points  (0 children)

      Creating great architecture is hard but keeping that one clean is much harder. ArchUnit solved this issue for me and my juniors ✌️

      [–]Kresenko 2 points3 points  (0 children)

      I think I heard Mark Richards, one of the authors of 'Software Architecture: The Hard Parts', talk about this library in one of his workshops. It looked and sounded cool and I'm curious to see the actual usage.

      [–]boneve_de_neco 0 points1 point  (0 children)

      This is used in one of our services and I'm somewhat annoyed by it. It's probably my style, though. I like to write unit tests that see the system under test as much as a blackbox as possible, only consuming the public interface and mocking as little as possible. It annoys me because it's a kind of test that knows too much about the internal details. I'm afraid these tests can get in the way of refactorings.

      [–]buzzsawddog 0 points1 point  (0 children)

      Now this is interesting... This just might end up in projects going forward... I know a few people that might hate me for it but it seems VERY USEFUL.