Reputation: 5070
I would like to write an ArchUnit rule which check that classes annotated with @Configuration in Spring does not have any fields that are PUBLIC.
For instance, this class should be OK, there is no field at all:
@Configuration
@EnableWebSecurity
class SecurityConfiguration {
@Bean
SecurityFilterChain securityFilterChain(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()).csrf(AbstractHttpConfigurer::disable);
return httpSecurity.build();
}
}
This class should also be OK; there is a field, but it is private static final:
@Configuration
class JdkClientHttpRequestFactoryConfiguration {
private static final int DEFAULT_READ_TIMEOUT = 5;
@Bean
JdkClientHttpRequestFactory jdkClientHttpRequestFactory() {
final JdkClientHttpRequestFactory jdkClientHttpRequestFactory = new JdkClientHttpRequestFactory();
jdkClientHttpRequestFactory.setReadTimeout(Duration.ofSeconds(DEFAULT_READ_TIMEOUT));
return jdkClientHttpRequestFactory;
}
}
And fail if any public fields.
I tried this rule:
@Test
void fieldShouldAllBePrivateToProtectEncapsulation() {
fields().that(areNotConfiguration())
.and().areNotStatic()
.and().areNotFinal()
.should().bePrivate()
.check(importedClasses);
}
private DescribedPredicate<? super JavaField> areNotConfiguration() {
return new DescribedPredicate<>("are not @Configuration") {
@Override
public boolean test(JavaField javaField) {
JavaClass owner = javaField.getOwner();
return !owner.isAnnotatedWith(Configuration.class) || !javaField.getRawType().isAssignableTo(owner.reflect());
}
};
}
However, it yields this very strange kind of failure:
JdkClientHttpRequestFactoryConfiguration$$SpringCGLIB$$0.$$beanFactory> does not have modifier PRIVATE in (:0)
SecurityConfiguration$$SpringCGLIB$$FastClass$$1.$$beanFactory> does not have modifier PRIVATE in (:0)
May I ask how to properly write the ArchUnit rule for classes with @Configuration?
Upvotes: 0
Views: 33