Re: Confusing error message for inner non-public service provider

2017-02-09 Thread Vicente Romero

Hi Alex,

Thanks for your answer,
Vicente

On 02/09/2017 06:07 PM, Alex Buckley wrote:

On 2/9/2017 2:49 PM, Vicente Romero wrote:

Just to double check, the right javac behavior in this case should be to
issue similar errors in both cases like:

some position here: error: ServiceImpl is not public in
com.example.internal; cannot be accessed from outside package


It's correct to give an error, but the clause "cannot be accessed from 
outside package" should be dropped (it's not relevant to ServiceLoader).



some other position here: error: Outer.ServiceImpl is not public in
com.example.internal; cannot be accessed from outside package


It's not correct to give an error at all. The JLS (acting on behalf of 
ServiceLoader) is not interested in the class Outer.ServiceImpl being 
"accessible" by some arbitrary client. All the JLS wants is for the 
class to be 'public'.



without mentioning in any case anything about visibility right?


Correct. All the types we're discussing are in the same module so they 
(and their packages) are all visible to each other; package visibility 
is irrelevant to this example.


Alex




Re: Confusing error message for inner non-public service provider

2017-02-09 Thread Vicente Romero

Hi Alex,

Just to double check, the right javac behavior in this case should be to 
issue similar errors in both cases like:


some position here: error: ServiceImpl is not public in 
com.example.internal; cannot be accessed from outside package
some other position here: error: Outer.ServiceImpl is not public in 
com.example.internal; cannot be accessed from outside package


without mentioning in any case anything about visibility right?

Thanks,
Vicente


On 02/07/2017 02:21 PM, Alex Buckley wrote:

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