Type Inference is Causing Verification Error
Ming-Yee Iu
mingyeeiu+lambda at gmail.com
Fri Sep 3 09:58:25 PDT 2010
I have a piece of code that seems to compile fine, but when I run it,
it generates a verification error.
I'm putting together a LINQish system for Java7, but the my system is
based only on bytecode analysis and uses no bytecode rewriting, so it
looks like a compiler problem (in fact, I haven't implemented nested
queries yet, so this piece of code was not successfully translated
into SQL by my system and was simply running directly).
Here is the code fragment that fails:
DBSet<Pair<Tuple3<Integer, String, String>, Integer>> matches =
db.allDBOrderLine()
.group(
#(ol)
{
DBItem i = ol.getItem();
DBAuthor a = i.getAuthor();
return new Tuple3<Integer, String, String>(i.getItemId(),
i.getTitle(), a.getFirstName());
},
#(key, olset) {
new Pair<Tuple3<Integer, String, String>, Integer>(
key, olset.sumInt(#(ol){ol.getQuantity()}))}
);
------
The definition of the group() method is
interface DBSet<T> extends Collection<T> {
...
public static interface AggregateInteger<U> {
public int aggregate(U val);
}
public int sumInt(AggregateInteger<T> aggregate);
...
public static interface AggregateSelect<U, V> {
public V aggregateSelect(DBSet<U> val);
}
public static interface AggregateGroup<W, U, V> {
public V aggregateSelect(W key, DBSet<U> val);
}
public <U, V> DBSet<Pair<U, V>> group(Select<T, U> select,
AggregateGroup<U, T, V> aggregate);
}
------
The verification error is
Exception in thread "main" java.lang.VerifyError: Bad return type in
method Test$2.aggregateSelect(Lch/epfl/labos/iu/orm/Tuple3;Lch/epfl/labos/iu/orm/DBSet;)Ljava/lang/Integer;
at offset 25
at Test.main(Test.java:12)
-----
The javap of Test$2 is
class Test$2 extends java.lang.Object implements
ch.epfl.labos.iu.orm.DBSet$AggregateGroup<ch.epfl.labos.iu.orm.Tuple3<java.lang.Integer,
java.lang.String, java.lang.String>,
ch.epfl.labos.iu.tpcw.entities.DBOrderLine, java.lang.Integer> {
public java.lang.Integer
aggregateSelect(ch.epfl.labos.iu.orm.Tuple3<java.lang.Integer,
java.lang.String, java.lang.String>,
ch.epfl.labos.iu.orm.DBSet<ch.epfl.labos.iu.tpcw.entities.DBOrderLine>);
Code:
0: new #2 // class ch/epfl/labos/iu/orm/Pair
3: dup
4: aload_1
5: aload_2
6: new #3 // class Test$2$1
9: dup
10: aload_0
11: invokespecial #4 // Method
Test$2$1."<init>":(LTest$2;)V
14: invokeinterface #5, 2 // InterfaceMethod
ch/epfl/labos/iu/orm/DBSet.sumInt:(Lch/epfl/labos/iu/orm/DBSet$AggregateInteger;)I
19: invokestatic #6 // Method
java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
22: invokespecial #7 // Method
ch/epfl/labos/iu/orm/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
25: areturn
Test$2();
Code:
0: aload_0
1: invokespecial #1 // Method
java/lang/Object."<init>":()V
4: return
public java.lang.Object aggregateSelect(java.lang.Object,
ch.epfl.labos.iu.orm.DBSet);
Code:
0: aload_0
1: aload_1
2: checkcast #8 // class ch/epfl/labos/iu/orm/Tuple3
5: aload_2
6: invokevirtual #9 // Method
aggregateSelect:(Lch/epfl/labos/iu/orm/Tuple3;Lch/epfl/labos/iu/orm/DBSet;)Ljava/lang/Integer;
9: areturn
}
----
I may have gotten the generics in my definition of group() mixed up,
but my intention was for Test$2.aggregateSelect() to return a Pair and
not an Integer (in any case, the compiler should not generate code
that does not verify).
-Ming
More information about the lambda-dev
mailing list