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