Releases: TNG/ArchUnit
Releases · TNG/ArchUnit
ArchUnit 0.18.0
Breaking Changes
JavaClass.get{All}Interfaces()is nowJavaClass.get{All}RawInterfaces()to be consistent with regards to the genericJavaClass.getInterfaces(). We decided that this is still a less painful way than deprecatinggetInterfaces(), introducting a newgetGenericInterfaces(), then deprecategetGenericInterfaces()in favor ofgetInterfaces()in a later release. To be consistent with other places in ArchUnitJavaClass.getInterfaces()needs to provide the generic version of the interfaces (compare e.g.JavaClass.getSuperclass()).
Enhancements
Core
- Support for Java Records (see #295; thanks a lot to @rweisleder)
JavaClassnow knows its generic interfaces (retrievable viaJavaClass.getInterfaces()). Furthermore type arguments of generic interfaces are now part of the JavaClass.directDependencies{From/To}Self (see #551)
Lang
- New syntax methods
classes().that().containAny{Members,Fields,Methods,...}That(..)(see #553; thanks a lot to @nils-christian)
Library
- Added an API to calculate Software Architecture Metrics inspired by John Lakos, Robert C. Martin and Herbert Dowalil. For further details check the user guide (see #572; thanks a lot to @hankem and @stefanhechtltng and to @hdowalil for the inspiration and support)
Further Acknowledgement
- Thanks a lot to @rweisleder and @Strohgelaender for improving the documentation
ArchUnit 0.17.0
Breaking Changes
- The
metaAnnotatedWith(..)predicate, as well as all syntax elements likeclasses().that().areMetaAnnotatedWith(..)orclasses().should().beMetaAnnotatedWith(..), now all also count direct annotations as matching. The background is, that the typical use case always seemed to be "either directly annotated or annotated with some meta-annotated annotation", so we decided to cover this directly.- If your rule has
metaAnnotatedWith(..).or(annotatedWith(..))it still works, but you can now drop theannotatedWith(..)part - If your rule really wanted to test that the annotation is not a direct annotation, but only meta-annotated on another annotation, this can still be asserted by
metaAnnotatedWith(..).and(not(annotatedWith(..)))(see #527)
- If your rule has
Enhancements
- Classes appearing in member signatures (like field types or method return values) are now automatically resolved in import (see #530)
- Support for Java 17 (see #535)
- New API to check if a
JavaAnnotationhas explicitly declared a certain property, i.e. it is set in the annotation and not taken from the default value (see #499)
Lang
- Improved Javadoc and error message to better explain the difference of
classes().that().implement(..)andclasses().that().areAssignableTo(..)
Library
- New rule to assert no proxy bypasses, e.g. if a Spring bean internally calls an
@Asyncmethod and thus bypasses the proxy (see #539)
JUnit
- We decided to rename
ArchRules.in(..)toArchTests.in(..), becauseArchRuleswas considered confusing, if the actual behavior is to collect all@ArchTestmembers of the other class.ArchRulesis still present (yet deprecated), so this will not break existingArchTestsuites (see #525)
ArchUnit 0.16.0
Bug Fixes
- Fix modulepath issue where sometimes classes on the modulepath would not be imported correctly (see #497)
FreezingArchRuledefault violation store now works correctly cross-platform with regards to line separators (see #458, #508)
Enhancements
Core
JavaClassnow knows its generic superclass (retrievable viaJavaClass.getSuperclass()). Furthermore type arguments of generic superclasses are now part of theJavaClass.directDependencies{From/To}Self(see #503)JavaClass/JavaCodeUnitnow know their references to other class objects (e.g.ExampleinList.of(Example.class)). Furthermore class objects are now part of theJavaClass.directDependencies{From/To}Self(see #518)- Added new
ImportOption.OnlyIncludeTeststo executeArchRulesonly on test classes (see #501; thanks a lot to @pstanoev)
Further Acknowledgement
- Thanks a lot to @rweisleder for improving the ArchUnit CI
- Thanks a lot to @perlun for improving the Imprint
- Thanks a lot to @sullis for upgrading the SLF4J dependency
- Thanks a lot to @Bananeweizen for improving the user guide
ArchUnit 0.15.0
Bug Fixes
TextFileBasedViolationStorenow correctly handles empty violation store files (see #456; thanks a lot to @hankem)- Fix URL scheme part issue on Windows when reading classpath URLs from manifest files (see #414; thanks a lot to @eriklumme)
Enhancements
Core
- Reduce excessive logging if
archunit.propertiesare overwritten by system properties (see #375; thanks a lot to @ldebruijn) - New method
JavaClass.tryGetConstructor()(see #386; thanks a lot to @rweisleder) JavaClassnow provides generic type information, i.e. there is nowJavaClass.getTypeParameters()(see #398). FurthermoreJavaClassnow reports type parameter bounds asDependencies(see #484)JavaClassnow offersJavaClass.getInstanceofChecks(), which are also reported asDependencies(see #371; thanks a lot to @t-h-e)- Support for Java 15 and 16-ea (see #409)
- Resolve imported annotations transitively with the configured
ClassResolver(i.e. by default from the classpath). This will make detection of meta-annotations work out of the box now in many cases, without the need to explicitly import these meta-annotation types as well (see #342, #450; thanks a lot to @KorSin) - New method
JavaClass.getBaseComponentType()(see #441; thanks a lot to @hankem) - Component types (i.e.
Stringfor an arrayString[]) are now detected as dependencies ofJavaClass(see #257; thanks a lot to @wengertj) - New method
..archunit..Optional.getOrThrow(Supplier)(see #391; thanks a lot to @idosal) - New method
JavaClass.getTransitiveDependenciesFromSelf()(see #401; thanks a lot to @hankem)
Lang
- New syntax
members().that().haveName{StartingWith/Containing/EndingWith}(..)andmembers().should().haveName{StartingWith/Containing/EndingWith}(..)(see #239; thanks a lot to @kamer) - Improve
CompositeArchRule.of(..)to accept anIterableofArchRule(see #384; thanks a lot to @sullis) - Clarify difference between
accessanddependin rule Javadocs (see #313; thanks a lot to @idosal) - New syntax
classes().that().are{Not}Annotations()(see #468) - New syntax
classes().that().doNotBelongToAnyOf(..)(see #422; thanks a lot to @perlun)
Further Acknowledgement
- Thanks a lot to @rweisleder for improving the ArchUnit user guide, development documentation and build
- Thanks a lot to @spanierm for improving OS-JDK-matrix CI builds with GitHub Actions
- Thanks a lot to @gernotstarke for website and documentation improvements (see #478 and #479)
- Thanks a lot to @kamilszymanski and @dariuszzbyrad for Javadoc improvements and code cleanups
- Thanks a lot to @sullis for upgrading various build dependencies
- Thanks a lot to @cristiangreco for introducing Upgrade Gradle Wrapper Action (see #486)
ArchUnit 0.14.1
Bug Fixes
- Fix broken Gradle metadata: Migrating the legacy Maven Plugin to the Publish Plugin caused some broken Gradle metadata published to Maven Central by accident. While
0.14.0should work fine with any other build tool like Maven, Gradle will complain about a missing artifactarchunit-junit, which does in fact not exist. This release fixes this by removing the broken metadata.
ArchUnit 0.14.0
Breaking Changes
- All methods that have been deprecated up to ArchUnit
0.12.0have been removed. It might make sense to look through your code for usage of deprecated methods and follow the advice in the Javadoc before upgrading (see #329; thanks a lot to @rweisleder for removing the old deprecations)
Bug Fixes
- Fix for Android where some classes were not imported correctly when run from the command line (see #319; also thanks a lot to @rweisleder for fixing the subsequent URI problems on Windows)
- Fixed surprising behavior when using
only{Call/Access}...That()...where the target of the call could not be resolved from the imported classes (see #340)
Enhancements
Core
JavaPackagenow offers methods to retrieve the annotations of the respectivepackage-info(see #263; thanks a lot to @rweisleder)ClassFileImporter.importClasspath()now respects anyImportOptionspassed viawithImportOption(..)(see #296; thanks a lot to @rweisleder)JavaMethodandJavaConstructornow have a heuristic line number instead of constant0(see #344; thanks a lot to @hankem)
Library
- The algorithm to detect cycles between slices has been improved from BFS to Johnson/Tarjan (see #138; thanks a lot to @torfmaster)
- Cycle detection now has a configurable limit for the max number of cycles to detect (by default 100) and a max number of violations reported (by default 20 dependencies per edge). This can be reconfigured according to the user guide (see #326)
onionArchitecture()now supports toignoreDependency(..)analogously tolayeredArchitecture()(see #318; thanks a lot to @hankem)- There now is a rule to forbid field injection in favor of constructor injection (see #288; thanks a lot to @rweisleder)
- There now is a rule to forbid dependencies on upper packages (see #151; thanks a lot to @qoomon for the initiative and POC)
JUnit
@ArchIgnore,@ArchTagand@ArchTagsare now usable as meta-annotations to compose custom annotations that inherit the behavior (analogous to https://junit.org/junit5/docs/current/user-guide/#writing-tests-meta-annotations; see #282; thanks a lot to @daniel-shuy)- Upgraded dependencies
junit-platform-*from1.5.2to1.6.2
Further Acknowledgement
ArchUnit 0.13.1
Bug Fixes
- Fixed
java.lang.IllegalStateException: Couldn't find module modules of URI jrt:/...being thrown when trying to import JDK classes where JDK version >=13. The path handling ofJrtFileSystemProviderhas been fixed according toJEP-220with JDK 13. Unfortunately ArchUnit was dependent on the old behavior. (see #303)
ArchUnit 0.13.0
Breaking Changes
- While technically a very slim chance of really "breaking" anything, the log level of some details during the class file import has been reduced from
DEBUGtoTRACE(field, method, access and call details, ...) (see #291)
Enhancements
Core
- Annotations and annotation parameters are now detected as dependencies. This could cause new findings when using the rules or library API. In particular
JavaClass.getDirectDependencies{From/To}Self()will now also returnDependenciesthat originate from@FormerlyNotDetectedor@Foo(someEnum = SomeEnumFormerlyNotDetected.FOO)or@Foo(bar = @Bar(type = SomeTypeFormerlyNotDetected.class))(see #136; thanks a lot to @kosani)
Lang
- Some rule API method parameter types were invariant instead of contravariant (effectively preventing a predicate for a super type to be passed). These methods should now be fixed (see #262)
- The rules API now offers more methods to filter and assert the type of class declaration ("top level class", "nested class", "member class", "inner class", "anonymous class" and "local class") (see #207; many thanks to @rweisleder)
Library
FreezingArchRuleby default now not only ignores line numbers, but also numbers after$which effectively makes theViolationStoreresilient against changes in compiled lambda and anonymous class names (see #248; thanks a lot to @hankem)LayeredArchitectureandOnionArchitecturenow allow to configureoptionalLayers(). In version0.12.0the behavior was made more strict, forbidding empty layers / parts ofLayeredArchitectureandOnionArchitectureto prevent misconfiguration. This in turn unfortunately broke some valid use cases where empty / optional layers were in fact okay. In version0.13.0this is now completely configurable. By default it will still fail to prevent misconfiguration, but a switch ofwithOptionalLayers(true)oroptionalLayer("Some Layer")will allow empty layers (and in turn empty parts ofOnionArchitecture) (see #267 and #271; many thanks to @hankem)
JUnit
- there is now a ArchUnit JUnit 5 aggregator POM, i.e. instead of two dependencies
archunit-junit5-apiandarchunit-junit5-engine, it is now also possible to simply add a single dependencyarchunit-junit5with scopetest/testCompile. Compare the user guide (see #272; thanks a lot to @eddumelendez) - Dependency upgrades (see #292)
junit-platform-*from1.5.1to1.5.2junit4from4.12to4.13(in case of problems witharchunit-junit4it should be possible to exclude the transitive dependency to JUnit4.13and replace it by a custom4.12one)
Further Acknowledgement
- Many thanks to @Bananeweizen for fixing spelling and grammar mistakes in Javadoc / methods
ArchUnit 0.12.0
Breaking Changes
- So far ArchUnit's terminology has been a little sloppy with respect to the naming of inner and nested classes. By the JLS "inner classes" are those classes that are nested and not static. ArchUnit's API now reflects this via
JavaClass.isNestedClass()versusJavaClass.isInnerClass(). Unfortunately this means that the method formerly calledJavaClass.isInnerClass()will now return a different result, i.e. it will only returntrue, if the class is non-static. On the other hand, the methodJavaClass.isNestedClass()will behave exactly likeisInnerClass()did in ArchUnit 0.11.0 (see #224; thanks a lot to @rweisleder for the clarification and PR) JavaAccessConditiondoes not filter self-accesses anymore. This was confusing behavior that did not solve the issue it was originally intended for. However, this might lead to additional violations showing up (see #209)
Bug Fixes
- Fixed bug where simple name of local classes was incorrect (see #216; thanks a lot to @rweisleder)
staticmodifier was missing from nested classes (see #219; thanks a lot to @rweisleder)
Enhancements
Core
- Support for Java 14 (see #230; thanks a lot to @hankem)
JavaModifiernow containsSYNTHETICandBRIDGEallowing more introspection and filtering of synthetic members (see #243; thanks a lot to @alexfedorenchik)- Every property in
archunit.propertiescan now be overwritten by passing a system property. This can be valuable in CI environments, e.g. to specify theViolationStorepath forFreezingArchRule. Compare the user guide (see #252) - A
JavaClassrepresenting an array can now be queried for its component type (see #187; thanks a lot to @alexfedorenchik) JavaClassnow offers a classpath independent version ofgetMethod(..)andgetConstructor(..)(see #236; thanks a lot to @rweisleder)
Lang
- Extended syntax for
classes().thatAreEnums()andclasses()...should().beEnums()(see #172; thanks a lot to @rweisleder)
Library
LayeredArchitecturenow also checks that no layer is empty. While originally with good intentions, the ability to define empty layers turned out to do more harm than good (see #177; thanks a lot to @mikomatic)LayeredArchitecturenow allows layers to be defined by predicate. This allows for a way more flexible definition than simple package patterns (see #228; thanks a lot to @mikomatic)FreezingArchRulecan now be configured to be more strict, when checking rules. In particular it is possible to forbid updates of theViolationStoreor the creation of a newViolationStore. This can serve as a safeguard in CI environments, where a missingViolationStoreis typically a misconfiguration. Compare the user guide (see #211; thanks a lot to @hankem for reviewing and providing valuable improvements)
ArchUnit 0.11.0
Enhancements
Core
DescribedPredicatenow offers a more lambda compatible factory methodDescribedPredicate.describe(description, predicate)(see #188; thanks a lot to @jzheaux)- New factory method
DescribedPredicate.allElements(..)to complementDescribedPredicate.anyElementThat(..)(see b8890f4) - Support for JDK 13 (see #195; thanks a lot to @jqno)
- ArchUnits configuration (
archunit.properties) and ignore patterns (archunit_ignore_patterns.txt) are now loaded with theContextClassLoaderinstead of theClassLoaderof the respective class (see 81c31f6)
Lang
- New method
classes().that().belongToAnyOf(..)to match any class or inner class of the passed classes (see #173; thanks a lot to @moboa) - New method
classes().should().haveOnlyPrivateConstructors()(see #204; thanks a lot to @sullis) - New methods
members().should().{have,notHave}FullName[Not][Matching](..)(see #205; thanks a lot to @hankem)
Library
- New
FreezingArchRuleto wrap any otherArchRuleand change the behavior (see #181):- on the first run record all existing violations
- on further runs only fail by unknown violations
- also on further runs automatically decrease the stored violation count if existing violations are solved
- compare the user guide
- New
Architectures.onionArchitecture()API offering a predefined API for Onion or Hexagonal Architectures, compare the user guide (see #174; thanks a lot to @spanierm)
JUnit
- The JUnit 5 platform dependency has been upgraded to version 1.5.1
Further Acknowledgement
- Thanks a lot to @hankem for adjusting Spotbugs to ignore false positives with JDK 9
- Thanks a lot to @hankem for fixing incompatibilities of some tests with JDK 12
- Thanks a lot to @vincent-fuchs for improving ArchUnit's logging
- Thanks a lot to @sullis for upgrading dependencies