Releases: TNG/ArchUnit
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.0
should 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.0
have 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
JavaPackage
now offers methods to retrieve the annotations of the respectivepackage-info
(see #263; thanks a lot to @rweisleder)ClassFileImporter.importClasspath()
now respects anyImportOptions
passed viawithImportOption(..)
(see #296; thanks a lot to @rweisleder)JavaMethod
andJavaConstructor
now 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
,@ArchTag
and@ArchTags
are 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.2
to1.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 ofJrtFileSystemProvider
has been fixed according toJEP-220
with 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
DEBUG
toTRACE
(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 returnDependencies
that originate from@FormerlyNotDetected
or@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
FreezingArchRule
by default now not only ignores line numbers, but also numbers after$
which effectively makes theViolationStore
resilient against changes in compiled lambda and anonymous class names (see #248; thanks a lot to @hankem)LayeredArchitecture
andOnionArchitecture
now allow to configureoptionalLayers()
. In version0.12.0
the behavior was made more strict, forbidding empty layers / parts ofLayeredArchitecture
andOnionArchitecture
to prevent misconfiguration. This in turn unfortunately broke some valid use cases where empty / optional layers were in fact okay. In version0.13.0
this 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-api
andarchunit-junit5-engine
, it is now also possible to simply add a single dependencyarchunit-junit5
with scopetest
/testCompile
. Compare the user guide (see #272; thanks a lot to @eddumelendez) - Dependency upgrades (see #292)
junit-platform-*
from1.5.1
to1.5.2
junit4
from4.12
to4.13
(in case of problems witharchunit-junit4
it should be possible to exclude the transitive dependency to JUnit4.13
and replace it by a custom4.12
one)
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) JavaAccessCondition
does 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)
static
modifier 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)
JavaModifier
now containsSYNTHETIC
andBRIDGE
allowing more introspection and filtering of synthetic members (see #243; thanks a lot to @alexfedorenchik)- Every property in
archunit.properties
can now be overwritten by passing a system property. This can be valuable in CI environments, e.g. to specify theViolationStore
path forFreezingArchRule
. Compare the user guide (see #252) - A
JavaClass
representing an array can now be queried for its component type (see #187; thanks a lot to @alexfedorenchik) JavaClass
now 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
LayeredArchitecture
now 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)LayeredArchitecture
now 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)FreezingArchRule
can now be configured to be more strict, when checking rules. In particular it is possible to forbid updates of theViolationStore
or the creation of a newViolationStore
. This can serve as a safeguard in CI environments, where a missingViolationStore
is 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
DescribedPredicate
now 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 theContextClassLoader
instead of theClassLoader
of 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
FreezingArchRule
to wrap any otherArchRule
and 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
ArchUnit 0.10.2
Bug Fixes
- Fixed
JavaPackage.getPackageDependenciesFromSelf()
containing the package itself if there was a dependency in the same package but not directly imported (e.g.importer.importClasses(Foo.class)
wheresome.pkg.Foo
would depend onsome.pkg.Bar
, which was not imported)
Enhancements
Core
- Some methods now return
Collection
types instead ofIterable
to integrate nicer with streams
Lang
FieldsShould
now contains the negationnotHaveRawTypes
(see #162; thanks a lot to @asbachb)CodeUnitsShould
now contains the negationsnotHaveRawParameterTypes
,notHaveRawReturnType
andnotDeclareThrowableOfType
- The syntax now contains
{methods,fields}().should().{be,notBe}{Static,Final}
(see #164; thanks a lot to @hankem)
Library
Slice
now also offersdependenciesToSelf
additionally todependenciesFromSelf
Further Acknowledgement
- Thanks a lot to @hankem for reviewing and improving the user guide
ArchUnit 0.10.1
Bug Fixes
JavaPackage.PackageVisitor
andJavaPackage.ClassVisitor
are now public instead of package-private to be usable as public API
ArchUnit 0.10.0
Breaking Changes
- The deprecated method
String JavaClass.getPackage()
was replaced byJavaPackage JavaClass.getPackage()
. To query the package name, please useString JavaClass.getPackageName()
. - The deprecated method
JavaClass.getDirectDependencies()
has been removed -> useJavaClass.getDirectDependenciesFromSelf()
instead - The deprecated field
JavaClass.Functions.SIMPLE_NAME
has been removed, please useJavaClass.Functions.GET_SIMPLE_NAME
New Deprecation
- ArchUnit does not use contractions anymore within the rules API. So far many methods were phrased like
dontHave...()
instead ofdoNotHave...()
. In general this seems to be more trouble than worth it and does not read that well without an apostrophe, so all those methods were declared deprecated and have a new counter part without the contraction. A simple search & replace ofdont
bydoNot
should fix all those deprecations. - Some methods were deprecated because they were not precise enough, if generics come into play. For example
JavaClass JavaField.getType()
is not precise enough, because the type of a field is something else than aJavaClass
(likeT someField
orList<? extends T> someField
). Thus all those methods have been deprecated to make room for a future extension with generics and instead got a new version explicitly stating that the "raw type" is meant. For exampleJavaField.getType()
->JavaField.getRawType()
,JavaMethod.getParameters()
->JavaMethod.getRawParameterTypes()
. Formatters.formatLocation(JavaClass, lineNumber)
was deprecated in favor of the newly introducedSourceCodeLocation.of(JavaClass, lineNumber)
which will report the correct location (i.e. link for IDEs) viatoString()
Enhancements
Core
- The default class resolution behavior for classes missing from the import was changed. Before by default missing classes were replaced by stubs, now by default they will be resolved from the classpath. Compare the user guide (see #111)
JavaClass
can now be queried for declared throws clauses, anyThrowables
declared on methods or constructors count as dependencies of aJavaClass
(see #126; thanks a lot to @tngwoerleij)JavaClass
can now be queried if it is an array (see #114; thanks a lot to @wengertj)- The resolution of classes from the classpath will now use the context
ClassLoader
if set (should usually not make any difference, but allows to control theClassLoader
used by ArchUnit for class resolution) JavaClass
now has a more sophisticatedJavaPackage
attached to it. It is also possible to retrieve anyJavaPackage
fromJavaClasses
.JavaPackage
offers a more convenient API for dependencies between packages (see #158; thanks a lot to @goetzd for reviewing and user guide adjustment)- For arrays
JavaClass.getPackageName()
now returns the package of the component type instead of empty. While empty is closer to the Java Reflection API, it is not really useful from a point of view of dependencies. Using an array of a type in a package should cause a dependency to that package (see #161)
Lang
- The rules API now provides an extensive support for checks of members / methods / fields (see #38; thanks a lot to @hankem for an extensive review and many improvements)
Library
- It is now possible to create a
CompositeArchRule
from severalArchRules
to check multiple rules at once (see #78; thanks a lot to @bogsi17) - The PlantUML rules API now understands more types of arrows (description on arrows, arrows from right to left, arrow colors), compare the user guide (see #135)
- New predefined rule to avoid the use of
org.joda.time
in favor of thejava.time
API (see #145; thanks a lot to @sullis) - The slices API is now more configurable to deal with inconsistent package structures and legacy projects. It is now possible to customize the assignment of
JavaClasses
toSlices
by a simple functionJavaClass
->Identifier
, compare the user guide (see #156)
JUnit
- The JUnit 5 platform dependency has been upgraded to version
1.4.0
.
Further Acknowledgement
- Thanks a lot to @alanktwong for improving the CONTRIBUTING docs on how to build the project
- Thanks a lot to @wengertj for removing use of deprecated Gradle API
- Thanks a lot to @olleolleolle for replacing the PNG build badge by SVG
- Thanks a lot to @sullis for updating the Travis build to use OpenJDK 11
ArchUnit 0.9.3
Bug Fixes
Fixed memory leak in combination of the newly added ArchRule.AssertionError
and JUnit 4. JUnit 4 keeps references to all thrown AssertionErrors
through the whole run. Since ArchRule.AssertionError
kept a reference to EvaluationResult
this could consume a lot of memory, if the respective results were big.
This release removes ArchRule.AssertionError
(introduced in version 0.9.0).
Note that this is in theory a breaking change, since it would have been possible to catch and process ArchRule.AssertionError
. There does not seem to be any clean solution to this problem though, and due to the slim probability that the removal of this part of the API will in fact affect any user, the step seems justified.
If anybody should against all odds have a problem with this, feel free to open an issue and we will find a different solution.
Also ArchUnitTestEngine
's engine id has been adjusted from junit-archunit
to archunit
to get rid of the warning JUnit 5 emits since version 1.3.0
.