From 1e0381953cb10798be1b89c1708b4a186ca5fd27 Mon Sep 17 00:00:00 2001 From: Manfred Hanke Date: Tue, 9 Apr 2024 01:17:22 +0200 Subject: [PATCH 1/2] rename parameters to clarify that injection rule targets fields Signed-off-by: Manfred Hanke --- .../layers/ClassViolatingInjectionRules.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java b/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java index 8f77353642..2586c10a19 100644 --- a/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java +++ b/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java @@ -28,39 +28,39 @@ public class ClassViolatingInjectionRules { } @Autowired - ClassViolatingInjectionRules(Object badBecauseAutowiredField) { + ClassViolatingInjectionRules(Object okayBecauseAutowiredConstructor) { } - ClassViolatingInjectionRules(@Value("${name}") List badBecauseValueField) { + ClassViolatingInjectionRules(@Value("${name}") List okayBecauseValueConstructorParameter) { } @javax.inject.Inject - ClassViolatingInjectionRules(Set badBecauseJavaxInjectField) { + ClassViolatingInjectionRules(Set okayBecauseJavaxInjectConstructor) { } @com.google.inject.Inject - ClassViolatingInjectionRules(Map badBecauseComGoogleInjectField) { + ClassViolatingInjectionRules(Map okayBecauseComGoogleInjectConstructor) { } void someMethod(String okayBecauseNotInjected) { } @Autowired - void someMethod(Object badBecauseAutowiredField) { + void someMethod(Object okayBecauseAutowiredMethod) { } - void someMethod(@Value("${name}") List badBecauseValueField) { + void someMethod(@Value("${name}") List okayBecauseValueMethodParameter) { } @javax.inject.Inject - void someMethod(Set badBecauseJavaxInjectField) { + void someMethod(Set okayBecauseJavaxInjectMethod) { } @com.google.inject.Inject - void someMethod(Map badBecauseComGoogleInjectField) { + void someMethod(Map okayBecauseComGoogleInjectMethod) { } @Resource - void someMethod(File badBecauseResourceField) { + void someMethod(File okayBecauseResourceMethod) { } } From 1d1a990eea6f7babb29847ad3b42d37c56f81f47 Mon Sep 17 00:00:00 2001 From: Manfred Hanke Date: Tue, 9 Apr 2024 00:33:34 +0200 Subject: [PATCH 2/2] consider Jakarta EE9 injection annotations for general coding rule The condition `BE_ANNOTATED_WITH_AN_INJECTION_ANNOTATION` and the rule `NO_CLASSES_SHOULD_USE_FIELD_INJECTION` previously considered the `javax.inject.Inject` and `javax.annotation.Resource` annotations, but not their jakarta variants (`jakarta.inject.Inject` and `jakarta.annotation.Resource`). Resolves: #1285 Signed-off-by: Manfred Hanke --- .../layers/ClassViolatingInjectionRules.java | 22 +++++++++++++----- .../integration/ExamplesIntegrationTest.java | 5 ++-- .../archunit/library/GeneralCodingRules.java | 23 ++++++++----------- build.gradle | 4 ++-- .../archunit.java-examples-conventions.gradle | 2 ++ 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java b/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java index 2586c10a19..ac70bf7dcd 100644 --- a/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java +++ b/archunit-example/example-plain/src/main/java/com/tngtech/archunit/example/layers/ClassViolatingInjectionRules.java @@ -5,8 +5,6 @@ import java.util.Map; import java.util.Set; -import javax.annotation.Resource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -21,8 +19,12 @@ public class ClassViolatingInjectionRules { private Set badBecauseJavaxInjectField; @com.google.inject.Inject private Map badBecauseComGoogleInjectField; - @Resource - private File badBecauseResourceField; + @javax.annotation.Resource + private File badBecauseJavaxResourceField; + @jakarta.inject.Inject + private Object badBecauseJakartaInjectField; + @jakarta.annotation.Resource + private Object badBecauseJakartaResourceField; ClassViolatingInjectionRules(String okayBecauseNotInjected) { } @@ -60,7 +62,15 @@ void someMethod(Set okayBecauseJavaxInjectMethod) { void someMethod(Map okayBecauseComGoogleInjectMethod) { } - @Resource - void someMethod(File okayBecauseResourceMethod) { + @javax.annotation.Resource + void someMethod(File okayBecauseJavaxResourceMethod) { + } + + @jakarta.inject.Inject + void someMethod(Void okayBecauseJakartaInjectMethod) { + } + + @jakarta.annotation.Resource + void someMethod(Integer okayBecauseJavaxResourceMethod) { } } diff --git a/archunit-integration-test/src/test/java/com/tngtech/archunit/integration/ExamplesIntegrationTest.java b/archunit-integration-test/src/test/java/com/tngtech/archunit/integration/ExamplesIntegrationTest.java index 8a670bcc7d..a224025da5 100644 --- a/archunit-integration-test/src/test/java/com/tngtech/archunit/integration/ExamplesIntegrationTest.java +++ b/archunit-integration-test/src/test/java/com/tngtech/archunit/integration/ExamplesIntegrationTest.java @@ -17,7 +17,6 @@ import java.util.function.Function; import java.util.stream.Stream; -import javax.annotation.Resource; import javax.persistence.EntityManager; import com.google.common.base.Joiner; @@ -266,7 +265,9 @@ Stream CodingRulesTest() { .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseValueField").beingAnnotatedWith(Value.class)) .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseJavaxInjectField").beingAnnotatedWith(javax.inject.Inject.class)) .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseComGoogleInjectField").beingAnnotatedWith(com.google.inject.Inject.class)) - .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseResourceField").beingAnnotatedWith(Resource.class)); + .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseJavaxResourceField").beingAnnotatedWith(javax.annotation.Resource.class)) + .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseJakartaInjectField").beingAnnotatedWith(jakarta.inject.Inject.class)) + .by(ExpectedField.of(ClassViolatingInjectionRules.class, "badBecauseJakartaResourceField").beingAnnotatedWith(jakarta.annotation.Resource.class)); expectFailures.ofRule("no classes should access standard streams and no classes should throw generic exceptions"); expectAccessToStandardStreams(expectFailures); diff --git a/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java b/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java index 5d23681fc7..ee6cbb6813 100644 --- a/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java +++ b/archunit/src/main/java/com/tngtech/archunit/library/GeneralCodingRules.java @@ -31,6 +31,7 @@ import com.tngtech.archunit.lang.ArchCondition; import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.ConditionEvents; +import com.tngtech.archunit.lang.conditions.ArchConditions; import static com.tngtech.archunit.PublicAPI.Usage.ACCESS; import static com.tngtech.archunit.base.DescribedPredicate.not; @@ -371,19 +372,15 @@ private static ArchCondition throwGenericExceptions() { * @see #NO_CLASSES_SHOULD_USE_FIELD_INJECTION */ @PublicAPI(usage = ACCESS) - public static final ArchCondition BE_ANNOTATED_WITH_AN_INJECTION_ANNOTATION = beAnnotatedWithAnInjectionAnnotation(); - - private static ArchCondition beAnnotatedWithAnInjectionAnnotation() { - ArchCondition annotatedWithSpringAutowired = beAnnotatedWith("org.springframework.beans.factory.annotation.Autowired"); - ArchCondition annotatedWithSpringValue = beAnnotatedWith("org.springframework.beans.factory.annotation.Value"); - ArchCondition annotatedWithGuiceInject = beAnnotatedWith("com.google.inject.Inject"); - ArchCondition annotatedWithJakartaInject = beAnnotatedWith("javax.inject.Inject"); - ArchCondition annotatedWithJakartaResource = beAnnotatedWith("javax.annotation.Resource"); - return annotatedWithSpringAutowired.or(annotatedWithSpringValue) - .or(annotatedWithGuiceInject) - .or(annotatedWithJakartaInject).or(annotatedWithJakartaResource) - .as("be annotated with an injection annotation"); - } + public static final ArchCondition BE_ANNOTATED_WITH_AN_INJECTION_ANNOTATION = + ArchConditions.beAnnotatedWith("org.springframework.beans.factory.annotation.Autowired") + .or(beAnnotatedWith("org.springframework.beans.factory.annotation.Value")) + .or(beAnnotatedWith("com.google.inject.Inject")) + .or(beAnnotatedWith("javax.inject.Inject")) + .or(beAnnotatedWith("javax.annotation.Resource")) + .or(beAnnotatedWith("jakarta.inject.Inject")) + .or(beAnnotatedWith("jakarta.annotation.Resource")) + .as("be annotated with an injection annotation"); /** * A rule that checks that none of the given classes uses field injection. diff --git a/build.gradle b/build.gradle index 118cddbc66..2a6eafa06f 100644 --- a/build.gradle +++ b/build.gradle @@ -69,8 +69,8 @@ ext { javaxAnnotationApi : [group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'], springBeans : [group: 'org.springframework', name: 'spring-beans', version: '5.3.23'], springBootLoader : [group: 'org.springframework.boot', name: 'spring-boot-loader', version: '2.7.13'], - jakartaInject : [group: 'jakarta.inject', name: 'jakarta.inject-api', version: '1.0'], - jakartaAnnotations : [group: 'jakarta.annotation', name: 'jakarta.annotation-api', version: '1.3.5'], + jakartaInject : [group: 'jakarta.inject', name: 'jakarta.inject-api', version: '2.0.1'], + jakartaAnnotations : [group: 'jakarta.annotation', name: 'jakarta.annotation-api', version: '2.1.1'], guice : [group: 'com.google.inject', name: 'guice', version: '5.1.0'], // NOTE: The pure javaee-api dependencies are crippled, so to run any test we need to choose a full implementation provider geronimoEjb : [group: 'org.apache.geronimo.specs', name: 'geronimo-ejb_3.1_spec', version: '1.0.2'], diff --git a/buildSrc/src/main/groovy/archunit.java-examples-conventions.gradle b/buildSrc/src/main/groovy/archunit.java-examples-conventions.gradle index c64fe3f408..0ae6b384a7 100644 --- a/buildSrc/src/main/groovy/archunit.java-examples-conventions.gradle +++ b/buildSrc/src/main/groovy/archunit.java-examples-conventions.gradle @@ -14,6 +14,8 @@ dependencies { // `api` dependencies so we can access them within `archunit-integration-test` api dependency.jodaTime api dependency.javaxAnnotationApi + api dependency.jakartaInject + api dependency.jakartaAnnotations api dependency.springBeans api dependency.guice api dependency.geronimoEjb