Hello everyone,
I have the following problem: I have a Java component that implements an
arbitrary service. For JAR file design reasons and to follow the best
practices for decoupling (like Dependency Inversion Principle), I'd like
to separate API from implementation, so that I get two Ivy modules:
- myservice-api
- myservice-impl
"myservice-api" holds the Java interfaces, "myservice-impl" holds the
default implementation. "myservice-impl" depends on "myservice-api", as it
implements the interfaces:
myservice-impl --> myservice-api
Now there are a lot of other modules that want to use my arbitrary
service. These modules know my service only by its interfaces, so they
depend on "myservice-api":
x --> myservice-api
y --> myservice-api
z --> myservice-api
Furthermore, these modules are some general basic modules, and several
customer projects may use them.
Now I am puzzled by the following problem: if I have a customer project
that wants to use, say, "x" and "y", and I let Ivy resolve the
dependencies, I get "x", "y", and "myservice-api". For Ivy, everything
looks fine. However, if I fire up the runtime, there is only the API and
no implementation for my service, so nothing will work. I would have to
add "myservice-impl" as a dependency to the customer project to get a
working set of modules. As there are a dozen or so services similar to
this example service, it gets quite tedious to figure out for each
customer project which API module has no corresponding implementation
module after resolving the dependencies.
It would be nice if I was somehow warned that the current list of
dependencies is not sufficient. Does anyone know a solution? Has anyone
already encountered a similar problem?
Regards,
Christoph
PS: I like the way how Debian based Linux distros solve this problem. I
don't know how they call it, I would call it "capability". If you install
a software package that needs a mail server at runtime, this software
package does not depend on a concrete mail server like sendmail or
postfix. Instead, it declares a dependency to something that can act as a
mail server (depends on "capability: mail-server"), and concrete mail
servers declare in their package metadata that they have this capability
(provides: "capability: mail-server"). Of course you have the manual step
of choosing your preferred mail server, or there are defaults. For Ivy I
would deem it sufficient to emit a warning if there is an unmatched
capability that some module depends on.