DateTimeFormatter.ofPattern(...) returns null on jenkins, while locally it works

723 Views Asked by At

When we run test on Jenkins with Jacoco coveradge tool, two tests that worked locally on IDE failed on Jenkins.

Jenkins Stacktrace

java.lang.NullPointerException: formatter
    at java.util.Objects.requireNonNull(Objects.java:228)
    at java.time.LocalDateTime.format(LocalDateTime.java:1751)
    at valid.package.MyUtils.generateReferenceId(MyUtils.java:356)

Tested Class

public class MyUtils{

       private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyyHHmmss");

//method under test
public static String generateReferenceId(StationState stationState) {
        StringBuilder referenceId = new StringBuilder();
        referenceId.append(String.format("%04d", stationState.getLocationId()));
        referenceId.append(String.format("%06d", stationState.getStoreNbr()));
        referenceId.append(String.format("%02d", stationState.getSessionId()));
        referenceId.append(LocalDateTime.now().format(formatter));  //null was found here - line 356
        return referenceId.toString();
    }

Test

@RunWith(PowerMockRunner.class)
@PrepareForTest({
        MyUtils.class
})
class MyUtilsTest{
@Test
        public void generateReferenceId_whenGenerate_shouldReturnNotNull() {
            //given
            //when
            String referenceId = MyUtils.generateReferenceId(stationState);
            //then
            // assertions
        }

Second tested method is in separate class and looks the same beside a different pattern.

private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);

So there is no reason to put it here. So:

  1. I am wondering how DateTimeFormatter.ofPattern(..) can return null for a private static final?

  2. Do you think it's because PowerMockito causes problems when used with Jacoco on-the-fly instrumentation PowerMockito with Jacoco. We are issuing a lowered coverage as described in above link.

  3. When I've inlined

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);

to a generateReferenceId() method

referenceId.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("ddMMyyyyHHmmss")));

test on Jenkins doesn't throw NPE anymore.

Env details:

Local env: Java version 1.8.0.271, Win 10 OS, country PL

Jenkins version:

[java]      [echo] *       Run By: jenkins on Wednesday, December 9, 2020 11:07:40 AM UTC
[java]      [echo] *          JVM: Oracle Corporation v25.231-b11
[java]      [echo] *           OS: Linux amd64 v4.14.203-156.332.amzn2.x86_64

Jenkins is on AWS in UK.

1

There are 1 best solutions below

0
On

Workaround

I've inline constants DateTimeFormatter.ofPattern(FORMAT) in a tested method and it doesn't throw NullPointerException on Jenkins anymore.

public static String generateReferenceId(StationState stationState) {
        StringBuilder referenceId = new StringBuilder();
        referenceId.append(String.format("%04d", stationState.getLocationId()));
        referenceId.append(String.format("%06d", stationState.getStoreNbr()));
        referenceId.append(String.format("%02d", stationState.getSessionId()));
        referenceId.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern(FORMAT)));
        return referenceId.toString();
    }

Maybe it's not a solution as I didn't find a root cause, but for sure it's a simple workaround.

To make sure I've made a test and first made an inline in first failing test method and it passes, while the other with constants failed. After I've inline it in second tested method is passes too.