JDK-8356696 : javac accepts illegal modifier on local class in violation of JLS §14.3
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 16,25
  • Priority: P3
  • Status: New
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2025-05-10
  • Updated: 2025-05-12
Related Reports
Causes :  
Description
ADDITIONAL SYSTEM INFORMATION :
macOS version:

```
Software:

    System Software Overview:

      System Version: macOS 13.2 (22D49)
      Kernel Version: Darwin 22.3.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      Computer Name: MacBook Pro
      User Name: MacBook
      Secure Virtual Memory: Enabled
      System Integrity Protection: Enabled
      Time since boot: 1 day, 2 hours, 19 minutes

Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro18,1
      Model Number: MK193CH/A
      Chip: Apple M1 Pro
      Total Number of Cores: 10 (8 performance and 2 efficiency)
      Memory: 16 GB
      System Firmware Version: 8419.80.7
      OS Loader Version: 8419.80.7
      Activation Lock Status: Disabled
```

OpenJDK version:

```
openjdk version "11.0.27" 2025-04-15
OpenJDK Runtime Environment Temurin-11.0.27+6 (build 11.0.27+6)
OpenJDK 64-Bit Server VM Temurin-11.0.27+6 (build 11.0.27+6, mixed mode)

openjdk version "17.0.15" 2025-04-15
OpenJDK Runtime Environment Temurin-17.0.15+6 (build 17.0.15+6)
OpenJDK 64-Bit Server VM Temurin-17.0.15+6 (build 17.0.15+6, mixed mode, sharing)

openjdk version "21.0.7" 2025-04-15 LTS
OpenJDK Runtime Environment Temurin-21.0.7+6 (build 21.0.7+6-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.7+6 (build 21.0.7+6-LTS, mixed mode, sharing)
```

A DESCRIPTION OF THE PROBLEM :
The following test program declares a local class within a code block. When compiled with `javac` of JDK 17 or JDK 21, it compiles without any error. However, compiling the same code using `javac` of JDK 11 or the Eclipse Compiler for Java (ECJ) results in a compilation error.

```
public class Test {
    public static void main(String[] args) {
        var outer = new java.lang.Object() {
            private class Inner {
                public void method() {
                    System.out.println("Inner local class method");
                }
            }
        };
    }
}
```

### Observed Behavior:

Using `javac` of JDK17 or JDK21, the program compiles successfully without any error.

```
>>> pathToJDK17/javac Test.java
>>> pathToJDK21/javac Test.java
```

However, using `javac` of JDK 11:

```
>>> pathToJDK11/javac Test.java
Test.java:4: error: modifier private not allowed here
            private class Inner {
                    ^
1 error
```

and, compiling the same code with **ECJ** produces the following error:

```java
>>> java -cp . -jar ecj-4.36.jar --release 21 -d . Test.java
----------
1. ERROR in /Test.java (at line 4)
        private class Inner {
                      ^^^^^
Illegal modifier for the local class Inner; only abstract or final is permitted
----------
1 problem (1 error)
```

According to the [Java Language Specification, §14.3](https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html#jls-14.3):

> “It is a compile-time error if a local class or interface declaration has any of the access modifiers public, protected, or private (§6.6).”
> 

This means local classes must not use access modifiers like `private`.

ECJ and JDK 11 correctly reject the code, adhering to the specification.

However, JDK 17 and JDK 21’s `javac` compilers silently accept it, which contradicts the language specification and may indicate a potential bug.

REGRESSION : Last worked in version 11.0.27

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile `Test.java` using `javac` from JDK 17 or JDK 21 — observe that it compiles successfully.
2. Compile `Test.java` using `javac` from JDK 11 — observe the compilation error.
3. Compile `Test.java` using ECJ (e.g., version 4.36) — observe the error.
4. Compare the outputs for consistency with the Java Language Specification.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program should report a compile-time error.
ACTUAL -
The program compiles successfully without any error.

---------- BEGIN SOURCE ----------
public class Test {
    public static void main(String[] args) {
        var outer = new java.lang.Object() {
            private class Inner {
                public void method() {
                    System.out.println("Inner local class method");
                }
            }
        };
    }
}
---------- END SOURCE ----------


Comments
Impact -> H (Regression) Likelihood -> L (Not an issue) Workaround -> M (Somewhere in-between the extremes) Priority -> P3
11-05-2025

The issue is caused by JDK-8254321. Since JDK 16 static members can be declared in inner classes. Closed as not an issue.
11-05-2025