2

I am getting this prompt from Sonar: Instance methods should not write to "static" fields

I'm not quite sure what I need to change to fix this issue.

Does "SemaMonitorProxy.applicationContext" have to equal a static method?

public class SemaMonitorProxy implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    public void registerFailedLoginAttempt(HttpServletRequest request, HttpServletResponse response) {
        final SemaMonitor semaMonitor = applicationContext.getBean(SemaMonitor.class);
        semaMonitor.registerFailedLoginAttempt(request, response);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SemaMonitorProxy.applicationContext = applicationContext;
    }
}
Kevin M
  • 25
  • 1
  • 6
  • Im not a Sonar specialist, but what I can imagine is that it might be dangerous to write to a static field in parallel. Just try add a synchronize block on SemaMonitorProxy.class and see if the warning goes away. – loonytune Nov 28 '17 at 10:34
  • The problem is you are setting the value of static field through a non-static field. Can you make the `setApplicationContext` method as `synchrozied`? I believe that should be enough to fix this. – utkarsh31 Nov 28 '17 at 10:42
  • There is a proper solution in [another question](https://stackoverflow.com/questions/21136302/findbugs-error-write-to-static-field-from-instance-method/21136731). – Mick Belker - Pseudonym Aug 31 '18 at 07:12

2 Answers2

2

In fact this method:

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    SemaMonitorProxy.applicationContext = applicationContext;
}

is an instance method writing to a static field:

private static ApplicationContext applicationContext

You cannot make the above method static. So the only solution would be to remove the static keyword from the applicationContext declaration.

private ApplicationContext applicationContext
gil.fernandes
  • 12,978
  • 5
  • 63
  • 76
  • I can't set setApplicationContext to static because then it wont be able to override ApplicationContextAware, which isn't an interface I can't change since it's part of the spring framework. – Kevin M Nov 28 '17 at 12:41
  • @KevinM: absolutely right. I suggest to make the applicationContext non static. It is typically a singleton anyway which exists once in memory. I have updated the answer. – gil.fernandes Nov 28 '17 at 12:47
0

Rule java:S2696

Correctly updating a static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play. Ideally, static fields are only updated from synchronized static methods.

Check this answer from @G. Ann - SonarSource Team

pbaris
  • 4,525
  • 5
  • 37
  • 61