With the original version of java.util.stream.ReferencePipeline, builds failed in the creation of 'make images'.
The failure is with the compiler error:
Creating rt.jar
warning: package com.oracle.nio does not exist
Using boot class path = [/home/robert/work/lambda/lambda/build/linux-x86_64-normal-server-release/images/lib/rt.jar, /home/robert/work/lambda/lambda/build/linux-x86_64-normal-server-release/langtools/dist/bootstrap/lib/javac.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/resources.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/sunrsasign.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/jsse.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/jce.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/charsets.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/netx.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/plugin.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/rhino.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/jfr.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/classes, /home/robert/work/lambda/lambda/build/linux-x86_64-normal-server-release/jdk/classes, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/dnsns.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/sunjce_provider.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/pulse-java.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/localedata.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/zipfs.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/sunpkcs11.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/sunec.jar, /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/ext/gnome-java-bridge.jar]
error: bad class file: /home/robert/work/lambda/lambda/build/linux-x86_64-normal-server-release/images/lib/rt.jar(java/util/stream/ReferencePipeline$1.class)
bad enclosing method attribute for class java.util.stream.ReferencePipeline$1
Please remove or make sure it appears in the correct subdirectory of the classpath.
1 error
1 warning
The error is generated in ClassReader.readEnclosingMethodAttr (since nt is null):
NameAndType nt = (NameAndType)readPool(nextChar());
...
MethodSymbol m = findMethod(nt, c.members_field, self.flags());
if (nt != null && m == null)
throw badClassFile("bad.enclosing.method", self);
On re-reading classfiles, the compiler does not enter synthetic members. See this method from ClassReader:
private void enterMember(ClassSymbol c, Symbol sym) {
if ((sym.flags_field & (SYNTHETIC|BRIDGE)) != SYNTHETIC)
c.members_field.enter(sym);
}
Lambda methods are SYNTHETIC. Changing LambdaToMethod to remove the SYNTHETIC attribute, the build succeeds.
As a workaround to this issue, ReferencePipeline was changed. To reproduce, revert the filter() method of ReferencePipeline to:
@Override
public Stream<U> filter(Predicate<? super U> predicate) {
Objects.requireNonNull(predicate);
return pipeline(Ops.<U,U>chainedRef(StreamOpFlag.NOT_SIZED,
(flags, sink) -> new Sink.ChainedReference<U>(sink) {
@Override
public void accept(U u) {
if (predicate.test(u))
downstream.accept(u);
}
}));
}
and perform a 'make images' in the new build system. The same failure will also occur in the old build system.
This is the lambda method bytecode in ReferencePipeline:
private java.util.stream.Sink lambda$72(java.util.function.Predicate, int, java.util.stream.Sink);
flags: ACC_PRIVATE, ACC_SYNTHETIC
Code:
stack=5, locals=4, args_size=4
0: new #61 // class java/util/stream/ReferencePipeline$1
3: dup
4: aload_0
5: aload_3
6: aload_1
7: invokespecial #62 // Method java/util/stream/ReferencePipeline$1."<init>":(Ljava/util/stream/ReferencePipeline;Ljava/util/stream/Sink;Ljava/util/function/Predicate;)V
10: areturn