4

I am using simple date format in my app in following way in the class:

static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

public static myFunction(final String strDate)
{
      Date endDate = null;
 endDate = MyClass.sdf.parse(strDate);
}

I am using FindBugs which is giving the following bug in above code:

"As the JavaDoc states, DateFormats are inherently unsafe for multithreaded use. The detector has found a call to an instance of DateFormat that has been obtained via a static field. This looks suspicous."

Can someone please explain the bug. I am not able to understand what above message is trying to tell.

Thanks for reading!!

Vicky
  • 16,679
  • 54
  • 139
  • 232
  • 2
    Possible [duplicate](http://stackoverflow.com/questions/2409657/call-to-method-of-static-java-text-dateformat-not-advisable)? – Dallas Dec 08 '11 at 05:14
  • The question pointed by @Dallas is not in the same wording but the accepted answer is useful and quite complete. – madth3 Dec 08 '11 at 05:24
  • Most Developers understand that for most classes that are not thread safe, that this is due to concurrently changing state. Once a Format is established, formatting a Date should not change state. Simply documenting this in official documentation as not thread-safe is not enough. It should be explicitly documented that even the format method is not thread-safe if it maintains temporary state in instance variables. Declaring it as static is not just a rookie mistake. Analogy can be made between modifying a collection (put) vs accessing a collection (get). – YoYo Nov 02 '14 at 05:28

5 Answers5

4

The others who answered about thread-safety and removing the static keyword from before SimpleDateFormat are correct, though the code you posted with your question is not compilable at all.

I think this is closer to the code you're looking for:

public static Date parseDateStr(final String dateStr) throws ParseException
{
 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
 return sdf.parse(dateStr);
}
RichW
  • 2,004
  • 2
  • 15
  • 24
1

DateFormat's are not thread safe. This is even documented in the javadoc. Since you are declaring it as a static variable, FindBugs knows that there is a potential for it being used in multiple threads. Read more about the issue and alternatives here.

Also, your code shouldn't compile as Java doesn't support local static variables. How do I create a static local variable in Java?

Community
  • 1
  • 1
Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
1

Remove the static from static SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

The var is being kept as a single static instance scoped to this method. Meaning that other threads accessing this method concurrently will make dateformat calls on the same instance which is not threadsafe.

Steven
  • 3,844
  • 3
  • 32
  • 53
  • Can not make it non static.. Actually its being used in a utility class where the methods are static so that could be called using class name. Something like: return MyUtil.sdf.format(calendar.getTime()); -- Any other solution or is it ok to ignore FingBugs ? – Vicky Dec 08 '11 at 05:17
  • If your app is single threaded then you can ignore it. From your comment I'm assuming sdf is a class field rather than inside of a method. You should update your question if this is the case. If your app is multithreaded then I advise against keeping a static instance of SDF around for use like this. It can return unpredictable results in these cases. You could get around this by providing synchronized access to this field via a method and making the field private to avoid anyone bypassing this method. – Steven Dec 08 '11 at 05:23
0

I had an issue where a JUnit test was failing when building outside of eclipse (via DOS ANT build and test script), but it ran just fine inside eclipse.

The code under test was a class and method from a batch job that had a SimpleDateFormat declared as private static final.

I did not care about thread safety because this batch job is single threaded.

I also did not want to instantiate a new instance of SimpleDateFormat every time I needed it because the process was in a loop processing thousands of data rows.

I got around it by changing the declaration of the SimpleDateFormat from private static final to private final transient.

Of course this does mean instantiating the class, which may not work for all cases, but it's a solution if you are instantiating the class and don't want to create new instances every time and thread safety is not an issue.

Warren
  • 1
0

as per the suggestion of Pangea go ahead and you can test the code below.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;



public class Test {

    public static Date myFunction(final String strDate) throws ParseExceptoion
    {
     SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        return sdf.parse(strDate);

    }


public static void main(String[] args) throws ParseException {
    System.out.println(myFunction("05/18/1989").toString());

}
}
Noufal Panolan
  • 1,357
  • 2
  • 14
  • 27