Releases: TNG/ArchUnit
Releases · TNG/ArchUnit
ArchUnit 0.23.0
Breaking Changes
- As mentioned in Enhancements/Core
ArchRules
will now by default reject evaluating if the set passed to theshould
-clause is empty. This will break existing rules that don't check any elements in theirshould
-clause. You can restore the old behavior by setting the ArchUnit propertyarchRule.failOnEmptyShould=false
Bug Fixes
- Fix wrong origins of
JavaCall
in case of bridge methods. If a class had two methods with the exact same name and parameter types theorigin
of aJavaCall
was picked randomly from them. It now always picks the non-synthetic method (see #513) - Fix non-deterministic return value of
JavaCodeUnit.getMethod()
. In case of bridge methods there might be more than one method matching the exact same name and parameters. In these cases the result ofgetMethod()
was random. It now always picks the non-synthetic method (see #256) layeredArchitecture()
will now allow to combinemayOnlyBeAccessedBy...
andmayOnlyAccess...
. PreviouslymayOnlyAccess...
would forbid all incoming dependencies (see #739; thanks a lot to @hankem)
Enhancements
Core
- Members targeted by
AccessTarget
are now resolved like the Java Reflection API would do it. PreviouslyAccessTarget.resolve()
would return a set of matching members, the new replacementAccessTarget.resolveMember()
returns an optional member making it a lot easier to handle (see #722) JavaClass
now knows itsmethodReferencesFromSelf
(e.g.Object::toString
) andconstructorReferencesFromSelf
(e.g.Object::new
) (see #215; thanks a lot to @KorSin)ArchRules
will now by default reject evaluating if the set passed to theshould
-clause is empty. This prevents implementation errors like picking a package inthat()...
that doesn't even exist and thus composing a rule that doesn't check anything (compare the user guide; see #774; thanks a lot @oberprah)- The automatic import dependency resolution now resolves classes missing from the import that are only referenced
- as class object (e.g. Foo.class)
- in a throws clause (e.g.
someMethod() throws FooException
) - in an instanceof check (e.g.
obj instanceof Foo
) - as an array component type (e.g.
Foo[] array;
) - as an annotation parameter (e.g.
@SomeAnnotation(type = Foo.class)
) - as part of a generic type signature (e.g.
List<? extends Foo>
) - Furthermore, the resolution behavior can now be tweaked to resolve deeper or not resolve at all. Thus, users can decide between resolving additional types and performance (compare the user guide; see #728)
- New predefined
ImportOption
to excludepackage-info.class
files (see #793; thanks a lot to @TomerFi)
Lang
- Analogously to
classes()
, there now exists a methodmembers()...should().containNumberOfElements(predicate)
(see #179; thanks a lot to @oberprah)
Library
PlantUmlArchCondition
now rejects files that don't specify any components at all or are of an invalid format (see #735; thanks a lot to @pfichtner)
JUnit
- Tests can now be run if their classes are loaded by the context
ClassLoader
instead of the ArchUnitClassLoader
(see #781; thanks a lot to @stuartwdouglas) - New method
Class<?> FieldSource.getJavaClass()
to retrieve the declaring class of the respective field (see #800; thanks a lot to @famod)
Further Acknowledgement
- thanks a lot to @marknp for improving the Javadoc on
ArchConditions
(see #725) - thanks a lot to @timtebeek for making the ArchUnit build work with JDK 17 (see #779)
ArchUnit 0.22.0
Bug Fixes
- Java class file URLs with spaces are now correctly handled when resolving transitive dependencies (see #683)
- fixed memory leak in ArchUnit JUnit 5 support (see #695)
- three bug fixes regarding generics import (see #700)
- toplevel generic array types (e.g.
T[]
) were not detected correctly as method parameters - primitive types were missing from the generic
JavaCodeUnit.getParameterTypes()
- inner classes were not detected correctly as upper bounds of type parameters
- toplevel generic array types (e.g.
Enhancements
Core
- support for method and constructor parameter annotations (see #701; thanks a lot to @hankem for extensive reviews)
- new method
JavaCodeUnit.getParameters()
that will return parameters in a structured form offering raw type, generic type and annotations - new method
JavaCodeUnit.getParameterAnnotations()
that offers just parameter annotations by index - parameter annotations are now part of
JavaClass.directDependencies{from/to}Self
- new method
SourceCodeLocation
now offers structured access to source file and source class (see #673; thanks a lot to @thmuch)
JUnit
ArchUnit 0.21.0
Breaking Changes
- the type
JavaClassList
has been removed completely. It was used inconsistently and provided very limited value (convenient way to get the names of the classes). On the other hand having a custom list implementation increases maintenance overhead and limits options in the future. Please replace usages ofJavaClassList.getNames()
by the static utilityHasName.Utils.namesOf(classes)
which can be used on anyIterable
with elements of typeHasName
(see #633)
Enhancements
Core
JavaMethod
now knows its generic parameter types (retrievable viaJavaMethod.getParameterTypes()
). Furthermore type arguments of generic method parameter types are now part of theJavaClass.directDependencies{From/To}Self
(see #640)
Library
Further Acknowledgement
- thanks a lot to @NilsOliverLinden for further automating the release process (see #646)
ArchUnit 0.20.1
Bug Fixes
- Fix bug where some anonymous classes compiled with JDK 7 could not be imported anymore (
java.lang.IllegalArgumentException: Can't register multiple enclosing classes, this is likely a bug!
) (see #637)
ArchUnit 0.20.0
Bug Fixes
onionArchitecture()
no longer loses ignored dependencies, if the description is changed afterwards (see #623; thanks a lot to @thmuch)
Enhancements
Core
- added support for JDK 18 (see #625; thanks a lot to @hankem)
- new method
JavaCodeUnit.getTypeParameters()
. Also the bounds of these type parameters have been added toJavaClass.directDependencies{From/To}Self
(see #616; thanks a lot to @hankem for extensive reviews) JavaMethod
now knows its generic return type (retrievable viaJavaMethod.getReturnType()
). Furthermore type arguments of generic method return types are now part of theJavaClass.directDependencies{From/To}Self
(see #616; thanks a lot to @hankem for extensive reviews)
JUnit
- upgraded JUnit Platform dependency from
1.7.1
to1.7.2
(see #628)
ArchUnit 0.19.0
Bug Fixes
- The last release archive contained a couple of classes from dependencies that were not relocated and thus lead to duplicate classes warnings in some environments. These classes have been removed (see #593)
Enhancements
Core
JavaField
now knows its generic type (retrievable viaJavaField.getType()
). Furthermore type arguments of generic field types are now part of theJavaClass.directDependencies{From/To}Self
(see #595; thanks a lot to @hankem for extensive reviews)
Lang
- new method
noClasses()...should().transitivelyDependOnClassesThat(..)...
(see #575; thanks a lot to @hankem) - the failure descriptions of
ArchRules
can not be customized (see #343; thanks a lot to @Farbauti89)
Library
- new method
layeredArchitecture()...mayOnlyAccessLayers(..)...
(see #592; thanks a lot to @GiorgadzeLuka) - improved readability for cycle rule violations (see #369; thanks a lot to @jzheaux)
FreezingArchRule
can now refreeze all violations, if current violations should simply be added to theViolationStore
without any failure (see #510)
JUnit
- annotations of test methods and fields are now passed to the
TestDescription
by the JUnit 4 test support (see #552)
Further Acknowledgement
- Thanks a lot to @GiorgadzeLuka and @OLibutzki for improving the documentation
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)
JavaClass
now 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
JavaAnnotation
has 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
@Async
method and thus bypasses the proxy (see #539)
JUnit
- We decided to rename
ArchRules.in(..)
toArchTests.in(..)
, becauseArchRules
was considered confusing, if the actual behavior is to collect all@ArchTest
members of the other class.ArchRules
is still present (yet deprecated), so this will not break existingArchTest
suites (see #525)
ArchUnit 0.16.0
Bug Fixes
- Fix modulepath issue where sometimes classes on the modulepath would not be imported correctly (see #497)
FreezingArchRule
default violation store now works correctly cross-platform with regards to line separators (see #458, #508)
Enhancements
Core
JavaClass
now 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
/JavaCodeUnit
now know their references to other class objects (e.g.Example
inList.of(Example.class)
). Furthermore class objects are now part of theJavaClass.directDependencies{From/To}Self
(see #518)- Added new
ImportOption.OnlyIncludeTests
to executeArchRules
only 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
TextFileBasedViolationStore
now 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.properties
are overwritten by system properties (see #375; thanks a lot to @ldebruijn) - New method
JavaClass.tryGetConstructor()
(see #386; thanks a lot to @rweisleder) JavaClass
now provides generic type information, i.e. there is nowJavaClass.getTypeParameters()
(see #398). FurthermoreJavaClass
now reports type parameter bounds asDependencies
(see #484)JavaClass
now 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.
String
for 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 anIterable
ofArchRule
(see #384; thanks a lot to @sullis) - Clarify difference between
access
anddepend
in 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)