Мне кажется, что было бы легче понять и прояснить, если бы проекты точек входа зависели от основного API, а не наоборот. Вы можете иметь структуру проекта, такую как:
settings.gradle
core/
build.gradle
src/
server/
build.gradle
src/
gui
build.gradle
src/
server и gui Project build.gradle файлы должны содержать:
dependencies {
implementation project(':core')
}
Проект, который использует библиотеку, может зависеть от сервера и / или GUI проецирует и создает экземпляр необходимого класса (ServerEntry или GuiEntry) напрямую.
Если вы хотите иметь возможность переключаться между различными реализациями точек входа без изменения кода в проекте, который использует экземпляр точки входа I Я бы предложил использовать инфраструктуру внедрения зависимостей (Spring, Guice, Dagger). Внедрение зависимостей поможет отделить конфигурацию (привязку интерфейсов к классам) от реального приложения.