Jigsaw spec clarifications
Jesse Glick
jesse.glick at oracle.com
Fri Jan 20 06:54:56 PST 2012
On 01/20/2012 07:28 AM, Alan Bateman wrote:
>>> provides service S1 with S;
>>> provides service S2 with S;
>
> probably won't be too common (either S is an interface
Impossible; it must be a concrete class.
> or S1 or S2 is a subtype of the other)
To the contrary I see this pattern all the time in NetBeans (*), without any subtype relationship between the interfaces:
module api {
exports api;
}
package api;
public interface FrobnitzReader {
java.io.Reader parse(java.io.File frobnitz);
}
package api;
public interface FrobnitzWriter {
void store(java.io.File frobnitz, java.io.Writer writer);
}
module impl {
requires api;
provides service api.FrobnitzReader with impl.FrobnitzHandler;
provides service api.FrobnitzWriter with impl.FrobnitzHandler;
}
package impl;
public class FrobnitzHandler implements api.FrobnitzReader, api.FrobnitzWriter {
public java.io.Reader parse(java.io.File frobnitz) {...}
public void store(java.io.File frobnitz, java.io.Writer writer) {...}
}
Nothing weird there that I can see; the author of impl merely preferred to keep related code in one source file.
(This does lead to a subtle point: currently ServiceProvider.load will always instantiate a fresh copy of each service implementation class every time you call it. This
means that nonstatic fields in a S.I. class, or an explicit constructor, are usually signs of a logic error. In the above example, it means that client code would get a
different FrobnitzHandler instance for reading vs. for writing. I do not think there is any reason to change this policy when SL is used in a modular environment, but it
should at least be documented whether SL may/must/must not cache instances. This is especially true since a system using dependency injection for the same purpose would
likely behave differently.)
> I don't think the current spec mandates that the the service implementation have a public no-arg constructor. javac doesn't check for this
> currently so it's possible to get a ServiceConfigurationError at runtime for this case
Seems like a defect in the spec. If there is some problem with the signature of the service that can reliably be detected at compile time, it should be treated as an error.
(*) Using the comparable @ServiceProvider, normally paired with Lookup.getDefault but also largely compatible with ServiceLoader.
More information about the jigsaw-dev
mailing list