Skip to content

Commit f2f8d85

Browse files
authored
Support scanning of classes that implement functional interface (#21)
1 parent a926cd8 commit f2f8d85

4 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/main/java/software/amazon/lambda/snapstart/ByteCodeIntrospector.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class ByteCodeIntrospector {
2525
add("com.amazonaws.services.lambda.runtime.RequestStreamHandler");
2626
}};
2727

28+
private static final String FUNCTIONAL_INTERFACE = "java.util.function.Function";
2829
private static final String CRAC_RESOURCE_INTERFACE = "org.crac.Resource";
2930

3031
private static final String RANDOM_SIGNATURE = "Ljava/util/Random;";
@@ -80,6 +81,23 @@ boolean implementsLambdaInterface(XClass xClass) {
8081
return false;
8182
}
8283

84+
/**
85+
* This returns true only when the class directly implements
86+
* <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html">Java Functional Interface</a>.
87+
*/
88+
boolean implementsFunctionalInterface(XClass xClass) {
89+
for (ClassDescriptor classDescriptor : xClass.getInterfaceDescriptorList()) {
90+
try {
91+
if (classDescriptor.getXClass().isInterface() && FUNCTIONAL_INTERFACE.equals(classDescriptor.getDottedClassName())) {
92+
return true;
93+
}
94+
} catch (CheckedAnalysisException e) {
95+
// ignore
96+
}
97+
}
98+
return false;
99+
}
100+
83101
/**
84102
* This returns true only when the class directly implements the CRaC (Coordinated Restore at Checkpoint)
85103
* <a href="https://javadoc.io/doc/io.github.crac/org-crac/latest/org/crac/Resource.html">Resource interface</a>.

src/main/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValue.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class LambdaHandlerInitedWithRandomValue extends OpcodeStackDetector {
2424

2525
private final BugReporter bugReporter;
2626
private boolean isLambdaHandlerClass;
27+
private boolean implementsFunctionalInterface;
2728
private boolean isCracResource;
2829
private boolean inInitializer;
2930
private boolean inStaticInitializer;
@@ -34,6 +35,7 @@ public class LambdaHandlerInitedWithRandomValue extends OpcodeStackDetector {
3435
public LambdaHandlerInitedWithRandomValue(BugReporter bugReporter) {
3536
this.bugReporter = bugReporter;
3637
this.isLambdaHandlerClass = false;
38+
this.implementsFunctionalInterface = false;
3739
this.isCracResource = false;
3840
this.inInitializer = false;
3941
this.inStaticInitializer = false;
@@ -48,13 +50,14 @@ public void visit(JavaClass obj) {
4850
inCracBeforeCheckpoint = false;
4951
XClass xClass = getXClass();
5052
isLambdaHandlerClass = introspector.isLambdaHandler(xClass);
53+
implementsFunctionalInterface = introspector.implementsFunctionalInterface(xClass);
5154
isCracResource = introspector.isCracResource(xClass);
5255
}
5356

5457
@Override
5558
public boolean shouldVisitCode(Code code) {
5659
boolean shouldVisit = false;
57-
if (isLambdaHandlerClass) {
60+
if (isLambdaHandlerClass || implementsFunctionalInterface) {
5861
inStaticInitializer = getMethodName().equals(Const.STATIC_INITIALIZER_NAME);
5962
inInitializer = getMethodName().equals(Const.CONSTRUCTOR_NAME);
6063
database = Global.getAnalysisCache().getDatabase(ReturnValueRandomnessPropertyDatabase.class);

src/test/java/software/amazon/lambda/snapstart/LambdaHandlerInitedWithRandomValueTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ public void testLambdaWithToString() {
152152
assertThat(bugCollection, containsExactly(1, snapStartBugMatcher().inClass("LambdaWithToString").atField("random").atLine(11).build()));
153153
}
154154

155+
@Test
156+
public void testClassImplementingFunctionalInterface() {
157+
BugCollection bugCollection = findBugsInClasses("ImplementsFunctionalInterface");
158+
assertThat(bugCollection, containsExactly(1, snapStartBugMatcher().inClass("ImplementsFunctionalInterface").atField("random").atLine(8).build()));
159+
}
160+
155161
// TODO fix all tests using this and remove this method eventually!
156162
private static void toBeFixed(Executable e) {
157163
assertThrows(AssertionError.class, e);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package software.amazon.lambda.snapstart.lambdaexamples;
2+
3+
import java.util.UUID;
4+
import java.util.function.Function;
5+
6+
public class ImplementsFunctionalInterface implements Function<String, String> {
7+
8+
private final UUID random = UUID.randomUUID();
9+
10+
@Override
11+
public String apply(String s) {
12+
return random.toString();
13+
}
14+
}

0 commit comments

Comments
 (0)