ArchUnit icon indicating copy to clipboard operation
ArchUnit copied to clipboard

How to verify that a method is wrapped with try-with-resources?

Open bfreitastgtg opened this issue 11 months ago • 1 comments

This is just a question. Is it possible to write an arch unit test that verifies that calls for certain methods are always wrapped with try-with-resources?

The method:

Stream<User> findAllByCustomQueryAndStream();

Compliant call:

try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
  //do something with stream
}

Non-compliant call:

Stream<User> stream = repository.findAllByCustomQueryAndStream();
//do something with stream

Context: Spring repository methods that return Stream should be wrapped by a try-with-resources block, as suggested by the official docs.

I have tried inspecting the TryCatchBlock object but it does not give me information on what's actually being wrapped, it only contains info on the //do something with stream block and the caught exceptions.

bfreitastgtg avatar Dec 19 '24 09:12 bfreitastgtg

I don't it's currently possible to assert exactly what you want. What you could do, and what might be close enough to catch the majority of "whoops, I forgot about closing the stream" errors, would be to check that all callers of your repository method also call Stream.close() within the same method. Basically something like

methods()
  .that().areDeclaredInClassesThat().haveSimpleNameEndingWith("Repository")
  .and().haveRawReturnType(Stream.class)
  .should().onlyBeCalled().byCodeUnitsThat(DescribedPredicate.describe("call Stream.close()", callToRepositoryMethod ->
    callToRepositoryMethod.getMethodCallsFromSelf().stream()
      .map(JavaAccess::getTarget)
      .anyMatch(AccessTarget.Predicates.declaredIn(Stream.class).and(HasName.Predicates.name("close")))
  ))
  .as("Classes calling Repository methods that return Streams should also close those Streams "
    + "(preferably by using try-with-resources, see "
    + "https://docs.spring.io/spring-data/jpa/reference/repositories/query-methods-details.html#repositories.query-streaming)")

codecholeric avatar Jan 19 '25 13:01 codecholeric