Why Interface Injection
Do we need interface injection, or do ClassValue and invokedynamic do everything we want?
Let's gather the use cases.
Definitions and design discussion may be found at Tobias Ivarsson's "Case for Interface Injection".
use cases for injecting the supertype *only*
In many cases, adding runtime information to arbitrary target classes can best be done with java.lang.ClassValue. The invokedynamic instruction can encode associated operations with this ClassValue.
In some cases, there is a prior commitment or inclination to use Java interfaces and perhaps interface inheritance.
Some languages (a) have infinite sets of supertypes, and (b) want to represent their types as Java classes and interfaces. Scala and Fortress are in this category.
Example: Given the way function types work, ()->String is a subtype of ()->Object. Argument type "go backwards", so (String)->void is a *supertype* of (Object)->void. In fact, (Foo)->void is a supertype of (Object->void for every subclass Foo of object! Thus, if a language represents (Object)->void as an interface IFn_Object_V, it may attempt to declare super-interfaces in the classfile of IFn_Object_V, including IFn_String_V, etc. If a new type Foo is loaded, then IFn_Foo_V should be retroactively added to the super-interface list for IFn_Object_V.
Workaround: Have the language use JVM interface subtyping as a first resort, but have its own subtype algorithm (like the JVM's) as a last resort. Same idea for method lookup, if IFn_Foo_V contains Java methods.
use cases for injecting methods
Defenders are methods which can be added to implementations of interfaces, where the implementation class and the interface are statically related; there is no need to modify a type's supertypes.