JDK-8047339 : Untyped object causes javac to crash when defined as lambda
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u5,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Cannot Reproduce
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2014-06-18
  • Updated: 2016-02-29
  • Resolved: 2015-08-03
Related Reports
Duplicate :  
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

A DESCRIPTION OF THE PROBLEM :
javac compiler can crash when an object with a bounded type is declared, without its generic type, to be a lambda function that uses a method available through the bounded type.

This appears to be caused by the compiler believing that two implementations of the method must exist (one for Object, one for the type bound) but obviously only one is defined by the lambda.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile code example.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should either compile, or should report a compilation error when defining the static final variable FOO.
ACTUAL -
Compiler crashed.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Failure executing javac, but could not parse the error:
An exception has occurred in the compiler (1.8.0_05). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.AssertionError
at com.sun.tools.javac.util.Assert.error(Assert.java:126)
at com.sun.tools.javac.util.Assert.check(Assert.java:45)
at com.sun.tools.javac.code.Types.functionalInterfaceBridges(Types.java:661)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$TranslationContext.<init>(LambdaToMethod.java:1685)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext.<init>(LambdaToMethod.java:1753)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.makeLambdaContext(LambdaToMethod.java:1634)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitLambda(LambdaToMethod.java:1256)
at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1618)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.tree.TreeTranslator.visitVarDef(TreeTranslator.java:153)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitVarDef(LambdaToMethod.java:1426)
at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:846)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70)
at com.sun.tools.javac.tree.TreeTranslator.visitClassDef(TreeTranslator.java:134)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitClassDef(LambdaToMethod.java:1203)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:687)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.analyzeAndPreprocessClass(LambdaToMethod.java:1156)
at com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.access$300(LambdaToMethod.java:1113)
at com.sun.tools.javac.comp.LambdaToMethod.visitClassDef(LambdaToMethod.java:223)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:687)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.comp.LambdaToMethod.translate(LambdaToMethod.java:188)
at com.sun.tools.javac.comp.LambdaToMethod.translate(LambdaToMethod.java:181)
at com.sun.tools.javac.comp.LambdaToMethod.translateTopLevelClass(LambdaToMethod.java:208)
at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1491)
at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1354)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:904)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:863)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.main.Main.compile(Main.java:381)
at com.sun.tools.javac.main.Main.compile(Main.java:370)
at com.sun.tools.javac.main.Main.compile(Main.java:361)
at com.sun.tools.javac.Main.compile(Main.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.plexus.compiler.javac.JavacCompiler.compileInProcess(JavacCompiler.java:554)
at org.codehaus.plexus.compiler.javac.JavacCompiler.compile(JavacCompiler.java:161)
at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:605)
at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:128)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public interface Test<A extends Comparable<? super A>> extends java.util.function.BiFunction<A, A, A> {

    @Override
    A apply(A a1, A a2);

    Test FOO = (a, b) -> a.compareTo(b) > 0 ? a : b;

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Define FOO using an anonymous inner class.


Comments
The issue can not be reproduced with current 9 repo
03-08-2015

Per our discussion: I have added my analysis of the failure and I'm reassigning it to you
04-10-2014

Problem occurs with the apply method inherited from BiFunction. It is erased without benefit of the type variable information from Test.
04-10-2014

What is being compared in Types.overrideEquivalent(Type t, Type s) is (java.lang.Object,java.lang.Object)java.lang.Object v.s. (java.lang.Comparable,java.lang.Comparable)java.lang.Comparable
01-10-2014

The underlying cause is that Types.overrideEquivalent(Type t, Type s) is returning false, which causes Types.findDescriptorInternal to throw failure which is caught by Types.isFunctionalInterface causing it to return false. This causes the Types.functionalInterfaceBridges() method when called with the constructed functional interface class to fail with the assertion shown in the trace-back which caused by the call to isFunctionalInterface returning false.
30-09-2014