From mike at plan99.net Tue Sep 24 15:24:16 2019 From: mike at plan99.net (Mike Hearn) Date: Tue, 24 Sep 2019 17:24:16 +0200 Subject: Could we get module-private visibility? Message-ID: Hello, Often you want a method or constructor to be private to your module. The closest approximation for this today is package-private, but this isn't an ideal match. Kotlin has the "internal" modifier, which makes the modified element be visible only inside a module. This is simple and often what you want if you have small modules (which Jigsaw makes much more practical), however, the JVM doesn't understand it so it's not enforced for other languages or in reflection/sandboxing. Using package-private correctly can be tricky. Using Kotlin's notion of internal is even worse because it gets mapped to public, so in effect the entire Java ecosystem ignores it. I think the underlying issue is that packages do a lot of work. They provide at minimum: 1. Better organisation of an API in JavaDocs, so types can be given descriptions and broken up to make exploration easier for users. 2. Organisation of a codebase for developers who work on it, to stop their IDEs being overwhelmed with giant lists of classes. 3. An abstraction boundary, so implementation details can be hidden from the API user. 4. A sandboxing boundary, so capabilities can be implemented more easily. 5. A VCS access control boundary, because they map to directories and many version control systems let developers own directories. 6. An IDE autocomplete boundary, so you can glob import and get better auto completion. So it's not surprising that they get used in various different ways. The JDK is filled with weird "secrets" classes that exist mostly because of mismatches between what level of visibility is needed vs provided. Nestmates have helped mop up some tech debt in this area, but what's offered to users hasn't changed much. Writing code for sandboxed usage is hard when you simultaneously want e.g. one package per backend of your API but also need those backends to access internal methods in top-level generic API classes. Calls cross package boundaries so package-private isn't quite right. An internal modifier like Kotlin's but supported by the JVM would help a lot for crafting good APIs. Alternatively, an interesting move might be to do invokedynamic but in reverse: allow methods/c'tors/fields in class files to declare other methods as 'guards' which decide at runtime if a link should be allowed or not. Then languages can implement whatever visibility rules they want in their standard library, and more of the JVM's linker logic can be moved into Java itself. From Michael.Rasmussen at roguewave.com Tue Sep 24 16:30:06 2019 From: Michael.Rasmussen at roguewave.com (Michael Rasmussen) Date: Tue, 24 Sep 2019 16:30:06 +0000 Subject: Could we get module-private visibility? In-Reply-To: References: Message-ID: Well, public is technically module-private for any non-exported package. /Michael ________________________________ From: jigsaw-dev on behalf of Mike Hearn Sent: 24 September 2019 18:24 To: jigsaw-dev at openjdk.java.net Subject: Could we get module-private visibility? Hello, Often you want a method or constructor to be private to your module. The closest approximation for this today is package-private, but this isn't an ideal match. Kotlin has the "internal" modifier, which makes the modified element be visible only inside a module. This is simple and often what you want if you have small modules (which Jigsaw makes much more practical), however, the JVM doesn't understand it so it's not enforced for other languages or in reflection/sandboxing. Using package-private correctly can be tricky. Using Kotlin's notion of internal is even worse because it gets mapped to public, so in effect the entire Java ecosystem ignores it. I think the underlying issue is that packages do a lot of work. They provide at minimum: 1. Better organisation of an API in JavaDocs, so types can be given descriptions and broken up to make exploration easier for users. 2. Organisation of a codebase for developers who work on it, to stop their IDEs being overwhelmed with giant lists of classes. 3. An abstraction boundary, so implementation details can be hidden from the API user. 4. A sandboxing boundary, so capabilities can be implemented more easily. 5. A VCS access control boundary, because they map to directories and many version control systems let developers own directories. 6. An IDE autocomplete boundary, so you can glob import and get better auto completion. So it's not surprising that they get used in various different ways. The JDK is filled with weird "secrets" classes that exist mostly because of mismatches between what level of visibility is needed vs provided. Nestmates have helped mop up some tech debt in this area, but what's offered to users hasn't changed much. Writing code for sandboxed usage is hard when you simultaneously want e.g. one package per backend of your API but also need those backends to access internal methods in top-level generic API classes. Calls cross package boundaries so package-private isn't quite right. An internal modifier like Kotlin's but supported by the JVM would help a lot for crafting good APIs. Alternatively, an interesting move might be to do invokedynamic but in reverse: allow methods/c'tors/fields in class files to declare other methods as 'guards' which decide at runtime if a link should be allowed or not. Then languages can implement whatever visibility rules they want in their standard library, and more of the JVM's linker logic can be moved into Java itself. From mike at plan99.net Wed Sep 25 09:30:00 2019 From: mike at plan99.net (Mike Hearn) Date: Wed, 25 Sep 2019 11:30:00 +0200 Subject: Could we get module-private visibility? In-Reply-To: References: Message-ID: Yes, I know. I'm talking about module-private inside exported packages. Otherwise it can be quite difficult to allow exported and non-exported packages to work closely together without weakening visibility, and at any rate, whilst the compatibility considerations are obvious, having a visibility level of "public" that's actually private to a scope is not a design anyone would pick if they had a blank slate I imagine! From forax at univ-mlv.fr Wed Sep 25 10:17:37 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 25 Sep 2019 12:17:37 +0200 (CEST) Subject: Could we get module-private visibility? In-Reply-To: References: Message-ID: <213686971.1397008.1569406657705.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Mike Hearn" > ?: "Michael Rasmussen" > Cc: "jigsaw-dev" > Envoy?: Mercredi 25 Septembre 2019 11:30:00 > Objet: Re: Could we get module-private visibility? > Yes, I know. I'm talking about module-private inside exported packages. > Otherwise it can be quite difficult to allow exported and non-exported > packages to work closely together without weakening visibility, and at any > rate, whilst the compatibility considerations are obvious, having a > visibility level of "public" that's actually private to a scope is not a > design anyone would pick if they had a blank slate I imagine! at the same time, a public method is not really public if the class is not public too, so it's like russian dolls all the way down. R?mi