Bug 1415580 - Lamda system is not properly initialized until main method is called
Summary: Lamda system is not properly initialized until main method is called
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: java-1.8.0-openjdk
Version: rawhide
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: ---
Assignee: Roland Westrelin
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-01-23 06:23 UTC by Luke Hutchison
Modified: 2017-01-24 09:58 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2017-01-24 09:58:03 UTC
Type: Bug


Attachments (Terms of Use)

Description Luke Hutchison 2017-01-23 06:23:46 UTC
Description of problem:

If you run the code below, the JVM locks up. The Eclipse debugger is not even able to stop the locked-up thread, or determine where it is stuck. If you change the value of either of the static boolean fields, the code completes as expected. The problem seems to be that some part of the Java 8 lambda system is not properly initialized until just before the main method is called.


Version-Release number of selected component (if applicable):

java-1.8.0-openjdk-1.8.0.111-5.b16.fc25.x86_64
Also present in upstream Oracle jdk1.8.0_121-1.8.0_121-fcs.x86_64


How reproducible:

100%


Steps to Reproduce:

Run the following code with both static fields set to true. (If either or both is false, the code runs fine.)

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LambdaBug {
    // Code will hang after "Entering startUp()" if and both these are true
    private static final boolean RUN_AS_STATIC_INITIALIZER = true;
    private static final boolean RUN_USING_LAMBDA = true;

    static {
        if (RUN_AS_STATIC_INITIALIZER) {
            startUp();
        }
    }

    private static void startUp() {
        System.out.println("Entering startUp()");
        ExecutorService es = Executors.newSingleThreadExecutor();
        try {
            Callable<Void> callable;
            if (RUN_USING_LAMBDA) {
                callable = () -> {
                    System.out.println("Lambda executed");
                    return null;
                };
            } else {
                callable = new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        System.out.println("Inner class method executed");
                        return null;
                    }
                };
            }
            es.submit(callable).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        } finally {
            es.shutdown();
        }
        System.out.println("Exiting startUp()");
    }

    public static void main(String[] args) {
        if (!RUN_AS_STATIC_INITIALIZER) {
            startUp();
        }
        System.out.println("Exiting main");
    }
}



Actual results:

Code locks up, if run as shown above.


Expected results:

Code should run to completion (which it does if either of the static boolean fields' values are changed).


Additional info:

This bug is also present in the upstream Oracle JDK, but I do not have an OpenJDK Author role, so I can't file a bug in the Jira system.

Comment 1 Luke Hutchison 2017-01-24 07:54:05 UTC
The upstream bug report I filed was accepted in the Oracle bug tracker:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8173252

This appears to be a deadlock, as explained here:

http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-January/046060.html

Comment 2 Luke Hutchison 2017-01-24 09:58:03 UTC
After further discussion on the core-libs-dev mailing list, it appears that this is expected behavior.


Note You need to log in before you can comment on or make changes to this bug.