Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 751
souser Avatar asked Aug 29 '18 13:08

souser


People also ask

Is Java 8 lambda expression correct?

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

How do you handle exception thrown by lambda expression?

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.

What is a Java 8 lambda?

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.

Is lambda introduced in Java 8?

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 .


1 Answers

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.

like image 65
Holger Avatar answered Sep 26 '22 14:09

Holger