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.

Reply via email to