Breaking Changes
- All deprecated members and classes have been removed (see #909)
@AnalyzeClasses()
without any explicit locations to import will now import the package of the annotated class by default instead of the whole classpath. To restore the old behavior use@AnalyzeClasses(wholeClasspath = true)
(see #828)- The
archunit-junit5-engine-api
now resides within the packagecom.tngtech.archunit.junit.engine_api
instead of directly underjunit
. This only affects users that want to programmatically interface with theArchUnitTestEngine
and should be irrelevant for most users (see #827) - ArchUnit now needs at least Java 8 to run (see #833)
- The ArchUnit types
Function
,Predicate
andOptional
have been replaced by the JDK 8 equivalents DescribedPredicate
now extends the JDK 8Predicate
, soapply(..)
has to be replaced bytest(..)
layeredArchitecture()
now forces to decide how to deal with dependencies by adding.considering...Dependencies()
in the beginning of the declaration. To restore the old behavior declare it aslayeredArchitecture().consideringAllDependencies()
(see #892)ConditionEvents
is now an interface and the interface has been cleaned out of all non-essential methods, e.g.getAllowed()
. This was done to increase maintainability and make it easier to optimize the internals. If you are missing any functionality now, please file an issue to discuss it (see #876)PackageMatcher
was moved from packagebase
tocore.domain
(see #894)- Primitive classes now reside in package
java.lang
to be consistent with the Reflection API'sClass.getPackageName()
(see #905) PlantUmlArchCondition.Configurations
has been merged intoPlantUmlArchCondition.Configuration
(see #891)
Bug Fixes
- While technically no real bug
PlantUmlArchCondition.Configuration
is now a public class instead of an interface, which solves a (non-fatal) Kotlin compiler warning complaining about the access rights (see #888)
Enhancements
Core
- Accesses from inside of lambdas are now correctly detected. Before, the origin was set as a synthetic method like
lambda$xxx$123
instead.JavaAccess
can now be queried forisDeclaredInLambda()
to distinguish this from an access outside of a lambda (see #847; thanks a lot to @oberprah, @FrederikFinckh) - Support for Java 19 (see #845)
- It is now possible to analyze try-catch-blocks, e.g. if a method call is wrapped into a try-catch-block catching a certain exception type (see #591; thanks a lot to @crizzis)
- Package identifiers like
..myapp.service..
now support alternations via..[service|legacy_service]..
. This also works for capturing groups like(a|b)
. Note that alternation groups cannot be nested (see #662; thanks a lot to @Pfoerd) DescribedPredicate
now offers static factory methodsand(predicates)
andor(predicates)
that join together varargsDescribedPredicate<>...
orIterable<DescribedPredicate<>>
via AND or OR (see #805)- The importer now ignores synthetic
$SwitchMap$
fields of enums (see #570) - Private member accesses are now correctly reported between inner classes. Before, the origin was set as a synthetic method
access$123
(see #889) ImportOption.DoNotIncludeTests
now works for plain IntelliJ project layouts (see #696; thanks a lot to @JCook21)
Lang
- New methods
codeUnits().should().onlyBeCalled().by{Classes/Methods/...}That(..)
(see #810; thanks a lot to @JKLedzion) ArchCondition
evaluation is now more efficient and has a smaller memory footprint (see #876)- The
ArchCondition
to search for transitive dependencies has been improved and now only reports relevant dependencies, in particular when checking for transitive dependencies between packagesa
andb
(see #780; thanks a lot to @Pfoerd) - New APIs
ArchCondition.from(predicate)
andArchConditions.{be/have}(predicate)
to easily createArchConditions
fromDescribedPredicates
(see #855; thanks a lot to @u3r) - Javadoc of the rules API has been extended to better guide to predefined
DescribedPredicates
likeJavaClass.Predicates
orHasName.Predicates
(see #912) - New convenience method
ConditionEvent.createMessage(..)
to easily create a standard ArchRule violation message likeClass <..> some description in (...java:123)
(see #826)
Library
layeredArchitecture()
now allows to easily specify how to deal with dependencies from classes within the layers. E.g. should only dependencies that target other classes within the layers be considered? Or all dependencies in the root package of the application? This should solve common confusion about dependencies on classes likejava.lang.Object
being reported (see #887)onionArchitecture()
components can now not only be defined by package identifiers but also by predicates (see #894)layeredArchitecture()
andonionArchitecture()
now supportensureAllClassesAreContainedInArchitecture()
(see #278; thanks a lot to @roxspring)- New rule
GeneralCodingRules.testClassesShouldResideInTheSamePackageAsImplementation()
to check that test classes reside in the same package as their class under test (see #475; thanks a lot to @mslowiak)
JUnit
- The
archunit-junit5
can now be used on the modulepath as well as the classpath (see #206) - JUnit 5 discovery speed is now notably faster in test projects with a lot of dependencies (see #546)
- For JUnit 5 support
@ArchTest
is now also supported within abstract base classes (see #104; thanks a lot to @hankem)
Further Acknowledgement
- thanks a lot to @marknp for migrating the code base to JDK 8 (see #833)
- thanks a lot to @grimsa for improving the Javadoc on
JavaClass.Predicates
(see #814) - thanks a lot to @rweisleder for Javadoc improvements regarding annotation APIs (see #835)
- thanks a lot for various reviews to @hankem, @spanierm42, @kaebiscs, @KorSin, @GandalfIX