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.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.

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.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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.