JDK-8173252 : Lambda system not fully initialized before main method runs
  • Type: Bug
  • Component: tools
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2017-01-22
  • Updated: 2017-01-24
  • Resolved: 2017-01-24
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux localhost.localdomain 4.8.15-300.fc25.x86_64 #1 SMP Thu Dec 15 23:10:23 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
See the testcase in the attachment classpath_test.zip in the following bug:

https://github.com/lukehutch/fast-classpath-scanner/issues/103

If a static initializer in the main class is called before the main method, and it uses lambdas, then the invocation of the lambdas hangs. The Java 8 lambda system does not seem to be fully initialized until the body of the main method is run.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Check out the classpath_test.zip code linked above; load it into Eclipse as a new Maven project; and then run it in the debugger. The code will hang (in the only active thread) when the lambda is invoked, and the debugger can't even provide a useful stacktrace.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should not hang.
ACTUAL -
The code hangs.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
See link above.
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't call the lambda-calling code in a static initializer block in main, call it from the main method itself.


Comments
Closing as requested by the filer -> http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-January/046073.html
24-01-2017

This can be closed as "not an issue". Submitter now understands the issues involved: http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-January/046058.html
24-01-2017

That looks like a variation of the classic class initialization deadlock problem. Your main thread is blocked in es.submit(callable).get(); while still within the static initializer of the LambdaBug class. If the executor thread also needs to ensure LambdaBug is initialized (which it will in the lambda case) then it will wait for the main thread to complete the initialization. Hence deadlock. There may be some scope to see if the lambda initialization code can avoid the need for the enclosing class to be initialized. Need to examine the exact code generated by the compiler to determine that. As a general rule you should never block on an external action in a static initialization block, due to the risk of deadlock.
24-01-2017

To reproduce the issue , run the attached test case. Following are the results: JDK 8u121 - Fail JDK 8u122-ea - Fail JDK 9-ea +153 - Fail Following is a sample output: Entering startUp() --program hangs after printing the above line --
24-01-2017