CI the architecture of Java / Kotlin applications with ArchUnit

** (Addition) **

It was announced at JJUG CCC 2019 Spring.

How to check and improve the Java-based application architecture with “ArchUnit” https://speakerdeck.com/kawanamiyuu/jjug-ccc-2019-spring


Currently, my team is working on Development of new HRTech services, and recently launched a tool called ** ArchUnit **. I will introduce it because it has been incorporated.

I read a book called Evolutionary Architecture and measured / guaranteed the degree of compliance with the requirements of the characteristics of the architecture ** Fitness function ** 1 As an example, JDepend that can test class dependencies is introduced, and when I searched for a similar tool, ArchUnit I found. It was also introduced as TRIAL in this year's Technology Radar VOL.19.

What is ArchUnit?

What are you happy about

Concrete example

Here is a portion of the test code embedded in the CI of the product currently under development.

(1) A general-purpose class common to domains must not depend on classes of other specific domains.

Prevents the common package from becoming non-common.


@Test
void domainCommonPackageShouldNotDependOnOtherPackages() {
    noClasses()
        .that().resideInAPackage(ROOT_PACKAGE + ".domain.common..")
        .should()
        .dependOnClassesThat(new DescribedPredicate<>("Classes other than the common package under the domain package") {
            @Override
            public boolean apply(JavaClass clazz) {
                return clazz.getPackageName().startsWith(ROOT_PACKAGE + ".domain")
                    && ! clazz.getPackageName().equals(ROOT_PACKAGE + ".domain") //The base interface directly under the domain package/Dependence on class is acceptable
                    && ! clazz.getPackageName().startsWith(ROOT_PACKAGE + ".domain.common");
            }
        })
        .check(CLASSES);
}

(2) An enum that implements JsonSerializable must also implement a deserialization method.

When deserializing a JSON property into a numeric enumeration, if you don't explicitly implement the deserialization method, the JSON library's JSON library will instantiate the enumeration that corresponds to the ordinal value of the enumeration instead of the enumeration that corresponds to the number. I was once addicted to the specifications.

Added a test to check for forgetting to implement the deserialization method (factory method annotated with @JsonCreator) so that you don't get hooked on the same thing twice.


@Test
void jsonSerializableShouldImplementJsonCreator() {
        classes()
            .that(new DescribedPredicate<>("JSON serialized enum") {
                @Override
                public boolean apply(JavaClass clazz) {
                    return clazz.isEnum() && clazz.isAssignableTo(JsonSerializable.class);
                }
            })
            .should(new ArchCondition<>("@Implement the annotated factory method in JsonCreator") {
                @Override
                public void check(JavaClass clazz, ConditionEvents events) {
                    boolean hasJsonCreator = clazz.getMethods().stream()
                        .anyMatch(method -> method.isAnnotatedWith(JsonCreator.class));

                    if (! hasJsonCreator) {
                        events.add(SimpleConditionEvent.violated(
                            clazz,
                            clazz.getName() + " should implement a factory method annotated with @JsonCreator."
                        ));
                    }
                }
            })
            .check(CLASSES);
}

Summary

What did you think. I don't think there are many tools to test the architecture before. In addition to the examples introduced this time, it seems that tests from various perspectives can be implemented depending on the idea. It would be exciting if we could continuously improve the architecture through product development while ensuring the quality of the architecture through automated testing: smile:

Recommended Posts

CI the architecture of Java / Kotlin applications with ArchUnit
[Java] Get MimeType from the contents of the file with Apathce Tika [Kotlin]
Calculate the similarity score of strings with JAVA
[Java / Kotlin] Resize considering the orientation of the image
Please note the division (division) of java kotlin Int and Int
Java language from the perspective of Kotlin and C #
Monitor the internal state of Java programs with Kubernetes
Check the behavior of Java Intrinsic Locks with bpftrace
The story of making dto, dao-like with java, sqlite
Replace only part of the URL host with java
How to use trained model of tensorflow2.0 with Kotlin / Java
I tried to summarize the basics of kotlin and java
[Java] Simplify the implementation of data history management with Reladomo
Be sure to compare the result of Java compareTo with 0
Find the number of days in a month with Kotlin
Whether to make the server side at the time of system rebuild with Kotlin or Java
[Java] Delete the elements of List
ArchUnit Practice: Architecture Testing of Onion Architecture
[Java1.8 +] Get the date of the next x day of the week with LocalDate
[Java version] The story of serialization
Easily Docker Java applications with Jib
I want to return to the previous screen with kotlin and java!
Try Hello World with the minimum configuration of Heroku Java spring-boot
[Details] Implementation of consumer applications with Kinesis Client Library for Java
Follow the link with Selenium (Java)
A story about hitting the League Of Legends API with JAVA
The point of addiction when performing basic authentication with Java URLConnection
Generics of Kotlin for Java developers
Overwrite upload of file with the same name with BOX SDK (java)
Is the version of Elasticsearch you are using compatible with Java 11?
The guy who tries-with-resources with kotlin
The origin of Java lambda expressions
[Code Pipeline x Elastic Beanstalk] Summary of errors and countermeasures for CI / CD Java applications to Elastic Beanstalk with Code Pipeline
Use Priority Queue with Kotlin (1.0.0) of AtCoder (+ Investigate the environment of the judge server)
The story of making a game launcher with automatic loading function [Java]
Let's express the result of analyzing Java bytecode with a class diagram
About the classification and concept of Immutable / Mutable / Const / Variable of Java and Kotlin.
Check the domain by checking the MX record of the email address with java
Get the result of POST in Java
Check the contents of the Java certificate store
Check the contents of params with pry
Examine the memory usage of Java elements
[Java] Get the day of the specific day of the week
Test the integrity of the aggregation using ArchUnit ②
Memo: [Java] Check the contents of the directory
CICS-Run Java applications-(3) Build management with Gradle
Compare the elements of an array (Java)
[day: 5] I summarized the basics of Java
What are the updated features of java 13
Easily measure the size of Java Objects
CICS-Run Java applications-(2) Build management with Maven
Looking back on the basics of Java
[Kotlin] Delete files with duplicate contents [Java]
Output of the book "Introduction to Java"
About the treatment of BigDecimal (with reflection)
Interoperability tips with Kotlin for Java developers
The story of writing Java in Emacs
Format the contents of LocalDate with DateTimeFormatter
[Java] Check the number of occurrences of characters
[Java] [Spring] Test the behavior of the logger
Try using the Wii remote with Java