POTD: bridge method injector
(I started cross-posting blogs to my own website.)
I was working on Hudson yesterday which led me to develop this little tool called Bridge method injector.
When you are writing a library, there are various restrictions about the kind of changes you can make, in order to maintain binary compatibility.
One such restriction is an inability to restrict the return type. Say in v1 of your library you had the following code:
public Foo getFoo() {
return new Foo();
}
In v2, say if you introduce a subtype of
public FooSubType getFoo() {
return new FooSubType();
}
But if you do this, you break the binary compatibility. The clients need to be recompiled to be able to work with the new signature. This is where this bridge method injector can help. By adding an annotation like the following:
@WithBridgeMethods(Foo.class)
public FooSubType getFoo() {
return new FooSubType();
}
... and running the bytecode post processor, your class file will get the additional "bridge methods." In pseudo-code, it'll look like this:
// your original definition
@WithBridgeMethods(Foo.class)
public FooSubType getFoo() {
return new FooSubType();
}
// added bridge method
public Foo getFoo() {
invokevirtual this.getFoo()LFooSubType;
areturn
}
Such code isn't allowed in Java source files, but class files allow that. With this addition, existing clients will continue to function.
In this way, you can evolve your classes more easily without breaking backward compatibility.
For more about how to use it in your Maven project, the project website.
- Login or register to post comments
- Printer-friendly version
- kohsuke's blog
- 3978 reads






Comments
It looks like this fails on
by irobertson - 2010-10-14 14:30
It looks like this fails on static methods; the method injection isn't passing an ACC_STATIC flag in those cases.How this is possible?
by vsilaev - 2010-08-09 08:02
Kohsuke, I don't know whether or not Java verifier will allow such tricks, but Java compiler will definitely complain if one defines 2 methods that are different only by return type... Where does your annotation processor adds "briddge" code?I add such methods through
by kohsuke - 2010-08-10 07:52
I add such methods through post-processing of the bytecode.
Or to be more precise, this tool works in two stages. First during javac via annotation processing to list up where @WithBridgeMethods are used (this by another POTD of mine), then the byte-code post processing phase uses the index generated by that to do pinpoint bytecode modification.
The website linked from the main post shows how to hook this up in your Maven project.
Alternate solution
by forax - 2010-08-08 13:39
The other solution is to introduce an abstract class as supertype, and let the compiler insert the bridge method:
Rémi
nice...I just ran into this
by mezlight - 2010-08-09 05:58
nice...I just ran into this problem the other day...LOL... @Remi...I know that is the correct way but sometimes it just doesn't make sense to create an abstract class at least in my situation...I think his technique works
by kohsuke - 2010-08-09 07:56
I think his technique works equally well with interfaces, too.