0

I wanted to parse some date, and for whatever the reason, parsing the date throws an error. I am using IntelliJ to debug it and from what I see, either IntelliJ is showing me a different stack, or something is happening beyond my understanding. I am using jdk 1.8.0_261 in my local, and I am debugging a remote machine which has jdk 1.8.0_291

EDIT: One thing to mention, this bug does not happen all the time. I am using the same and different values for dates and from time to time, it throws an exception. So, although I give "15/04/2021" for an input string, it is not 100% guaranteed that I will face an exception.

This is the thing that I wanted to parse:

return sf.parse((String)properties.get("validfrom"));

sf is SimpleDateFormat

public Date parse(String source) throws ParseException

method is called with the source being "15/04/2021"

DateFormat.java/parse method, line 364

Then, DecimalFormat.java/parse method, digitList.getLong() is called. The digitlist seems to have "0.2021x10^4"

DecimalFormat.java/parse, digitList

Deeper in the stack, Long.parseLong is called with the same "0.2021x10^4"

Long.getLong()

Long.getLong() 2 (To capture another picture of the line of codes being executed, I have re-executed from the beginning, that is why the object Id's are different.).

Suddenly, the string passed to parseLong() becomes ""

static long parseLong(String s)

In the end, it throws an exception.

The weirder thing is, when I try to execute return sf.parse((String)properties.get("validfrom")); inside debugger mode, with evaluation (pressing alt + clicking on the line) it does not throw an error, and it returns me what I am expecting, the date.

What am I missing in here? Somehow the inner workings of java library between 1.8.0_261 and 291 is changed?

SimpleDateFormat was created via this.sf = new SimpleDateFormat("dd/MM/yyyy", Locale.US);

Stack trace

java.lang.NumberFormatException: For input string: ""
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.lang.Long.parseLong(Long.java:601)
        at java.lang.Long.parseLong(Long.java:631)
        at java.text.DigitList.getLong(DigitList.java:195)
        at java.text.DecimalFormat.parse(DecimalFormat.java:2082)
        at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
        at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
        at java.text.DateFormat.parse(DateFormat.java:364)
        at com.foo.bar(baz.java:123)
  • 1
    It would really help if you could provide a [mcve] and a complete stack trace. All the digging into the JRE source code is good, but it's all a bit confusing when we can't see your original source code (e.g. how `sf` is set up). Rather than try to debug through the JRE, I'd try to fix the problem within *your* code, as that's likely to be feasible... but we can't really help you do that without a [mcve]. – Jon Skeet Aug 18 '21 at 06:24
  • Did you set a pattern in the SimpleDateFormat object? SimpleDateFormat sf = new SimpleDateFormat("MM/dd/yyyy"); – Franz Deschler Aug 18 '21 at 06:26
  • SimpleDateFormat is being set up via ```this.sf = new SimpleDateFormat("dd/MM/yyyy", Locale.US);``` . Unfortunately, I cannot give you the minimal reproducible example because it is just impossible. The bug that I have mentioned above does not happen all the time. I am passing the similar values again and again. Although the values are the same or in the same format, "sometimes" it throws an exception . But I am adding the stacktrace for additional information – hovibi9445 Aug 18 '21 at 06:27
  • 2
    Are you shure, that you do not access the SimpleDateFormat from different Threads? SimpleDateFormat is not thread safe! – keuleJ Aug 18 '21 at 06:34
  • 1
    Indeed, given the facts that a) you're using a field for your `SimpleDateFormat`; b) it doesn't happen all the time; c) you see the right results in the debugger, this sounds *very* much like it could be a threading issue. (Note that if you used java.time instead, this wouldn't be a problem. Try to move away from java.util.Date etc as soon as you can...) – Jon Skeet Aug 18 '21 at 06:37
  • Oh, that could be the reason. As I said, I am remote debugging a machine. It has the production application and I know that we have bunch of threads. Although I am not specifically creating threads to parse the date, maybe, somewhere in the application another thread is trying to use my ```baz``` class and tries to parse another (maybe the same value) date. – hovibi9445 Aug 18 '21 at 06:42
  • Under all circumstances I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 18 '21 at 12:10

1 Answers1

2

SimpleDateFormat is not thread-safe.

DateTimeFormatter in Java 8 is immutable and thread-safe alternative to SimpleDateFormat. You should use the new java.time classes if possible

keuleJ
  • 3,418
  • 4
  • 30
  • 51
  • Of course the OP can use `DateTimeFormatter` and the other classes from java.time. They are reporting that they are using Java 8. – Ole V.V. Aug 18 '21 at 12:09