6

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.access000ドル() 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.

Nikolas
45.1k19 gold badges132 silver badges201 bronze badges
asked Aug 29, 2018 at 13:04
7
  • 1
    What happens if you replace the lambda with its respective anonymous class? Commented Aug 29, 2018 at 13:07
  • There are no errors reported if I replace it with an anonymous class Commented Aug 29, 2018 at 13:10
  • I guess it's a bug on their end, then. You should try updating to the latest version of Java to see if it's been fixed. Commented Aug 29, 2018 at 13:11
  • Supplier<String> s = () -> { return "VALUE"; }; works? Commented Aug 29, 2018 at 13:13
  • 1
    Do the program works correctly with flight recorder? Is the error only visible IN mission control? It make prefect sense under the hood some random errors and exceptions catch and handled by the JRE itself, transparently. Commented Aug 29, 2018 at 13:50

1 Answer 1

5

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.access100ドル() 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.

answered Aug 29, 2018 at 17:55
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.