Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature suggestion: Expose synchronized blocks in core API #1315

Open
bannmann opened this issue Jun 1, 2024 · 0 comments
Open

Feature suggestion: Expose synchronized blocks in core API #1315

bannmann opened this issue Jun 1, 2024 · 0 comments

Comments

@bannmann
Copy link

bannmann commented Jun 1, 2024

There is a widespread practice of avoiding unnecessarily exposing your synchronization locks, i.e. using synchronized(myPrivateField) instead of public synchronized void myMethod(). (For background, see e.g. this SO question or the rationale for using a related Lombok feature.)

I think ArchUnit could be used nicely to write rules around this, for example:

  • regarding "don't expose your locks":
    • "no method should have the synchronized modifier" (already possible in ArchUnit today)
    • "no synchronized block should use this"
    • "fields used for synchronized blocks should neither be public nor have public getters"
  • regarding "don't lock on the wrong stuff":
    • "no synchronized block should use a field of another class or a result returned from a method of another (library) class"

As far as I can see, however, ArchUnit does not model the existence of synchronized blocks or which locks they use.

Now of course there are static code analyzers that do some of this (e.g. Error Prone with its @GuardedBy annotation). Still, I believe it's worthwhile to support this concept in ArchUnit for the following reasons:

  • Some locks are shared intentionally, e.g. as described in the javadoc for Collections.synchronizedMap(). With ArchUnit, a team could easily write their own annotation, e.g. @ReturnValueSuitableForLocking, and have their rules make an exception for those of their methods that have it.
  • Other tools don't have a notion of architecture layers, whereas in ArchUnit it would be possible to implement a rule like "shared locks can only be used within the layer they are defined in, not in other/upper layers".
  • "Stupid" reason: introducing a static code analyzer (or any new dependency, for that matter) can be cumbersome, controversial, or both. If ArchUnit is already in place, it could be used as a) a permanent workaround for the lack of specialized tooling or b) as a proof of concept that checking for those code smells is valuable and specialized tooling should be introduced.

So, could this be added?

Note: in theory, it would also be possible to model what accesses are done inside a synchronized block, enabling rules similar to what ErrorProne does (see link above). IMO this is not required. However, when refactoring the model now in order to add the minimal feature, one should probably take care to not create any obstacles for a future addition of the larger feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant