JDK-8337240 : AccessFlags factories do not require necessary arguments
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang.classfile
  • Priority: P4
  • Status: Provisional
  • Resolution: Unresolved
  • Fix Versions: 24
  • Submitted: 2024-07-25
  • Updated: 2024-07-30
Related Reports
CSR :  
Description
Summary
-------

Remove error-prone `AccessFlags` factories that do not require sufficient information (class-file major version).

Problem
-------

`AccessFlags` interpretation is class-file version specific: some flags are invalid in some versions, and we need the version to translate physical flags to logical flags. We cannot create version-specific class files as long as users can create `AccessFlags` with bad version assumptions, similar to the trouble of `String::toUpperCase` in Turkish locale with `i`.

Solution
--------

Remove the 6 factories for `AccessFlags` from public API. `AccessFlags` is reserved for parsing bit flags given the location + classfile version from the classfile builder context. Users currently can create them implicitly with individual `withFlags` methods on classfile builders, which can capture the correct classfile version from builder context.

This API change also allows us to add more APIs to perform version-specific  flag parsing (such as inferring valhalla `ACC_IDENTITY` flag from older class flags without `ACC_SUPER` set) in the future.

Specification
-------------

    diff --git a/src/java.base/share/classes/java/lang/classfile/AccessFlags.java b/src/java.base/share/classes/java/lang/classfile/AccessFlags.java
    index 283094b81d6..6c6ac75e648 100644
    --- a/src/java.base/share/classes/java/lang/classfile/AccessFlags.java
    +++ b/src/java.base/share/classes/java/lang/classfile/AccessFlags.java
    @@ -64,52 +64,4 @@ public sealed interface AccessFlags
          * method, or field}
          */
         AccessFlag.Location location();
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a class}
    -     * @param mask the flags to be set, as a bit mask
    -     */
    -    static AccessFlags ofClass(int mask) {
    -        return new AccessFlagsImpl(AccessFlag.Location.CLASS, mask);
    -    }
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a class}
    -     * @param flags the flags to be set
    -     */
    -    static AccessFlags ofClass(AccessFlag... flags) {
    -        return new AccessFlagsImpl(AccessFlag.Location.CLASS, flags);
    -    }
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a field}
    -     * @param mask the flags to be set, as a bit mask
    -     */
    -    static AccessFlags ofField(int mask) {
    -        return new AccessFlagsImpl(AccessFlag.Location.FIELD, mask);
    -    }
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a field}
    -     * @param flags the flags to be set
    -     */
    -    static AccessFlags ofField(AccessFlag... flags) {
    -        return new AccessFlagsImpl(AccessFlag.Location.FIELD, flags);
    -    }
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a method}
    -     * @param mask the flags to be set, as a bit mask
    -     */
    -    static AccessFlags ofMethod(int mask) {
    -        return new AccessFlagsImpl(AccessFlag.Location.METHOD, mask);
    -    }
    -
    -    /**
    -     * {@return an {@linkplain AccessFlags} for a method}
    -     * @param flags the flags to be set
    -     */
    -    static AccessFlags ofMethod(AccessFlag... flags) {
    -        return new AccessFlagsImpl(AccessFlag.Location.METHOD, flags);
    -    }
     }
Comments
Moving to Provisional, not Approved. One of the intended client of the AccessFlag enum was and is the class file API. Are there any additional facilities that should be added there to help support the class file API? Defining the factory methods to assume the latest class file version or adding a class file version parameter to the factories are both problematic?
30-07-2024

It is a reasonable cleanup of risky factory methods, given the fact we have more safe `withFlags` builders methods.
26-07-2024