Possible bug in the compiler
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Sep 7 11:33:17 UTC 2018
Hi,
from the looks of it, seems like a latent bug that is made more explicit
by the fact that the compiler now fails over when attempting to generate
a bad signature containing an intersection type (which is not legal at
the VM level). If I'm correct, even if the code compile correctly with
JDK 10, the bytecode you got out of that was probably illegal, which
might be in itself a javac issue.
Also, Javac should generate a better error message, so there's
definitively an issue here (e.g. the compiler should not crash like this).
Seems to me that your example has to do with serializable lambdas, but
your simplified test case doesn't have Serializable lambdas in them -
could that be the issue?
I'm able to reproduce with this:
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.function.*;
class JDK11CompilerBug {
interface IFilter {
Component getComponent();
}
static class Filter implements IFilter {
@Override
public Component getComponent() { return null; }
}
public Component buildFilter(List<? extends Filter> l, Dialog dialog) {
Panel c = new Panel();
l.stream()
.map(f -> {
Button btn = (Button) f.getComponent();
btn.addActionListener((java.io.Serializable &
ActionListener)evt -> {
applyFilter(f);
dialog.setVisible(false);
});
return btn;
})
.forEach(c::add);
return c;
}
private void applyFilter(IFilter f) {}
}
And, if I fix the compiler crash, I get this better message:
error: error while generating class JDK11CompilerBug
(illegal signature attribute for type CAP#1)
where CAP#1 is a fresh type-variable:
CAP#1 extends Filter from capture of ? extends Filter
1 error
So indeed it looks as if the compiler was trying to generate an illegal
signature here. But - there's a caveat here - the signature generation
logic here is just called in order to get a unique string that we can
use for the lambda deserialized method. So, whether that contains
characters that are illegal for the VM or not, it's not great cause of
concern and one might argue that the compiler is being overly zealous here.
I will followup with creating a new issue and issue a RFR as I think I
have a fix.
Maurizio
On 07/09/18 09:45, Andrej Golovnin wrote:
> Hi all,
>
> I'm in the process to migrate our product to Java 11.
> When I try to compile our product using javac from OpenJDK 11 (build 11+28),
> then the compiler stops at some point with the following exception:
>
> compiler message file broken: key=compiler.misc.msg.bug arguments=11,
> {1}, {2}, {3}, {4}, {5}, {6}, {7}
> com.sun.tools.javac.code.Types$SignatureGenerator$InvalidSignatureException
> at jdk.compiler/com.sun.tools.javac.code.Types$SignatureGenerator.assembleSig(Types.java:5107)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod.typeSig(LambdaToMethod.java:2436)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext.serializedLambdaDisambiguation(LambdaToMethod.java:2049)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext.serializedLambdaName(LambdaToMethod.java:2082)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor$LambdaTranslationContext.complete(LambdaToMethod.java:2282)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.analyzeLambda(LambdaToMethod.java:1477)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitLambda(LambdaToMethod.java:1454)
> at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1807)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.visitApply(TreeTranslator.java:280)
> at jdk.compiler/com.sun.tools.javac.comp.LambdaToMethod$LambdaAnalyzerPreprocessor.visitApply(LambdaToMethod.java:1337)
> at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1634)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.visitExec(TreeTranslator.java:250)
> at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1452)
> at jdk.compiler/com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
> ...
> (I can provide the full stack trace when needed.)
>
> Unfortunately I'm not able to create a small example to reproduce this error.
> But the code that causes this error looks like this:
>
> public class JDK11CompilerBug {
>
> interface IFilter {
> Component getComponent();
> }
>
> static class Filter implements IFilter {
>
> @Override
> public Component getComponent() {}
>
> }
>
> public Component buildFilter(List<? extends Filter> l, Dialog dialog) {
> Panel c = new Panel();
> l.stream()
> .map(f -> {
> Button btn = (Button) f.getComponent();
> btn.addActionListener(evt -> {
> applyFilter(f);
> dialog.setVisible(false);
> });
> return btn;
> })
> .forEach(c::add);
> return c;
> }
>
> private void applyFilter(IFilter f) {}
>
> }
>
> When I remove the call "applyFilter(f);", then the error disappears.
> But this is not really helpful.
>
> The real workaround is to add the type to the lambda parameter:
> .map((Filter f) -> {}).
> When I do so, then the project is compiled without any problem.
>
> The compiler from OpenJDK 10 compiles the project even without this
> modifications.
>
> I hope this helps to identify the problem in the compiler.
> Please let me know if there are some options that allow to get more
> diagnostic informations from the compiler. (FYI: I have already tried
> -Xdiags:verbose.
> But it doesn't seem to produce any useful information or I'm not able
> to find it.)
>
> Best regards,
> Andrej Golovnin
More information about the compiler-dev
mailing list