How to enforce this pattern via gradle plugins?

Viewed 96

We are trying to keep our code 'consistent' over time on our projects and follow this pattern

https://blog.twitter.com/engineering/en_us/topics/insights/2019/onepattern.html

For any classes annotated with @Entity or @Data, we consider these data objects and would like to enforce that

  1. The new keyword cannot be used on any objects NOT annotated with @Data (ie. all business logic is created by guice) - This is the hard one here!
  2. Only get/set/is member methods are in the data objects(perhaps along with equals) - This could be done by scanning and reflection
  3. All objects with no @Data are annotated with @Singleton(we program in stateless) OR with @ExceptionNotSingleton for exceptions (our exceptions are very rare as we build stateless systems - Could again be done with scanning and reflection
  4. NO static methods allowed on business objects even utilities -> scan and reflection

The 4th point is for a specific project webpieces where since we use that platform, we can fix bugs in any code by swapping out the class. swapping static methods doesn't work very well.

What tool can do something like this such that I can feed it a simple processor? A gradle plugin would be nice where I can feed it some small snippets of code, but I am not sure that exists.

I could add a unit test to every project as well I guess and then just need a class scanner to inspect the classes.

I am looking for a plugin perhaps with a link to some examples I could try out.

1 Answers

What you're talking about is similar to static code analysis.

The basic (and simplified) idea is to parse the source code into a tree and then analyze that tree for the specific patterns you're looking for.

In you case, for example, whenever you see a constructor invocation in the tree, you check whether the target class is annotated with @Data or not. Or, whenever you're analyzing a class, you visit all its method leaves and look for statics. If you spot violations – you log them and probably break the build.

The trick here is to define your rules in the term of formal patterns in AST tree.

There are a plenty of code analyzers for Java, but IMHO the most popular one is Checkstyle. All of them probably work nice with Gradle (Checkstyle and PMD do), so it's not really a question about build tool, but about extending the analyzer.

Usually, static code analyzers allows users to extend them with custom checks / rules / plugins / etc. So does Checkstyle: read more about writing new checks. This article describes the AST and navigation in details. Checkstyle also provides a GUI tool to analyze Java classes to help find the patterns and write checks. Go ahead an load some of you clases there and look if you can track your issues via AST tree.

When you're comfortable with AST, its navigation, visitors and so on – go and write your own checks and integrate them in you build.

This idea is applicable for other static code analyzers as well, like PMD or SpotBugs (although SpotBugs's docs are poor).

Related