Repository: tng/archunit
Issue: Layeredarchitecture problem with three layers A,B,C - The access check fails for A->B, but the violation comes up when allowing access B->C

We came across an issue with `layeredarchitecture` where we have three layers A, B and C: A may access B, B may access C. 

As soon as we allow the access from B to C with `.whereLayer(layerB).mayOnlyAccessLayers(layerC)` , the architecture tests fails because of a violation by the access from layer A to layer B (which is even explicitely allowed). What are we doing wrong?

We are using ArchUnit V0.22.0 (but the same issue occurs with older versions, as we tried a few like 0.11 or 0.19 to 0.21).

# Our scenario: Three layers A, B, C
We put some minimal sample code to a separate Github repo https://github.com/mrtnlhmnn/archunit-layeredarchitecture-problem

We have a component `mycomponent` and want to check the access rules between these technical layers. Originally, we were checking an onion architecture with its technical layers (like application, domain, infrastructure). 

- We stripped that down to a very minimum with three layers, named `layerA` and `layerB` and `layerC`, see [here](https://github.com/mrtnlhmnn/archunit-layeredarchitecture-problem/tree/main/src/main/java/mycomponent)
- Each layer is a separate package.
- Each package contains one class `A` and `B` and `C` (where class `A` has a dependency to class `B` and class `B` has one to class `C`).
- Our ArchUnit test fails as soon as we allow `.whereLayer(layerB).mayOnlyAccessLayers(layerC)`, but the violation says that there is a problem with the access from `layerA` to `layerB`, though we have this explictely allowed. 
- If we commented that `whereLayer...` out, the test is OK. This looks weird to us, as this  `mayOnlyAccessLayers` is "outgoing from B" while the violation is for an "incoming to B".


# Violation
```
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'Layered architecture consisting of
layer 'LayerA' ('mycomponent.layerA..')
layer 'LayerB' ('mycomponent.layerB..')
layer 'LayerC' ('mycomponent.layerC..')
where layer 'LayerA' may not be accessed by any layer
where layer 'LayerA' may only access layers ['LayerB']
where layer 'LayerB' may only be accessed by layers ['LayerA']
where layer 'LayerC' may only be accessed by layers ['LayerB']
where layer 'LayerB' may only access layers ['LayerC']' was violated (1 times):
Field <mycomponent.layerA.A.b> has type <mycomponent.layerB.B> in (A.java:0)
```

# ArchUnit test
Whole class see [here](https://github.com/mrtnlhmnn/archunit-layeredarchitecture-problem/blob/main/src/test/java/ArchUnit_LayeredArchitectureProblem.java)
```
String PKG = "mycomponent";
JavaClasses myClasses = new ClassFileImporter().importPackages(PKG);

String layerA = "LayerA";
String layerB = "LayerB";
String layerC = "LayerC";

Architectures.LayeredArchitecture layeredArchitecture = Architectures.layeredArchitecture()
          .layer(layerA).definedBy(PKG+".layerA..")
          .layer(layerB).definedBy(PKG+".layerB..")
          .layer(layerC).definedBy(PKG+".layerC..")
          // ignore any dependencies to java.. Not sure if this ignore could be avoided
          .ignoreDependency(isMyClass, isJavaClass)
          // no access to A
          .whereLayer(layerA).mayNotBeAccessedByAnyLayer()
          // A --can access--> B
          .whereLayer(layerA).mayOnlyAccessLayers(layerB)
          .whereLayer(layerB).mayOnlyBeAccessedByLayers(layerA)
          // B --can access--> C
          .whereLayer(layerC).mayOnlyBeAccessedByLayers(layerB)
     /*  .whereLayer(layerB).mayOnlyAccessLayers(layerC) */  // <== problem occurs when this line is commented in
 ;

// the check is ok, when the last whereLayer() is commented out but fails with the line commented in
layeredArchitecture.check(myClasses);
```

# We ignore accesses to Java standard classes
Note that in the test code above we are explicitely ignoring any dependencies to `java..` by saying `.ignoreDependency(isMyClass, isJavaClass)`. For that we wrote two `DescribePredicate`s which look as follows:

```
    DescribedPredicate<JavaClass> isMyClass = new DescribedPredicate<>("is in mycomponent") {
        @Override
        public boolean apply(JavaClass input) {
            return input.getPackageName().startsWith(PKG);
        }
    };

    DescribedPredicate<JavaClass> isJavaClass = new DescribedPredicate<>("is Java class") {
        @Override
        public boolean apply(JavaClass input) {
            return input.getPackageName().startsWith("java");
        }
    };
```

Changed files:
archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
archunit/src/test/java/com/tngtech/archunit/library/ArchitecturesTest.java
archunit/src/main/java/com/tngtech/archunit/base/PackageMatcher.java
archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/allowed/MayOnlyAccessLayersAllowedClass.java
archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/forbidden/MayOnlyAccessLayersForbiddenClass.java
archunit/src/main/java/com/tngtech/archunit/library/Architectures.java

diff --git a/archunit/src/main/java/com/tngtech/archunit/base/PackageMatcher.java b/archunit/src/main/java/com/tngtech/archunit/base/PackageMatcher.java
index 67fa4871..a2afb391 100644
--- a/archunit/src/main/java/com/tngtech/archunit/base/PackageMatcher.java
+++ b/archunit/src/main/java/com/tngtech/archunit/base/PackageMatcher.java
@@ -28,7 +28,7 @@ import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
 
 /**
  * Matches packages with a syntax similar to AspectJ. In particular '*' stands for any sequence of
- * characters, '..' stands for any sequence of packages, including zero packages.<br>
+ * characters but not the dot '.', while '..' stands for any sequence of packages, including zero packages.<br>
  * For example
  * <ul>
  * <li><b>{@code '..pack..'}</b> matches <b>{@code 'a.pack'}</b>, <b>{@code 'a.pack.b'}</b> or <b>{@code 'a.b.pack.c.d'}</b>,
@@ -38,7 +38,7 @@ import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
  * <li><b>{@code '*.*.pack*..'}</b> matches <b>{@code 'a.b.packfix.c.d'}</b>,
  * but neither <b>{@code 'a.packfix.b'}</b> nor <b>{@code 'a.b.prepack.d'}</b></li>
  * </ul>
- * Furthermore the use of capturing groups is supported. In this case '(*)' matches any sequence of characters,
+ * Furthermore, the use of capturing groups is supported. In this case '(*)' matches any sequence of characters,
  * but not the dot '.', while '(**)' matches any sequence including the dot. <br>
  * For example
  * <ul>
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
index 225fa021..7f086eb3 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
@@ -39,12 +39,16 @@ import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
  * following:
  * <ul>
  * <li>a class accesses a field of another class</li>
- * <li>a class calls a method of another class</li>
- * <li>a class calls a constructor of another class</li>
- * <li>a class inherits from another class (which is in fact a special case of constructor call)</li>
+ * <li>a class calls a method/constructor of another class</li>
+ * <li>a class inherits from another class</li>
  * <li>a class implements an interface</li>
  * <li>a class has a field with type of another class</li>
  * <li>a class has a method/constructor with parameter/return type of another class</li>
+ * <li>a class (or method/constructor of this class) declares a type parameter referencing another class</li>
+ * <li>a class (or method/constructor of this class) is annotated with an annotation of a certain type or referencing another class as annotation parameter</li>
+ * <li>a method/constructor of a class references another class in a throws declaration</li>
+ * <li>a class references another class object (e.g. {@code Example.class})</li>
+ * <li>a class references another class in an {@code instanceof} check</li>
  * </ul>
  * Note that a {@link Dependency} will by definition never be a self-reference,
  * i.e. <code>origin</code> will never be equal to <code>target</code>.
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
index 9160fccf..f5e9efca 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
@@ -1221,18 +1221,8 @@ public class JavaClass
     }
 
     /**
-     * Returns all dependencies originating directly from this class (i.e. not just from a superclass),
-     * where a dependency can be
-     * <ul>
-     * <li>field access</li>
-     * <li>method call</li>
-     * <li>constructor call</li>
-     * <li>extending a class</li>
-     * <li>implementing an interface</li>
-     * <li>referencing in throws declaration</li>
-     * </ul>
-     *
-     * @return All dependencies originating directly from this class (i.e. where this class is the origin)
+     * @return All dependencies originating directly from this class (i.e. where this class is the origin).
+     *         For further details about dependencies refer to {@link Dependency}.
      */
     @PublicAPI(usage = ACCESS)
     public Set<Dependency> getDirectDependenciesFromSelf() {
diff --git a/archunit/src/main/java/com/tngtech/archunit/library/Architectures.java b/archunit/src/main/java/com/tngtech/archunit/library/Architectures.java
index a64e3570..3bfbf6ce 100644
--- a/archunit/src/main/java/com/tngtech/archunit/library/Architectures.java
+++ b/archunit/src/main/java/com/tngtech/archunit/library/Architectures.java
@@ -30,6 +30,7 @@ import com.google.common.base.Joiner;
 import com.tngtech.archunit.PublicAPI;
 import com.tngtech.archunit.base.DescribedPredicate;
 import com.tngtech.archunit.base.Optional;
+import com.tngtech.archunit.base.PackageMatcher;
 import com.tngtech.archunit.core.domain.Dependency;
 import com.tngtech.archunit.core.domain.JavaClass;
 import com.tngtech.archunit.core.domain.JavaClasses;
@@ -226,12 +227,9 @@ public final class Architectures {
         }
 
         private EvaluationResult evaluateDependenciesShouldBeSatisfied(JavaClasses classes, LayerDependencySpecification specification) {
-            ArchCondition<JavaClass> satisfyLayerDependenciesCondition =
-                    onlyHaveDependentsWhere(originMatchesIfDependencyIsRelevant(specification.layerName, specification.allowedAccessors));
-            if (!specification.allowedTargets.isEmpty()) {
-                satisfyLayerDependenciesCondition = satisfyLayerDependenciesCondition
-                        .and(onlyHaveDependenciesWhere(targetMatchesIfDependencyIsRelevant(specification.layerName, specification.allowedTargets)));
-            }
+            ArchCondition<JavaClass> satisfyLayerDependenciesCondition = specification.constraint == LayerDependencyConstraint.ORIGIN
+                    ? onlyHaveDependentsWhere(originMatchesIfDependencyIsRelevant(specification.layerName, specification.allowedLayers))
+                    : onlyHaveDependenciesWhere(targetMatchesIfDependencyIsRelevant(specification.layerName, specification.allowedLayers));
             return classes().that(layerDefinitions.containsPredicateFor(specification.layerName))
                     .should(satisfyLayerDependenciesCondition)
                     .evaluate(classes);
@@ -305,16 +303,30 @@ public final class Architectures {
                     irrelevantDependenciesPredicate, Optional.of(newDescription), optionalLayers);
         }
 
+        /**
+         * Configures the rule to ignore any violation from a specific {@code origin} class to a specific {@code target} class.
+         * @param origin A {@link Class} object specifying the origin of a {@link Dependency} to ignore
+         * @param target A {@link Class} object specifying the target of a {@link Dependency} to ignore
+         * @return a {@link LayeredArchitecture} to be used as an {@link ArchRule} or further restricted through a fluent API.
+         */
         @PublicAPI(usage = ACCESS)
         public LayeredArchitecture ignoreDependency(Class<?> origin, Class<?> target) {
             return ignoreDependency(equivalentTo(origin), equivalentTo(target));
         }
 
+        /**
+         * Same as {@link #ignoreDependency(Class, Class)} but allows specifying origin and target as fully qualified class names.
+         */
         @PublicAPI(usage = ACCESS)
-        public LayeredArchitecture ignoreDependency(String origin, String target) {
-            return ignoreDependency(name(origin), name(target));
+        public LayeredArchitecture ignoreDependency(String originFullyQualifiedClassName, String targetFullyQualifiedClassName) {
+            return ignoreDependency(name(originFullyQualifiedClassName), name(targetFullyQualifiedClassName));
         }
 
+        /**
+         * Same as {@link #ignoreDependency(Class, Class)} but allows specifying origin and target by freely defined predicates.
+         * Any dependency where the {@link Dependency#getOriginClass()} matches the {@code origin} predicate
+         * and the {@link Dependency#getTargetClass()} matches the {@code target} predicate will be ignored.
+         */
         @PublicAPI(usage = ACCESS)
         public LayeredArchitecture ignoreDependency(
                 DescribedPredicate<? super JavaClass> origin, DescribedPredicate<? super JavaClass> target) {
@@ -323,6 +335,12 @@ public final class Architectures {
                     irrelevantDependenciesPredicate.add(dependency(origin, target)), overriddenDescription, optionalLayers);
         }
 
+        /**
+         * Allows restricting accesses to or from this layer. Note that "access" in the context of a layer refers to
+         * any dependency as defined by {@link Dependency}.
+         * @param name a layer name as specified before via {@link #layer(String)}
+         * @return a specification to fluently define further restrictions
+         */
         @PublicAPI(usage = ACCESS)
         public LayerDependencySpecification whereLayer(String name) {
             checkLayerNamesExist(name);
@@ -383,6 +401,9 @@ public final class Architectures {
                 this.optional = optional;
             }
 
+            /**
+             * Defines a layer by a predicate, i.e. any {@link JavaClass} that will match the predicate will belong to this layer.
+             */
             @PublicAPI(usage = ACCESS)
             public LayeredArchitecture definedBy(DescribedPredicate<? super JavaClass> predicate) {
                 checkNotNull(predicate, "Supplied predicate must not be null");
@@ -390,6 +411,9 @@ public final class Architectures {
                 return LayeredArchitecture.this.addLayerDefinition(this);
             }
 
+            /**
+             * Defines a layer by package identifiers (compare {@link PackageMatcher})
+             */
             @PublicAPI(usage = ACCESS)
             public LayeredArchitecture definedBy(String... packageIdentifiers) {
                 String description = String.format("'%s'", Joiner.on("', '").join(packageIdentifiers));
@@ -410,38 +434,72 @@ public final class Architectures {
             }
         }
 
+        private enum LayerDependencyConstraint {
+            ORIGIN,
+            TARGET
+        }
+
         public final class LayerDependencySpecification {
             private final String layerName;
-            private final Set<String> allowedAccessors = new LinkedHashSet<>();
-            private final Set<String> allowedTargets = new LinkedHashSet<>();
+            private final Set<String> allowedLayers = new LinkedHashSet<>();
+            private LayerDependencyConstraint constraint;
             private String descriptionSuffix;
 
             private LayerDependencySpecification(String layerName) {
                 this.layerName = layerName;
             }
 
+            /**
+             * Forbids any {@link Dependency dependency} from another layer to this layer.
+             * @return a {@link LayeredArchitecture} to be used as an {@link ArchRule} or further restricted through a fluent API.
+             */
             @PublicAPI(usage = ACCESS)
             public LayeredArchitecture mayNotBeAccessedByAnyLayer() {
-                descriptionSuffix = "may not be accessed by any layer";
-                return LayeredArchitecture.this.addDependencySpecification(this);
+                return denyLayerAccess(LayerDependencyConstraint.ORIGIN, "may not be accessed by any layer");
             }
 
+            /**
+             * Restricts this layer to only allow the specified layers to have {@link Dependency dependencies} to this layer.
+             * @param layerNames the names of other layers (as specified by {@link #layer(String)}) that may access this layer
+             * @return a {@link LayeredArchitecture} to be used as an {@link ArchRule} or further restricted through a fluent API.
+             */
             @PublicAPI(usage = ACCESS)
             public LayeredArchitecture mayOnlyBeAccessedByLayers(String... layerNames) {
-                checkLayerNamesExist(layerNames);
-                allowedAccessors.addAll(asList(layerNames));
-                descriptionSuffix = String.format("may only be accessed by layers ['%s']",
-                        Joiner.on("', '").join(allowedAccessors));
-                return LayeredArchitecture.this.addDependencySpecification(this);
+                return restrictLayers(LayerDependencyConstraint.ORIGIN, layerNames, "may only be accessed by layers ['%s']");
+            }
+
+            /**
+             * Forbids any {@link Dependency dependency} from this layer to any other layer.
+             * @return a {@link LayeredArchitecture} to be used as an {@link ArchRule} or further restricted through a fluent API.
+             */
+            @PublicAPI(usage = ACCESS)
+            public LayeredArchitecture mayNotAccessAnyLayer() {
+                return denyLayerAccess(LayerDependencyConstraint.TARGET, "may not access any layer");
             }
 
+            /**
+             * Restricts this layer to only allow {@link Dependency dependencies} to the specified layers.
+             * @param layerNames the only names of other layers (as specified by {@link #layer(String)}) that this layer may access
+             * @return a {@link LayeredArchitecture} to be used as an {@link ArchRule} or further restricted through a fluent API.
+             */
             @PublicAPI(usage = ACCESS)
             public LayeredArchitecture mayOnlyAccessLayers(String... layerNames) {
-                checkArgument(layerNames.length > 0, "At least 1 layer name should be provided.");
+                return restrictLayers(LayerDependencyConstraint.TARGET, layerNames, "may only access layers ['%s']");
+            }
+
+            private LayeredArchitecture denyLayerAccess(LayerDependencyConstraint constraint, String description) {
+                allowedLayers.clear();
+                this.constraint = constraint;
+                descriptionSuffix = description;
+                return LayeredArchitecture.this.addDependencySpecification(this);
+            }
+
+            private LayeredArchitecture restrictLayers(LayerDependencyConstraint constraint, String[] layerNames, String descriptionTemplate) {
+                checkArgument(layerNames.length > 0, "At least 1 layer name must be provided.");
                 checkLayerNamesExist(layerNames);
-                allowedTargets.addAll(asList(layerNames));
-                descriptionSuffix = String.format("may only access layers ['%s']",
-                        Joiner.on("', '").join(allowedTargets));
+                allowedLayers.addAll(asList(layerNames));
+                this.constraint = constraint;
+                descriptionSuffix = String.format(descriptionTemplate, Joiner.on("', '").join(layerNames));
                 return LayeredArchitecture.this.addDependencySpecification(this);
             }
 
diff --git a/archunit/src/test/java/com/tngtech/archunit/library/ArchitecturesTest.java b/archunit/src/test/java/com/tngtech/archunit/library/ArchitecturesTest.java
index 439894f7..23cd7e54 100644
--- a/archunit/src/test/java/com/tngtech/archunit/library/ArchitecturesTest.java
+++ b/archunit/src/test/java/com/tngtech/archunit/library/ArchitecturesTest.java
@@ -275,18 +275,20 @@ public class ArchitecturesTest {
                         .layer("Allowed").definedBy("..library.testclasses.mayonlyaccesslayers.allowed..")
                         .layer("Forbidden").definedBy("..library.testclasses.mayonlyaccesslayers.forbidden..")
                         .layer("Origin").definedBy("..library.testclasses.mayonlyaccesslayers.origin..")
-                        .whereLayer("Origin").mayOnlyAccessLayers("Allowed"),
+                        .whereLayer("Origin").mayOnlyAccessLayers("Allowed")
+                        .whereLayer("Forbidden").mayNotAccessAnyLayer(),
                 layeredArchitecture()
                         .layer("Allowed").definedBy(
-                        resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.allowed..")
-                                .as("'..library.testclasses.mayonlyaccesslayers.allowed..'"))
+                                resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.allowed..")
+                                        .as("'..library.testclasses.mayonlyaccesslayers.allowed..'"))
                         .layer("Forbidden").definedBy(
-                        resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.forbidden..")
-                                .as("'..library.testclasses.mayonlyaccesslayers.forbidden..'"))
+                                resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.forbidden..")
+                                        .as("'..library.testclasses.mayonlyaccesslayers.forbidden..'"))
                         .layer("Origin").definedBy(
-                        resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.origin..")
-                                .as("'..library.testclasses.mayonlyaccesslayers.origin..'"))
-                        .whereLayer("Origin").mayOnlyAccessLayers("Allowed"));
+                                resideInAnyPackage("..library.testclasses.mayonlyaccesslayers.origin..")
+                                        .as("'..library.testclasses.mayonlyaccesslayers.origin..'"))
+                        .whereLayer("Origin").mayOnlyAccessLayers("Allowed")
+                        .whereLayer("Forbidden").mayNotAccessAnyLayer());
     }
 
     @Test
@@ -297,7 +299,8 @@ public class ArchitecturesTest {
                         "layer 'Allowed' ('..library.testclasses.mayonlyaccesslayers.allowed..')" + lineSeparator() +
                         "layer 'Forbidden' ('..library.testclasses.mayonlyaccesslayers.forbidden..')" + lineSeparator() +
                         "layer 'Origin' ('..library.testclasses.mayonlyaccesslayers.origin..')" + lineSeparator() +
-                        "where layer 'Origin' may only access layers ['Allowed']");
+                        "where layer 'Origin' may only access layers ['Allowed']" + lineSeparator() +
+                        "where layer 'Forbidden' may not access any layer");
     }
 
     @Test
@@ -312,7 +315,10 @@ public class ArchitecturesTest {
                         expectedAccessViolationPattern(
                                 MayOnlyAccessLayersOriginClass.class, "call", MayOnlyAccessLayersForbiddenClass.class, "callMe"),
                         expectedAccessViolationPattern(MayOnlyAccessLayersOriginClass.class, CONSTRUCTOR_NAME, Object.class, CONSTRUCTOR_NAME),
+                        expectedAccessViolationPattern(MayOnlyAccessLayersForbiddenClass.class, CONSTRUCTOR_NAME, Object.class, CONSTRUCTOR_NAME),
+                        expectedAccessViolationPattern(MayOnlyAccessLayersForbiddenClass.class, "callMe", MayOnlyAccessLayersOriginClass.class, CONSTRUCTOR_NAME),
                         expectedInheritancePattern(MayOnlyAccessLayersOriginClass.class, Object.class),
+                        expectedInheritancePattern(MayOnlyAccessLayersForbiddenClass.class, Object.class),
                         expectedFieldTypePattern(MayOnlyAccessLayersOriginClass.class, "illegalTarget", MayOnlyAccessLayersForbiddenClass.class)));
     }
 
@@ -322,7 +328,9 @@ public class ArchitecturesTest {
         JavaClasses classes = new ClassFileImporter().importPackages(absolute("mayonlyaccesslayers"));
 
         architecture = architecture.ignoreDependency(MayOnlyAccessLayersOriginClass.class, MayOnlyAccessLayersForbiddenClass.class)
-                .ignoreDependency(MayOnlyAccessLayersOriginClass.class, Object.class);
+                .ignoreDependency(MayOnlyAccessLayersOriginClass.class, Object.class)
+                .ignoreDependency(MayOnlyAccessLayersForbiddenClass.class, Object.class)
+                .ignoreDependency(MayOnlyAccessLayersForbiddenClass.class, MayOnlyAccessLayersOriginClass.class);
 
         assertThat(architecture.evaluate(classes).hasViolation()).as("result has violation").isFalse();
     }
diff --git a/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/allowed/MayOnlyAccessLayersAllowedClass.java b/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/allowed/MayOnlyAccessLayersAllowedClass.java
index f34e80ad..3eca4882 100644
--- a/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/allowed/MayOnlyAccessLayersAllowedClass.java
+++ b/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/allowed/MayOnlyAccessLayersAllowedClass.java
@@ -1,6 +1,9 @@
 package com.tngtech.archunit.library.testclasses.mayonlyaccesslayers.allowed;
 
+import com.tngtech.archunit.library.testclasses.mayonlyaccesslayers.origin.MayOnlyAccessLayersOriginClass;
+
 public class MayOnlyAccessLayersAllowedClass {
     public void callMe() {
+        new MayOnlyAccessLayersOriginClass();
     }
 }
diff --git a/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/forbidden/MayOnlyAccessLayersForbiddenClass.java b/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/forbidden/MayOnlyAccessLayersForbiddenClass.java
index 461f57d3..ad488a99 100644
--- a/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/forbidden/MayOnlyAccessLayersForbiddenClass.java
+++ b/archunit/src/test/java/com/tngtech/archunit/library/testclasses/mayonlyaccesslayers/forbidden/MayOnlyAccessLayersForbiddenClass.java
@@ -1,6 +1,9 @@
 package com.tngtech.archunit.library.testclasses.mayonlyaccesslayers.forbidden;
 
+import com.tngtech.archunit.library.testclasses.mayonlyaccesslayers.origin.MayOnlyAccessLayersOriginClass;
+
 public class MayOnlyAccessLayersForbiddenClass {
     public void callMe() {
+        new MayOnlyAccessLayersOriginClass();
     }
 }