Скорее всего, чтобы заставить разработчика плагина думать, что он делает. Если бы вместо Listener метод registerListener() принимал Object, то новички ломали бы голову, что конкретно они обязаны передать в метод. А так становится понятней, и всё подряд в метод передать уже не получится - приходится реализовать интерфейс Listener (а значит и логично, что нужно добавить обработку конкретных событий)
Хотя, например, в спонже аналога такого интерфейса нет, насколько я знаю. Можно на метод в любом классе повесить аннотацию, и это будет работать. Но в спонже и уровень навыков Java у разработчиков выше, поэтому это не является проблемой.
Ещё есть вариант, что это сделано с целью НЕ сломать обратную совместимость с плагинами, написанными под старые версии. И якобы будь возможность - уже бы переделали на тот же поход, как в спонже. Но в этот вариант верится слабо.
Но вообще в целом в Java пустые интерфейсы периодически могут использоваться:
1) Для идентификации специфики объекта при помощи instanceof
2) Для хранения в оперативной памяти в таком виде, чтобы ничего лишнего не задать переменной. Или, например, ничего лишнего не добавить в коллекцию
3) Чтобы в будущем было проще добавлять функционал объектам с общим признакам. Например, можно заранее создать интерфейс Vehicle, а уже потом когда-нибудь создать в нём метод move(). При этом сразу всем транспортным средствам в проекте придётся принудительно реализовать этот метод