admin管理员组文章数量:1394206
Certain frameworks require the empty constructor of a class to be present, e.g. a JakartaEE stateless service, but they do not have the appropriate dependencies injected. I would like to annotate these constructors with something like a DoNotUse
annotation (with a reason), and then use ArchUnit to check if no one is actually using it.
Something like this:
ArchRuleDefinition.noConstructors()
.that()
.areAnnotatedWith(DoNotUse.class)
.should()
.beCalled();
But beCalled
or beUsed
AFAIK does not exist. I solved it now by adding a never matching condition:
ArchRuleDefinition.constructors()
.that()
.areAnnotatedWith(DoNotUse.class)
.should()
.onlyBeCalled()
.byClassesThat()
.haveSimpleName("ThisOnPurposeDoesNotMatchAnything");
How do I write a beCalled
or the inverse neverBeCalled
?
Certain frameworks require the empty constructor of a class to be present, e.g. a JakartaEE stateless service, but they do not have the appropriate dependencies injected. I would like to annotate these constructors with something like a DoNotUse
annotation (with a reason), and then use ArchUnit to check if no one is actually using it.
Something like this:
ArchRuleDefinition.noConstructors()
.that()
.areAnnotatedWith(DoNotUse.class)
.should()
.beCalled();
But beCalled
or beUsed
AFAIK does not exist. I solved it now by adding a never matching condition:
ArchRuleDefinition.constructors()
.that()
.areAnnotatedWith(DoNotUse.class)
.should()
.onlyBeCalled()
.byClassesThat()
.haveSimpleName("ThisOnPurposeDoesNotMatchAnything");
How do I write a beCalled
or the inverse neverBeCalled
?
- why create a method/constructor that should never be called? – Stultuske Commented Mar 13 at 12:29
- you can usually declare those empty constructors to be private, the frameworks will stick pick them up – Rick Commented Mar 13 at 12:40
- Some frameworks do require public default constructors. Even if it could be avoided in this case, it's a valid question. – kapex Commented Mar 13 at 12:42
- 1 I already explained that: frameworks like JakartaEE require those constructors. When using WildFly you can suffice with a protected constructor (because the generated proxies will extend the class), not private. But then IntelliJ will place an error marker on those classes and your code base is all red. – tbeernot Commented Mar 13 at 12:46
- I don't have an answer but sometimes it helps to reverse the order, even though it look less intuitive. Instead "this should not be called" reverse it to "nothing should call this" e.g. create a rule: no classes should call constructors annotated with DoNotUse. – kapex Commented Mar 13 at 13:02
1 Answer
Reset to default 0You can use a custom condition using convenient factory methods for ArchCondition
s and DescribedPredicate
s:
import static com.tngtech.archunit.base.DescribedPredicate.describe;
import static com.tngtech.archunit.lang.conditions.ArchConditions.be;
// ...
ArchRule rule = ArchRuleDefinition.noConstructors()
.that().areAnnotatedWith(DoNotUse.class)
.should(be(describe("called", ctor -> !ctor.getCallsOfSelf().isEmpty())));
If you want more descriptive error messages indicating where the unwanted call happens (cf. comment), you can use a custom ArchCondition
like this:
import static com.tngtech.archunit.lang.SimpleConditionEvent.satisfied;
// ...
ArchRule rule = ArchRuleDefinition.noConstructors()
.that().areAnnotatedWith(DoNotUse.class)
.should(new ArchCondition<JavaConstructor>("be called") {
@Override
public void check(JavaConstructor constructor, ConditionEvents events) {
constructor.getCallsOfSelf().forEach(call ->
events.add(satisfied(call, call.getDescription()))
);
}
});
本文标签:
版权声明:本文标题:java - How does one write an ArchUnit specification that a constructor or method should never be called? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744700849a2620553.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论