On 14.04.20 11:09, Alan Bateman wrote:
On 14/04/2020 09:24, Jochen Theodorou wrote:
Hi all,

I am wondering if there is a solution purely in the module-info for this:

* Project requires Library1 and Library2
* SomeLibrary requires SharedApi
* OtherLibrary requires SharedApiImpl

The problem is, that it will not compile because SharedApi and
SharedApiImpl implement the same packages but not the same logic. One is
just an API, while the other is an implementation of the API.
This seems futile without first cleaning up the architectural issues.

How does SharedApi locate the implementation?

It does not, there is no SPI. It just implements the interfaces

Is this configurable or
does it always assume it's in the same run-time package as itself?

actually it does not even assume somebody else may have it. So yes.

If
the API and implementation (or default implementation) have to be in the
same run-time package then it leads to SharedApi and SharedApiImpl
needing to be combined into one module, not two.

so the best way would be to change SomeLibrary to require
SharedApiImpl... which means changing the library after the fact...
which is a tad difficult

Why is OtherLibrary requiring SharedApiImpl? This suggests that
SharedApiImpl is more than an implementation, does it have an additional
implementation specific API that OtherLibrary make use of?

There can be different implementations (it is just no an SPI
architecture). There is one that then builds on top of SharedAPI, but it
is not the implementation I need.

If you decide to combine the API and default implementation into the one
module then it will look something like this:

module api {
     exports api;
     uses spi;
}

The default implementation will be non-public classes in the same
package as the public API classes. The `uses spi` is stand in for
whatever the service type that some other implementation can provide
(assume it is indeed pluggable, why else would they be separated in the
first place?).

If you don't want to combine the API and implementation into the same
module then you'll have to move the implementation to another package so
you have something like the following fully encapsulated implementation:

module impl {
     requires api;
     provides spi with impl;
}

Different run-time packages means they can't use package-privates. If
there is an implementation-specific/extension API then impl will need to
export that package. There will be presumably be api types in the impl
specific API so the requires would change to `requires transitive api`.
OtherImpl will `requires impl`.

I see.

bye Jochen


Reply via email to