[ 
https://issues.apache.org/jira/browse/WW-5678?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Lukasz Lenart updated WW-5678:
------------------------------
    Description: 
Follow-up to [WW-5674|https://issues.apache.org/jira/browse/WW-5674], deferred 
to 8.0.0 because part of it is a source-breaking change.

{panel:title=Check WW-5675 before starting}
Item 1 below may already be gone. WW-5675 carries a design note proposing that 
the two allowlist sets be replaced by a single precomputed union, which would 
delete the three-argument overload outright — and with it the name collision. 
Confirm the state of WW-5675 before planning any work here.
{panel}

h2. 1. The package-private overload shares a name with a public method

WW-5674 left {{SecurityMemberAccess}} with three related static methods:

{code:java}
public static boolean isClassBelongsToPackages(Class clazz, Set 
matchingPackages)     // public API
       static boolean isClassBelongsToPackages(Class clazz, Set first, Set 
second)    // package-private
       static boolean isPackageBelongsToPackages(String packageName, Set first, 
Set second)
{code}

(Generics omitted above — the issue tracker mangles them.)

The two-argument form is public; the three-argument overload deliberately is 
not, because it has a single caller ({{isClassAllowlisted}}) and its only test 
lives in the same package. Publishing it would freeze it as {{struts2-core}} 
API.

Sharing a name across the visibility boundary is a hazard: a contributor 
tidying up "an inconsistent modifier" can widen the overload to {{public}} by 
reflex and never realise they have added permanent API surface. Giving the 
package-private overload a distinct name removes the trap. This part is not 
source-breaking and could land earlier if convenient.

As noted above, WW-5675 may remove this method altogether. The two-set 
parameter exists only because a precomputed union of 
{{ALLOWLIST_REQUIRED_PACKAGES}} and {{allowlistPackageNames}} is not currently 
worthwhile under the prototype bean scope; once WW-5675 makes the parsed 
configuration shared, the union becomes the better shape and the overload 
disappears.

h2. 2. The names are grammatically awkward

{{isClassBelongsToPackages}} and {{isPackageBelongsToPackages}} read as "is 
class belongs to packages". Something like {{classBelongsToAnyPackage}} / 
{{packageMatchesAny}} would be clearer. The public one cannot be renamed before 
a major release.

This item stands regardless of what WW-5675 does.

h2. 3. Two public statics have no callers outside the class

{{isClassBelongsToPackages(Class, Set)}} and {{toPackageName(Class)}} are both 
{{public static}} on a public class, but a repository-wide search finds no 
caller outside {{SecurityMemberAccess}} itself — not in core, not in any 
plugin, not in the tests. They appear to be public by accident rather than by 
design.

Narrowing them to package-private would shrink the surface that has to be 
preserved. This _is_ source-breaking for anyone who happens to call them, hence 
8.0.0. This item also stands regardless of WW-5675.

h2. Why this matters now

WW-4759 is drawing the {{struts2-api}} boundary for 8.0.0. Deciding what in 
{{SecurityMemberAccess}} is genuinely API is part of the same exercise, and it 
is cheaper to settle it while that work is open than to inherit these three 
methods into the new artefact unexamined.

h2. Constraints

{{SecurityMemberAccessPackageMatchingTest}} calls all three methods directly 
and will need updating. Any rename must not disturb the frozen 
{{legacyPrefixMatch}} and {{legacyToPackageName}} reference oracles in that 
test — they are verbatim copies of the pre-WW-5674 implementation kept as 
differential oracles, and they must continue to _not_ delegate to production 
code.

Renaming or narrowing anything public needs a migration-guide entry.

  was:
Follow-up to [WW-5674|https://issues.apache.org/jira/browse/WW-5674], deferred 
to 8.0.0 because part of it is a source-breaking change.

h2. 1. The package-private overload shares a name with a public method

WW-5674 left {{SecurityMemberAccess}} with three related static methods:

{code:java}
public static boolean isClassBelongsToPackages(Class clazz, Set 
matchingPackages)     // public API
       static boolean isClassBelongsToPackages(Class clazz, Set first, Set 
second)    // package-private
       static boolean isPackageBelongsToPackages(String packageName, Set first, 
Set second)
{code}

(Generics omitted above — the issue tracker mangles them.)

The two-argument form is public; the three-argument overload deliberately is 
not, because it has a single caller ({{isClassAllowlisted}}) and its only test 
lives in the same package. Publishing it would freeze it as {{struts2-core}} 
API.

Sharing a name across the visibility boundary is a hazard: a contributor 
tidying up "an inconsistent modifier" can widen the overload to {{public}} by 
reflex and never realise they have added permanent API surface. Giving the 
package-private overload a distinct name removes the trap. This part is not 
source-breaking and could land earlier if convenient.

h2. 2. The names are grammatically awkward

{{isClassBelongsToPackages}} and {{isPackageBelongsToPackages}} read as "is 
class belongs to packages". Something like {{classBelongsToAnyPackage}} / 
{{packageMatchesAny}} would be clearer. The public one cannot be renamed before 
a major release.

h2. 3. Two public statics have no callers outside the class

{{isClassBelongsToPackages(Class, Set)}} and {{toPackageName(Class)}} are both 
{{public static}} on a public class, but a repository-wide search finds no 
caller outside {{SecurityMemberAccess}} itself — not in core, not in any 
plugin, not in the tests. They appear to be public by accident rather than by 
design.

Narrowing them to package-private would shrink the surface that has to be 
preserved. This _is_ source-breaking for anyone who happens to call them, hence 
8.0.0.

h2. Why this matters now

WW-4759 is drawing the {{struts2-api}} boundary for 8.0.0. Deciding what in 
{{SecurityMemberAccess}} is genuinely API is part of the same exercise, and it 
is cheaper to settle it while that work is open than to inherit these three 
methods into the new artefact unexamined.

h2. Constraints

{{SecurityMemberAccessPackageMatchingTest}} calls all three methods directly 
and will need updating. Any rename must not disturb the frozen 
{{legacyPrefixMatch}} and {{legacyToPackageName}} reference oracles in that 
test — they are verbatim copies of the pre-WW-5674 implementation kept as 
differential oracles, and they must continue to _not_ delegate to production 
code.

Renaming or narrowing anything public needs a migration-guide entry.


> Tidy up the SecurityMemberAccess package-matching helper names and visibility
> -----------------------------------------------------------------------------
>
>                 Key: WW-5678
>                 URL: https://issues.apache.org/jira/browse/WW-5678
>             Project: Struts 2
>          Issue Type: Improvement
>            Reporter: Lukasz Lenart
>            Priority: Major
>             Fix For: 8.0.0
>
>
> Follow-up to [WW-5674|https://issues.apache.org/jira/browse/WW-5674], 
> deferred to 8.0.0 because part of it is a source-breaking change.
> {panel:title=Check WW-5675 before starting}
> Item 1 below may already be gone. WW-5675 carries a design note proposing 
> that the two allowlist sets be replaced by a single precomputed union, which 
> would delete the three-argument overload outright — and with it the name 
> collision. Confirm the state of WW-5675 before planning any work here.
> {panel}
> h2. 1. The package-private overload shares a name with a public method
> WW-5674 left {{SecurityMemberAccess}} with three related static methods:
> {code:java}
> public static boolean isClassBelongsToPackages(Class clazz, Set 
> matchingPackages)     // public API
>        static boolean isClassBelongsToPackages(Class clazz, Set first, Set 
> second)    // package-private
>        static boolean isPackageBelongsToPackages(String packageName, Set 
> first, Set second)
> {code}
> (Generics omitted above — the issue tracker mangles them.)
> The two-argument form is public; the three-argument overload deliberately is 
> not, because it has a single caller ({{isClassAllowlisted}}) and its only 
> test lives in the same package. Publishing it would freeze it as 
> {{struts2-core}} API.
> Sharing a name across the visibility boundary is a hazard: a contributor 
> tidying up "an inconsistent modifier" can widen the overload to {{public}} by 
> reflex and never realise they have added permanent API surface. Giving the 
> package-private overload a distinct name removes the trap. This part is not 
> source-breaking and could land earlier if convenient.
> As noted above, WW-5675 may remove this method altogether. The two-set 
> parameter exists only because a precomputed union of 
> {{ALLOWLIST_REQUIRED_PACKAGES}} and {{allowlistPackageNames}} is not 
> currently worthwhile under the prototype bean scope; once WW-5675 makes the 
> parsed configuration shared, the union becomes the better shape and the 
> overload disappears.
> h2. 2. The names are grammatically awkward
> {{isClassBelongsToPackages}} and {{isPackageBelongsToPackages}} read as "is 
> class belongs to packages". Something like {{classBelongsToAnyPackage}} / 
> {{packageMatchesAny}} would be clearer. The public one cannot be renamed 
> before a major release.
> This item stands regardless of what WW-5675 does.
> h2. 3. Two public statics have no callers outside the class
> {{isClassBelongsToPackages(Class, Set)}} and {{toPackageName(Class)}} are 
> both {{public static}} on a public class, but a repository-wide search finds 
> no caller outside {{SecurityMemberAccess}} itself — not in core, not in any 
> plugin, not in the tests. They appear to be public by accident rather than by 
> design.
> Narrowing them to package-private would shrink the surface that has to be 
> preserved. This _is_ source-breaking for anyone who happens to call them, 
> hence 8.0.0. This item also stands regardless of WW-5675.
> h2. Why this matters now
> WW-4759 is drawing the {{struts2-api}} boundary for 8.0.0. Deciding what in 
> {{SecurityMemberAccess}} is genuinely API is part of the same exercise, and 
> it is cheaper to settle it while that work is open than to inherit these 
> three methods into the new artefact unexamined.
> h2. Constraints
> {{SecurityMemberAccessPackageMatchingTest}} calls all three methods directly 
> and will need updating. Any rename must not disturb the frozen 
> {{legacyPrefixMatch}} and {{legacyToPackageName}} reference oracles in that 
> test — they are verbatim copies of the pre-WW-5674 implementation kept as 
> differential oracles, and they must continue to _not_ delegate to production 
> code.
> Renaming or narrowing anything public needs a migration-guide entry.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to