I'm trying to profile a Java application with FlightRecorder and MissionControl and I'm getting some errors related to lambda functions. The app runs perfectly - the errors appear only in FR/MC.
Simple program:
import java.util.function.Supplier;
public class TestClass {
public static void main(String[] args) {
Supplier<String> s = () -> "VALUE"; // <- error at this line
}
}
Java version:
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
JVM args:
-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=delay=0s,duration=10s,filename=recording.jfr,settings=profile
Java Error as reported by FlightRecorder (open recording.jfr in MissionControl and go to Events->Log):
Class java.lang.NoSuchFieldError thrownClass class
Message method resolution failed message text
Event Thread main (thread) thread
Error.<init>(String) line: 71
LinkageError.<init>(String) line: 55
IncompatibleClassChangeError.<init>(String) line: 55
NoSuchFieldError.<init>(String) line: 57
MethodHandleNatives.resolve(MemberName, Class)
MemberName$Factory.resolve(byte, MemberName, Class) line: 975
MemberName$Factory.resolveOrFail(byte, MemberName, Class, Class) line: 1000
MethodHandles$Lookup.resolveOrFail(byte, Class, String, MethodType) line: 1386
MethodHandles$Lookup.findStatic(Class, String, MethodType) line: 780
MethodHandleImpl.findCollector(String, int, Class, Class[]) line: 1387
MethodHandleImpl.makeArrays() line: 1427
MethodHandleImpl.access$000() line: 49
MethodHandleImpl$Lazy.<clinit>() line: 610
MethodHandleImpl.varargsArray(int) line: 1506
MethodHandleImpl.varargsArray(Class, int) line: 1623
MethodHandle.asCollector(Class, int) line: 999
MethodHandleImpl$AsVarargsCollector.<init>(MethodType, MethodHandle, Class) line: 460
MethodHandleImpl$AsVarargsCollector.<init>(MethodHandle, Class) line: 454
MethodHandleImpl.makeVarargsCollector(MethodHandle, Class) line: 445
MethodHandle.setVarargs(MemberName) line: 1325
MethodHandles$Lookup.getDirectMethodCommon(byte, Class, MemberName, boolean, boolean, Class) line: 1670
MethodHandles$Lookup.getDirectMethod(byte, Class, MemberName, Class) line: 1605
MethodHandles$Lookup.findStatic(Class, String, MethodType) line: 781
CallSite.<clinit>() line: 226
MethodHandleNatives.linkCallSiteImpl(Class, MethodHandle, String, MethodType, Object, Object[]) line: 307
MethodHandleNatives.linkCallSite(Object, Object, Object, Object, Object, Object[]) line: 297
TestClass.main(String[]) line: 6
Any thoughts? Cheers.
Q 6 - Which of the following is correct about Java 8 lambda expression? A - Using lambda expression, you can refer to final variable or effectively final variable (which is assigned only once).
A lambda expression cannot throw any checked exception until its corresponding functional interface declares a throws clause. An exception thrown by any lambda expression can be of the same type or sub-type of the exception declared in the throws clause of its functional interface.
A lambda in Java essentially consists of three parts: a parenthesized set of parameters, an arrow, and then a body, which can either be a single expression or a block of Java code. In the case of the example shown in Listing 2, run takes no parameters and returns void , so there are no parameters and no return value.
Introduction. Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection .
TL;DR These two reported errors are nothing to worry about.
FlightRecorder records every throwable regardless of whether it has been handled or not, even worse, it may record errors which just have been constructed, regardless of whether they were actually been thrown. E.g., when I use the following program,
public class Test {
static NoSuchFieldError PREPARED = new NoSuchFieldError();
public static void main(String... args) {
}
}
FlightRecorder reports the following event:
Class java.lang.NoSuchFieldError thrownClass class
Message message text
Event Thread main (thread) thread
Error.<init>() line: 59
LinkageError.<init>() line: 45
IncompatibleClassChangeError.<init>() line: 45
NoSuchFieldError.<init>() line: 47
Test.<clinit>() line: 3
so we can’t even assume that every reported throwable reflects an actual error, further, exceptions thrown and caught within a framework like java.lang.invoke
are nothing that should bother us.
In this regard, note that the reported stacktrace contains MethodHandleImpl$Lazy.<clinit>()
, a class initializer of an internal class whose initialization has been triggered by CallSite.<clinit>()
, the class initializer of the class CallSite
, which is independent from your actual operation, except that the invokedynamic
instruction generated for the lambda expression triggered it.
When we use
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Test {
public static void main(String... args) {
MethodHandles.Lookup l = MethodHandles.lookup();
MethodType type = MethodType.methodType(void.class, String[].class);
try {
l.findStatic(Test.class, "main", type).asCollector(String[].class, 2);
l.findStatic(Test.class, "main", type).asCollector(String[].class, 2);
}
catch(ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
Runnable r = Test::main;
}
}
instead, we get
Name Value Identifier Content Type Relational Key
Class java.lang.NoSuchFieldError thrownClass class
Message method resolution failed message text
Event Thread main (thread) thread
Error.<init>(String) line: 71
LinkageError.<init>(String) line: 55
IncompatibleClassChangeError.<init>(String) line: 55
NoSuchFieldError.<init>(String) line: 57
MethodHandleNatives.resolve(MemberName, Class)
MemberName$Factory.resolve(byte, MemberName, Class) line: 975
MemberName$Factory.resolveOrFail(byte, MemberName, Class, Class) line: 1000
MethodHandles$Lookup.resolveOrFail(byte, Class, String, MethodType) line: 1386
MethodHandles$Lookup.findStatic(Class, String, MethodType) line: 780
MethodHandleImpl.findCollector(String, int, Class, Class[]) line: 1387
MethodHandleImpl.makeFillArrays() line: 1488
MethodHandleImpl.access$100() line: 49
MethodHandleImpl$Lazy.<clinit>() line: 611
MethodHandleImpl.varargsArray(Class, int) line: 1638
MethodHandle.asCollector(Class, int) line: 999
Test.main(String[]) line: 9
(two identical events within a millisecond)
which demonstrates that the actual class initialization trigger is indeed irrelevant, as we get the same behavior for line 9, l.findStatic(Test.class, "main", type).asCollector(String[].class, 2);
and it’s a one-time initialization thing, as we don’t get it for the identical statement on the next line and neither for the method reference a few lines below.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With