Confusing error message for inner non-public service provider

Alex Buckley alex.buckley at oracle.com
Tue Feb 7 19:21:41 UTC 2017


On 2/7/2017 1:11 AM, Gunnar Morling wrote:
>      ---
>      package com.example;
>      public interface SomeService {
>          public void foo();
>      }
>      ---
>      package com.example.internal;
>      class Outer {
>
>          public static class ServiceImpl implements com.example.SomeService {
>              public ServiceImpl() {}
>              public void foo() {}
>          }
>      }
>      ---
>      package com.example.internal;
>      class ServiceImpl implements com.example.SomeService {
>          public ServiceImpl() {}
>          public void foo() {}
>      }
>      ---
>      module com.example {
>          exports com.example;
>          provides com.example.SomeService with com.example.internal.ServiceImpl;
>          provides com.example.SomeService with
> com.example.internal.Outer.ServiceImpl;
>      }
>      ---
>
> Essentially, I'm wondering:
>
> * Why Outer.ServiceImpl triggers the error about package visibility
> while ServiceImpl doesn't (I had a look at the EDR JLS, but I couldn't
> find an explanation for that, happy about any specific pointers).
> * Why Outer.ServiceImpl triggers "does not have a default constructor"
> (ServiceImpl does not). Maybe a hint would be nice that is caused by
> Outer not having public access.

Thanks for showing the code. Since everything in the same module, 
package visibility is not relevant and javac shouldn't mention it.

I suspect that javac is getting tripped up by the fact that 
Outer.ServiceImpl is declared 'public' (as the JLS and ServiceLoader 
both demand) but it isn't widely accessible, even within the com.example 
module, due to Outer's default (package) access. I believe the JLS and 
ServiceLoader rules are correct, so it's a javac bug.

Alex


More information about the jigsaw-dev mailing list