diff --git a/src/main/java/software/amazon/lambda/snapstart/ByteCodeIntrospector.java b/src/main/java/software/amazon/lambda/snapstart/ByteCodeIntrospector.java index 70af805..3bda7f5 100644 --- a/src/main/java/software/amazon/lambda/snapstart/ByteCodeIntrospector.java +++ b/src/main/java/software/amazon/lambda/snapstart/ByteCodeIntrospector.java @@ -37,6 +37,14 @@ public class ByteCodeIntrospector { private static final String INSTANT_SIGNATURE = "Ljava/time/Instant;"; + private static final String LOCAL_DATE_TIME_SIGNATURE = "Ljava/time/LocalDateTime;"; + + private static final String LOCAL_DATE_SIGNATURE = "Ljava/time/LocalDate;"; + + private static final String LOCAL_TIME_SIGNATURE = "Ljava/time/LocalTime;"; + + private static final String ZONED_DATE_TIME_SIGNATURE = "Ljava/time/ZonedDateTime;"; + private static final Map> TIMESTAMP_METHODS = new HashMap>() {{ put("java.lang.System", setOf("currentTimeMillis", "nanoTime")); }}; @@ -188,6 +196,18 @@ boolean isTimestamp(OpcodeStack stack) { if (INSTANT_SIGNATURE.equals(stack.getStackItem(0).getSignature())) { return true; } + if (LOCAL_DATE_TIME_SIGNATURE.equals(stack.getStackItem(0).getSignature())) { + return true; + } + if (LOCAL_DATE_SIGNATURE.equals(stack.getStackItem(0).getSignature())) { + return true; + } + if (LOCAL_TIME_SIGNATURE.equals(stack.getStackItem(0).getSignature())) { + return true; + } + if (ZONED_DATE_TIME_SIGNATURE.equals(stack.getStackItem(0).getSignature())) { + return true; + } XMethod xMethod = stack.getStackItem(0).getReturnValueOf(); if (xMethod != null) { Set methodNames = TIMESTAMP_METHODS.get(xMethod.getClassName()); diff --git a/src/test/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValueTest.java b/src/test/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValueTest.java index 5aac5ed..b3b44a1 100644 --- a/src/test/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValueTest.java +++ b/src/test/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValueTest.java @@ -113,13 +113,17 @@ public void timestampMemberFieldBreaksSnapStart() { BugCollection bugCollection = findBugsInClasses("LambdaUsingTs"); BugInstanceMatcherBuilder bugMatcherBuilder = snapStartBugMatcher().inClass("LambdaUsingTs"); - assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromSystemTimeMillis").atLine(24).build())); - assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromSystemTimeNano").atLine(25).build())); - assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromInstantNow").atLine(26).build())); - assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromClock").atLine(27).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromSystemTimeMillis").atLine(32).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromSystemTimeNano").atLine(33).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromInstantNow").atLine(34).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromClock").atLine(35).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromLocalDateTimeNow").atLine(36).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromLocalDateNow").atLine(37).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromLocalTimeNow").atLine(38).build())); + assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("tsFromZonedDateTimeNow").atLine(39).build())); toBeFixed(() -> assertThat(bugCollection, containsExactly(1, bugMatcherBuilder.atField("logName").atLine(29).build()))); - assertThat(bugCollection, containsExactly(4, snapStartBugMatcher().build())); - toBeFixed(() -> assertThat(bugCollection, containsExactly(5, snapStartBugMatcher().build()))); + assertThat(bugCollection, containsExactly(8, snapStartBugMatcher().build())); + toBeFixed(() -> assertThat(bugCollection, containsExactly(9, snapStartBugMatcher().build()))); } @Test diff --git a/src/test/java/software/amazon/lambda/snapstart/lambdaexamples/LambdaUsingTs.java b/src/test/java/software/amazon/lambda/snapstart/lambdaexamples/LambdaUsingTs.java index 32464e1..7078ef0 100644 --- a/src/test/java/software/amazon/lambda/snapstart/lambdaexamples/LambdaUsingTs.java +++ b/src/test/java/software/amazon/lambda/snapstart/lambdaexamples/LambdaUsingTs.java @@ -9,6 +9,10 @@ import com.amazonaws.services.lambda.runtime.RequestHandler; import java.time.Clock; import java.time.Instant; +import java.time.LocalDateTime; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZonedDateTime; import java.util.Map; public class LambdaUsingTs implements RequestHandler, String> { @@ -19,12 +23,21 @@ public class LambdaUsingTs implements RequestHandler, String> private long tsFromSystemTimeNano; private Instant tsFromInstantNow; private Instant tsFromClock; + private LocalDateTime tsFromLocalDateTimeNow; + private LocalDate tsFromLocalDateNow; + private LocalTime tsFromLocalTimeNow; + private ZonedDateTime tsFromZonedDateTimeNow; public LambdaUsingTs(Clock clock) { tsFromSystemTimeMillis = System.currentTimeMillis(); // This is a bug tsFromSystemTimeNano = System.nanoTime(); // This is a bug tsFromInstantNow = Instant.now(); // This is a bug tsFromClock = clock.instant(); // This is a bug + tsFromLocalDateTimeNow = LocalDateTime.now(); // This is a bug + tsFromLocalDateNow = LocalDate.now(); // This is a bug + tsFromLocalTimeNow = LocalTime.now(); // This is a bug + tsFromZonedDateTimeNow = ZonedDateTime.now(); // This is a bug + logName = getLogName(); // This is a bug } @@ -40,6 +53,10 @@ public String handleRequest(Map event, Context context) { out.println(tsFromSystemTimeNano); out.println(tsFromInstantNow); out.println(tsFromClock); + out.println(tsFromLocalDateTimeNow); + out.println(tsFromLocalDateNow); + out.println(tsFromLocalTimeNow); + out.println(tsFromZonedDateTimeNow); return "200"; } }