Что ж, делайте то, что у вас должно было быть долгое время раньше, раздельно реализуйте и API ... хорошо, это не всегда так просто в существующих системах, но эта модель имеет огромный успех. Когда ваш API находится в отдельном (гораздо более стабильном) пакете / jar, вы можете скомпилировать клиенты и реализации для этого пакета / jar.
Одним из ключевых качеств успешного пакета является то, что он делает как можно меньше предположений о внешнем мире. Это означает, что вам не нужно компилировать пакеты, с которыми вы работаете во время выполнения, я предпочитаю стараться не делать этого. Вы должны скомпилировать только минимальный набор зависимостей пакетов. Если сделаны предположения, они явно указаны как импортированные пакеты и использование сервисов. Хорошо спроектированные системы OSGi пытаются использовать сервисы для всех межпакетных коммуникаций. Эта модель не только избавляет от проблем с загрузкой классов, но и делает вашу сборку более изолированной.
К сожалению, большая часть кода написана в виде библиотек с довольно широким интерфейсом, потому что они содержат много функциональных возможностей, предоставляемых сервисами из коробки, таких как Factories и Listeners. Этот код имеет тесную связь между реализацией и API, поэтому вы должны иметь то же самое в пути к классам во время компиляции и в OSGi. Одним из решений этой проблемы является включение такого рода кода в комплект с его использованием (но убедитесь, что объекты этой библиотеки не просочились в другие комплекты). Небольшое дополнительное потребление памяти, но оно избавляет вас от головной боли.
Так что с OSGi попытайтесь создавать системы, основанные на сервисах, и компилировать их API сервисов, а не пакет реализации.