StackOverflowError on Stream primitive iterator

Paul Sandoz paul.sandoz at oracle.com
Tue May 7 03:09:32 PDT 2013


$ javap java/util/PrimitiveIterator\$OfDouble.class 
Compiled from "PrimitiveIterator.java"
public interface java.util.PrimitiveIterator$OfDouble extends java.util.PrimitiveIterator<java.lang.Double> {
  public abstract double nextDouble();
  public void forEachRemaining(java.util.function.DoubleConsumer);
  public java.lang.Double next();
  public void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
  public java.lang.Object next();
}

A bridge method is generated for "Object next()", the implementation is:

  public java.lang.Object next();
    descriptor: ()Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokeinterface #13,  1           // InterfaceMethod next:()Ljava/lang/Double;
         6: areturn       
      LineNumberTable:
        line 208: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   Ljava/util/PrimitiveIterator$OfDouble;


So i think what is happening is method dispatch is always going to the bridge method hence the stack overflow.

The example below can reproduce the problem. However, AFAICT the issue is only triggered when there are 2 or more default methods present. Comment out the default method something() and the example runs without error.

Paul.

import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;

public class A {

    public static interface OfDouble extends Iterator<Double> {

        // This causes the stack overflow
        default void something() {}
        
        double nextDouble();
        
        default Double next() {
            return nextDouble();
        }
    }

    public static void main(String[] args) {
        class Adapter implements OfDouble {
            public boolean hasNext() { return true; }
            public double nextDouble() { return 1.0; }
        }
        OfDouble i = new Adapter();
        
        Double s = i.next();
    }
}


On May 7, 2013, at 11:11 AM, Paul Sandoz <Paul.Sandoz at oracle.com> wrote:

> I can reproduce. It could either be a compiler error or hotspot method dispatch error or both when invoking default methods. Digging deeper...
> 
> Paul.
> 
> 
> On May 7, 2013, at 8:51 AM, Boaz Nahum <boaznahum at gmail.com> wrote:
> 
>> OK. I pull minutes ago latest from lambda/lambda and perform 'make clean
>> images'
>> 
>> I *rebuild** my code*
>> 
>> Still got same error
>> 
>> Boaz
> 



More information about the lambda-dev mailing list