[ 
https://issues.apache.org/jira/browse/GROOVY-11916?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18143177#comment-18143177
 ] 

ASF GitHub Bot commented on GROOVY-11916:
-----------------------------------------

blackdrag commented on code in PR #3227:
URL: https://github.com/apache/groovy/pull/3227#discussion_r4542807437


##########
src/main/java/org/codehaus/groovy/control/ResolveVisitor.java:
##########
@@ -750,7 +750,7 @@ protected boolean resolveFromDefaultImports(final ClassNode 
type, final String[]
             // WARNING: This code does not expect a class that has a static
             //          inner class in DEFAULT_IMPORTS
             ConstructedClassWithPackage tmp = new 
ConstructedClassWithPackage(packagePrefix, typeName);
-            if (resolve(tmp, false, false, false)) {
+            if (resolve(tmp, false, false, false) && 
isStarImportAccessible(tmp, null)) {

Review Comment:
   
   > package pb;
   > public class String {}
   > 
   > package user;
   > import pb.*;
   > class Use { String s; }
   > 
   > javac: `reference to String is ambiguous, both class pb.String in pb and 
class java.lang.String in java.lang match`. An explicit `import java.lang.*` is 
redundant with the implicit one (JLS 7.5.2) and does not change that. If 
`pb.String` is package-private, the star imports nothing and the name is 
`java.lang.String`. There is no access error on `pb.String`. Row 3's "resolved 
to c.X, error if not accessible" is the opposite on both counts: the accessible 
`java.lang` type is not hidden, and the inaccessible one is not bound.
   
   Meaning this is a breaking change, and going away from the old guiding 
principle:  declared imports shadow default imports. 
   
   > Groovy's other default imports (`java.util`, `java.io`, `java.net`, 
`java.time`, `groovy.lang`, `groovy.util`, plus `BigInteger` and `BigDecimal`) 
are not the JLS implicit import. Putting them in the same tier as a star the 
user wrote would reject programs javac accepts:
   > 
   > import java.sql.*;
   > class Use { Date d; }       // javac: java.sql.Date
   > 
   > import java.awt.*;
   > class Use { List x; }       // javac: java.awt.List
   
   why do we special case them? Do we want to comply with the JLS or with how 
javac behaves? What about custom default star imports?
   
   > Both are one accessible type-import-on-demand. `java.util.Date` and 
`java.util.List` are not in scope in Java. They stay below explicit stars here, 
so those two programs keep the javac result. They also stay below module 
imports: `import module java.desktop` binds `List` to `java.awt.List`, and an 
explicit `import java.util.*` shadows that, which is the JLS 6.4.1 order 
`ImportTest` already locks. What does become ambiguous is two stars the user 
actually wrote:
   > 
   > import java.util.*;
   > import java.sql.*;
   > class Use { Date d; }       // javac: ambiguous, either order
   
   current Groovy uses the first import to resolve Date. Another breaking 
change.
    
   > The cases above are `testExplicitStarImportMatrixMatchesJavac`, 
`testSamePackageTypeShadowsOnDemandImports`, 
`testJavaLangOnDemandTiesWithExplicitStars`, 
`testStaticOnDemandImportsAreAmbiguous`, 
`testExtraDefaultImportsDoNotTieWithExplicitStars`, 
`testSingleTypeImportShadowsOnDemand` and `testJavaLangShadowsModuleImports`.
   
   `NamedVariantTransformTest` and `testSingletonGuice` show case breaking 
changes. The tests you name are not part of this PR. And at least 
`testExplicitStarImportMatrixMatchesJavac` is not in main as far as I can tell. 
I did not check the others





> Star imports should not resolve package-private types
> -----------------------------------------------------
>
>                 Key: GROOVY-11916
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11916
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: Paul King
>            Priority: Major
>
> Groovy's star import resolution (e.g., import java.util.*) currently includes 
> package-private classes in name resolution. On modern JDKs (9+) with the 
> module system, these classes cannot actually be used — attempts result in 
> IllegalAccessError at runtime. This can lead to confusing errors and 
> inconsistency with Java's behaviour where star imports only resolve public 
> types.
> For example, import java.util.* allows def cls = TimSort to compile 
> (resolving the package-private java.util.TimSort), but any actual usage 
> (instanceof, construction, method calls) fails at runtime with 
> IllegalAccessError.
> {code:groovy}
> import java.util.*
> assert String.modifiers == 17
> def cls = TimSort     // fine
> assert cls.modifiers == 0
> println cls           // => class java.util.TimSort
> println Class.forName('java.util.TimSort') // => class java.util.TimSort
> println new Object() instanceof TimSort // IllegalAccessError
> {code}
> Having said that, as a counter example, is it really any different than being 
> able to get the class via Class.forName?
> If the Java behavior is deemed correct, the fix would be to filter non-public 
> classes during star import resolution in ResolveVisitor, producing a clean 
> compile-time error instead of a runtime error. This is technically a breaking 
> change but only affects code that was already failing at runtime on modular 
> JDKs.
> This also benefits the import module feature (GROOVY-11896), which expands to 
> star imports — filtering at the resolution level means module imports 
> correctly include only public types, matching Java's import module semantics.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to