Why is this an issue?

Marking a non-public method @Async or @Transactional is misleading because Spring does not recognize non-public methods, and so makes no provision for their proper invocation. Nor does Spring make provision for the methods invoked by the method it called.

Therefore marking a private method, for instance, @Transactional can only result in a runtime error or exception if the method is annotated as @Transactional.

How to fix it

Declare the method public. Note that this action alone does not resolve the issue of direct instance calls from within the same class (see rule {rule:java:S6809}), but it is a required precondition to fix it.

Code examples

Noncompliant code example

@Async
private Future<String> asyncMethodWithReturnType() { // Noncompliant, no proxy generated and
    return "Hellow, world!";                         // can only be invoked from same class
}

Compliant solution

@Async
public Future<String> asyncMethodWithReturnType() { // Compliant
    return "Hellow, world!";
}

Resources

Documentation

Articles & blog posts