souser
souser

Reputation: 139

Java 8 lambda errors

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.

Upvotes: 6

Views: 374

Answers (1)

Holger
Holger

Reputation: 298539

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.

Upvotes: 5

Related Questions