Skip to content

Commit 06bc4d0

Browse files
author
michaelk
committed
Enforcing your architecture with arch unit
1 parent 4f081b3 commit 06bc4d0

File tree

11 files changed

+308
-0
lines changed

11 files changed

+308
-0
lines changed

archunit/.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/modules.xml
8+
.idea/jarRepositories.xml
9+
.idea/compiler.xml
10+
.idea/libraries/
11+
*.iws
12+
*.iml
13+
*.ipr
14+
15+
### Eclipse ###
16+
.apt_generated
17+
.classpath
18+
.factorypath
19+
.project
20+
.settings
21+
.springBeans
22+
.sts4-cache
23+
24+
### NetBeans ###
25+
/nbproject/private/
26+
/nbbuild/
27+
/dist/
28+
/nbdist/
29+
/.nb-gradle/
30+
build/
31+
!**/src/main/**/build/
32+
!**/src/test/**/build/
33+
34+
### VS Code ###
35+
.vscode/
36+
37+
### Mac OS ###
38+
.DS_Store

archunit/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Examples for [Enforcing Your Architecture with ArchUnit](https://reflectoring.io/enforce-architecture-with-arch-unit)
2+
3+
This repository contains the source code of the article's examples.
4+
The code examples and the code in the repository use Maven as a build tool and JUnit as testing framework.
5+
The only exception are the code examples for using ArchUnit with Scala.

archunit/pom.xml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>io.reflectoring</groupId>
8+
<artifactId>archunit</artifactId>
9+
<version>0.0.1-SNAPSHOT</version>
10+
<name>ArchUnit</name>
11+
<description>Demo project for ArchUnit</description>
12+
13+
<properties>
14+
<maven.compiler.source>19</maven.compiler.source>
15+
<maven.compiler.target>19</maven.compiler.target>
16+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>com.tngtech.archunit</groupId>
22+
<artifactId>archunit-junit5</artifactId>
23+
<version>1.0.1</version>
24+
<scope>test</scope>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.junit.jupiter</groupId>
28+
<artifactId>junit-jupiter-engine</artifactId>
29+
<version>5.8.1</version>
30+
<scope>test</scope>
31+
</dependency>
32+
<dependency>
33+
<groupId>javax.ws.rs</groupId>
34+
<artifactId>javax.ws.rs-api</artifactId>
35+
<version>2.1.1</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.junit.jupiter</groupId>
39+
<artifactId>junit-jupiter-api</artifactId>
40+
<version>5.9.2</version>
41+
<scope>test</scope>
42+
</dependency>
43+
</dependencies>
44+
45+
</project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.reflectoring.archunit;
2+
3+
import java.math.BigDecimal;
4+
5+
public class ArchUnitExamples {
6+
7+
public void reference_deprecated_class() {
8+
Dep dep = new Dep();
9+
}
10+
11+
@Deprecated
12+
public class Dep {
13+
14+
}
15+
16+
public void this_method_calls_the_wrong_BigDecimal_constructor() {
17+
BigDecimal value = new BigDecimal(123.0);
18+
19+
// BigDecimal value = new BigDecimal("123.0"); // works!
20+
}
21+
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.reflectoring.archunit.api;
2+
3+
import io.reflectoring.archunit.model.EmployeeResponse;
4+
import io.reflectoring.archunit.service.EmployeeService;
5+
6+
import javax.ws.rs.GET;
7+
import javax.ws.rs.Path;
8+
9+
public class EmployeeController {
10+
11+
@GET()
12+
@Path("/employees")
13+
public EmployeeResponse getEmployee() {
14+
EmployeeService service = new EmployeeService();
15+
return service.getEmployee();
16+
}
17+
18+
// Uncomment to cause ArchUnit rule violation
19+
// @GET()
20+
// @Path("/employees")
21+
// public EmployeeResponse getEmployee_withViolation() {
22+
// EmployeeDao dao = new EmployeeDao();
23+
// Employee employee = dao.findEmployee();
24+
// return new EmployeeResponse(
25+
// employee.id(),
26+
// employee.name(),
27+
// employee.active()
28+
// );
29+
// }
30+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package io.reflectoring.archunit.model;
2+
3+
public record Employee(long id, String name, boolean active) { }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package io.reflectoring.archunit.model;
2+
3+
public record EmployeeResponse(long id, String name, boolean active) { }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.reflectoring.archunit.persistence;
2+
3+
import io.reflectoring.archunit.model.Employee;
4+
5+
public class EmployeeDao {
6+
7+
public Employee findEmployee() {
8+
return new Employee(1, "name", true);
9+
}
10+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.reflectoring.archunit.service;
2+
3+
import io.reflectoring.archunit.model.Employee;
4+
import io.reflectoring.archunit.model.EmployeeResponse;
5+
import io.reflectoring.archunit.persistence.EmployeeDao;
6+
7+
public class EmployeeService {
8+
public EmployeeResponse getEmployee() {
9+
EmployeeDao employeeDao = new EmployeeDao();
10+
Employee employee = employeeDao.findEmployee();
11+
return new EmployeeResponse(
12+
employee.id(),
13+
employee.name(),
14+
employee.active()
15+
);
16+
}
17+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.reflectoring.archunit;
2+
3+
import com.tngtech.archunit.core.domain.JavaClasses;
4+
import com.tngtech.archunit.junit.AnalyzeClasses;
5+
import com.tngtech.archunit.junit.ArchTest;
6+
import com.tngtech.archunit.lang.ArchRule;
7+
8+
import java.math.BigDecimal;
9+
10+
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
11+
12+
@AnalyzeClasses(packages = "io.reflectoring.archunit")
13+
public class ArchUnitCachedTest {
14+
@ArchTest
15+
public void do_not_call_deprecated_methods_from_the_project(JavaClasses classes) {
16+
ArchRule rule = noClasses().should().dependOnClassesThat().areAnnotatedWith(Deprecated.class);
17+
rule.check(classes);
18+
}
19+
20+
@ArchTest
21+
public void do_not_call_constructor_cached(JavaClasses classes) {
22+
ArchRule rule = noClasses().should().callConstructor(BigDecimal.class, double.class);
23+
rule.check(classes);
24+
}
25+
}

0 commit comments

Comments
 (0)