Possible binary compatibility failure 2.7.7 -> 2.7.8?

Some of our services use scala-steward, so we tend to be very up-to-the-minute. So a bunch of services tried to upgrade to Play 2.7.8 a couple of hours ago, and everything went boom.

The problem appears to be that we routinely extend play.api.mvc.BaseController in our libraries – we have many stock controllers built on top of that, in various libraries. In every case, if the library is still on Play 2.7.7 or earlier, a service using it, that has upgraded to 2.7.8, is crashing with variations of this error:

java.lang.AbstractMethodError: Method com/rallyhealth/swagger/SwaggerController.play$api$mvc$BaseControllerHelpers$_setter_$defaultFormBinding_$eq(Lplay/api/data/FormBinding;)V is abstract
[info]   at com.rallyhealth.swagger.SwaggerController.play$api$mvc$BaseControllerHelpers$_setter_$defaultFormBinding_$eq(SwaggerController.scala)

The precise error depends on the library controller in question, but they’re all basically the same error. They all appear to point to this new line (Controller.scala line 78):

  implicit val defaultFormBinding: FormBinding = parse.formBinding(parse.DefaultMaxTextLength)

I confess, I’m not sure why adding this line is causing binary incompatibility, but it certainly appears to be doing so. Very consistently, at the spot where our Play-2.7.8 service instantiates the Play-2.7.7 controller that extends BaseController, it crashes in this line. When I upgrade one library, compiling my service fails on the next.

I’m not sure what the protocol is for bugs of this nature, and it’s possible that I’m misunderstanding something here, but I think Play 2.7.8 breaks lib/service binary compatibility, and it’s causing some havoc for us…

Hi @jducoeur,

thanks for raising this.
That binary incompatibility was a necessary change in order to honor a configuration setting used to prevent OOME.
Note that we’ve just found a regression introduced exactly by that line and will need to release a new version of Play. See the PR with the fix at https://github.com/playframework/playframework/pull/10592

To report this kind of issues we generally prefer GH issues, but sometimes an early discussion in this forum helps isolate the cause, determine the criticity or build a reproducer.

Thanks,

Okay, cool – hopefully that will also fix the binary incompatibility. (Not sure, but it’s possible, since it’s the initialization of defaultFormBinding that seems to be crashing – if that’s lazy, it might just not happen.)

For my reference, what are the binary-compatibility expectations for minor versions of Play? We tend to fairly casually assume that minor versions are binary-compatible, but I don’t know what the team’s policy on this actually is…

For my reference, what are the binary-compatibility expectations for minor versions of Play? We tend to fairly casually assume that minor versions are binary-compatible, but I don’t know what the team’s policy on this actually is…

All versions with the same MINOR should be binary compatible, but sometimes (very rarely) we need to introduce these breaking changes. So, yeah, the team policy is “don’t break bincompat until next MINOR unless there’s no other choice”.

In this particular case, we had an alternative for the fix that was binary compatible but not source compatible. This alternative would have required all users to add an argument to every bindFromRequest() invocation. That was worse.

Okay, good to know – thanks!