Skip to content

Releases: TNG/ArchUnit

ArchUnit 1.2.0

Choose a tag to compare

@codecholeric codecholeric released this 06 Nov 00:30

Enhancements

Core

  • Add support for Java 22 (see #1172; thanks a lot to @hankem)
  • New methods {JavaType/JavaMember}.getAllInvolvedRawTypes() to quickly detect all raw types contributing to a type (e.g. List<? extends Serializable>) or member (e.g. List<? extends Serializable> method(Set<String> args) {..}) (see #723; thanks a lot to @leonardhusmann)

Lang

  • New rules API FieldsShould.{be/notBe}AccessedByMethodsThat(predicate) to prevent fields from being accessed by certain methods (see #857; thanks a lot to @leonardhusmann)

Library

  • New extensive modules rule syntax to support easier checks for modularization (dependency direction, API surface, ...) (compare the user guide; see #1078)

JUnit

Further Acknowledgement

ArchUnit 1.1.0

Choose a tag to compare

@codecholeric codecholeric released this 09 Aug 14:55

Bug Fixes

  • Try-Catch-Blocks declared within lambdas will now be detected correctly (see #1069)
  • Fix ArchUnit not being able to find classes loaded by Spring Boot ClassLoader (see #1131; thanks a lot to @odrotbohm)

Enhancements

Core

  • New ImportOption DoNotIncludeGradleTestFixtures (see #949)
  • Reduce all log levels except WARN to TRACE (see #1050)
  • Add support for Java 21 (see #1098)

Library

  • Two new GeneralCodingRules (see #970; thanks a lot to @hankem)
    • ASSERTIONS_SHOULD_HAVE_DETAIL_MESSAGE
    • DEPRECATED_API_SHOULD_NOT_BE_USED
  • TextFileBasedViolationStore is now part of the public API and can thus be used for customization; as a special case of this file names can now be adjusted (see #1046; thanks a lot to @danhaywood)
  • TextFileBasedViolationStore now adds a final new line character to the violation file to better conform to the spec (see #1057; thanks a lot to @pkubowicz)

ArchUnit 1.0.1

Choose a tag to compare

@codecholeric codecholeric released this 21 Nov 18:21

Bug Fixes

  • Fix bug where referenced class objects and instanceof checks were not detected if declared within a lambda (see #992)
  • Fix empty records not being detected as records (see #998; thanks a lot to @hankem)
  • Fix Javadoc on layeredArchitecture() missing the new consideringDependencies part (see #977; thanks a lot to @Thunderforge)
  • Fix user guide still showing DescribedPredicate.apply instead of .test (see #978; thanks a lot to @thmuch)

ArchUnit 1.0.0

Choose a tag to compare

@codecholeric codecholeric released this 03 Oct 18:04

⚠️ If you upgrade from the latest 0.x version, please also refer to the release notes of release candidate 1.0.0-rc1 as these release notes refer to upgrading from the release candidate ⚠️

Breaking Changes

  • Naming around JavaPackage subpackages and dependencies has been improved to remove ambiguities. In general, whenever all classes from a package and subpackages recursively are involved, this is now called "package tree". Otherwise, it only targets the classes directly within this package (see #919/#968; thanks a lot to @grimsa)
    The following mapping shows how to translate the old methods to the current methods:
    • getAllClasses() -> getClassesInPackageTree()
    • getAllSubpackages() -> getSubpackagesInTree()
    • getClassDependenciesFromSelf() -> getClassDependenciesFromThisPackageTree()
    • getClassDependenciesToSelf() -> getClassDependenciesToThisPackageTree()
    • getPackageDependenciesFromSelf() -> getPackageDependenciesFromThisPackageTree()
    • getPackageDependenciesToSelf() -> getPackageDependenciesToThisPackageTree()
    • accept(..) -> traversePackageTree(..)
  • Importing the default package via ClassFileImporter.importPackages("") will now yields the same result as using importClasspath() without any ImportOption (see #954)
  • ClassFileImporter.importClasspath() now behaves consistently to other import APIs. I.e. no default ImportOptions like DoNotIncludeArchives are added anymore, instead all ImportOptions need to be added the same way as for all other import methods (see #958)
  • The custom collection ImportOptions has been removed from the public API and been replaced by a standard Collection<ImportOption> where appropriate (see #958)
  • The package com.tngtech.archunit.library.plantuml has been moved to com.tngtech.archunit.library.plantuml.rules to make room for adding other PlantUML related features (see #959)
  • SLF4J-API has been upgraded from 1.7.30 to 2.0.3, so any log adapter dependency to be used with ArchUnit (e.g. to hook in Log4J) has to be compatible with SLF4J-API 2.x from now on (see #966)

Bug Fixes

  • Fix bug where multiple synthetic access calls to methods like access$123(..) would lead to only one access being imported. Note, that these synthetic methods are added for calls to private fields / methods from inner classes to outer classes, etc. (see #957)

Enhancements

Lang

  • archunit_ignore_patterns.txt is now also respected by FreezingArchRule. Thus, ignored violations are not added to the ViolationStore anymore (see #915)

Library

  • testClassesShouldResideInTheSamePackageAsImplementation(..) now supports multiple test classes with same simple name (see #918; thanks a lot to @mslowiak)
  • PlantUmlArchCondition now does not throw exceptions anymore, if a class is in none or multiple components, but instead reports those as standard violations. This way these violations can also be frozen via FreezingArchRule instead of crashing the test (see #960)

Further Acknowledgement

  • Thanks a lot to @hankem for upgrading various dependencies, cleaning up code and extensive reviews

ArchUnit 1.0.0-rc1

Choose a tag to compare

@codecholeric codecholeric released this 13 Jul 18:11

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 package com.tngtech.archunit.junit.engine_api instead of directly under junit. This only affects users that want to programmatically interface with the ArchUnitTestEngine 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 and Optional have been replaced by the JDK 8 equivalents
  • DescribedPredicate now extends the JDK 8 Predicate, so apply(..) has to be replaced by test(..)
  • 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 as layeredArchitecture().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 package base to core.domain (see #894)
  • Primitive classes now reside in package java.lang to be consistent with the Reflection API's Class.getPackageName() (see #905)
  • PlantUmlArchCondition.Configurations has been merged into PlantUmlArchCondition.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 for isDeclaredInLambda() 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 methods and(predicates) and or(predicates) that join together varargs DescribedPredicate<>... or Iterable<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 packages a and b (see #780; thanks a lot to @Pfoerd)
  • New APIs ArchCondition.from(predicate) and ArchConditions.{be/have}(predicate) to easily create ArchConditions from DescribedPredicates (see #855; thanks a lot to @u3r)
  • Javadoc of the rules API has been extended to better guide to predefined DescribedPredicates like JavaClass.Predicates or HasName.Predicates (see #912)
  • New convenience method ConditionEvent.createMessage(..) to easily create a standard ArchRule violation message like Class <..> 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 like java.lang.Object being reported (see #887)
  • onionArchitecture() components can now not only be defined by package identifiers but also by predicates (see #894)
  • layeredArchitecture() and onionArchitecture() now support ensureAllClassesAreContainedInArchitecture() (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

ArchUnit 0.23.1

Choose a tag to compare

@codecholeric codecholeric released this 27 Feb 15:34

Bug Fixes

  • Fix exception Never found a JavaCodeUnit that matches supposed origin... occurring with Kotlin inline functions where the descriptor of a method deviates from the signature (this was introduced by checking the return type of the method as well when looking for a call origin in #714; see #804, #807)
  • Fix optional layers of LayeredArchitecture failing with the new default behavior archRule.failOnEmptyShould = true (see #809; thanks a lot to @oberprah)

Enhancements

  • Log automatic resolution configuration on debug to reduce log clutter (see #802)
  • Add new Method ArchRule.allowEmptyShould(boolean) to override the configured archRule.failOnEmptyShould configuration on a per rule basis (see #803, #806, #808; thanks a lot to @oberprah)

ArchUnit 0.23.0

Choose a tag to compare

@codecholeric codecholeric released this 20 Feb 07:05

Breaking Changes

  • As mentioned in Enhancements/Core ArchRules will now by default reject evaluating if the set passed to the should-clause is empty. This will break existing rules that don't check any elements in their should-clause. You can restore the old behavior by setting the ArchUnit property archRule.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 the origin of a JavaCall 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 of getMethod() was random. It now always picks the non-synthetic method (see #256)
  • layeredArchitecture() will now allow to combine mayOnlyBeAccessedBy... and mayOnlyAccess.... Previously mayOnlyAccess... 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. Previously AccessTarget.resolve() would return a set of matching members, the new replacement AccessTarget.resolveMember() returns an optional member making it a lot easier to handle (see #722)
  • JavaClass now knows its methodReferencesFromSelf (e.g. Object::toString) and constructorReferencesFromSelf (e.g. Object::new) (see #215; thanks a lot to @KorSin)
  • ArchRules will now by default reject evaluating if the set passed to the should-clause is empty. This prevents implementation errors like picking a package in that()... 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 exclude package-info.class files (see #793; thanks a lot to @TomerFi)

Lang

  • Analogously to classes(), there now exists a method members()...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 ArchUnit ClassLoader (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

Choose a tag to compare

@codecholeric codecholeric released this 30 Oct 06:26

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

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
  • SourceCodeLocation now offers structured access to source file and source class (see #673; thanks a lot to @thmuch)

JUnit

  • new option to replace underscores in rule field/method names by spaces in the test description to improve readability (see #626; thanks a lot to @thmuch)

ArchUnit 0.21.0

Choose a tag to compare

@codecholeric codecholeric released this 22 Aug 17:49

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 of JavaClassList.getNames() by the static utility HasName.Utils.namesOf(classes) which can be used on any Iterable with elements of type HasName (see #633)

Enhancements

Core

  • JavaMethod now knows its generic parameter types (retrievable via JavaMethod.getParameterTypes()). Furthermore type arguments of generic method parameter types are now part of the JavaClass.directDependencies{From/To}Self (see #640)

Library

  • the PlantUML rule syntax now allows colored components (see #258; thanks a lot to @johthor)

Further Acknowledgement

ArchUnit 0.20.1

Choose a tag to compare

@codecholeric codecholeric released this 16 Jul 12:33

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)