-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
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 "1.8.0_442"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_442-b06)
OpenJDK 64-Bit Server VM (Temurin)(build 25.442-b06, mixed mode)
A DESCRIPTION OF THE PROBLEM :
The provided test program demonstrates inconsistent behavior when invoking a method recursively via reflection in OpenJDK 8. The program is designed to recursively call the vMeth method using reflection, which should ideally result in a StackOverflowError. However, the program exhibits inconsistent outputs across different runs on OpenJDK 8, while it behaves consistently on OpenJDK 11, 17, and 21. Additionally, the behavior is consistent on OpenJ9.
```
public class Test {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
java.util.function.IntConsumer consumer = (int value) -> {
try {
java.lang.reflect.Method method = Test.class.getMethod("vMeth", int.class);
method.invoke(this, value);
} catch (NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
};
consumer.accept(N);
}
}
public static void main(String[] args) {
new Test().vMeth(N);
}
}
```
### Observed Behavior:
1. **Inconsistent Output on OpenJDK 8**:
(1)In some runs, the program throws a `NoClassDefFoundError`:
```
Exception in thread "main"
Exception: java.lang.NoClassDefFoundError thrown from the UncaughtExceptionHandler in thread "main"
```
(2)In other runs, it throws an `InvocationTargetException`:
```
java.lang.reflect.InvocationTargetExceptionjava.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at Test.lambda$vMeth$0(Test.java:12)
at Test.vMeth(Test.java:17)
```
2. **Consistent Output Without Reflection**:
When the recursive invocation is performed directly (without reflection), the program consistently throws a `StackOverflowError`:
```
public class Normal {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
try {
vMeth(b);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Normal().vMeth(N);
}
}
```
Output:
```
Exception in thread "main" java.lang.StackOverflowError
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
```
3. **Consistent Behavior on OpenJ9**:
On OpenJ9, the program consistently throws an `InvocationTargetException`:
```
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:503)
at Test.lambda$vMeth$0(Test.java:12)
at Test.vMeth(Test.java:17)
```
4. **Consistent Behavior on OpenJDK 11, 17, and 21**:
On OpenJDK 11, 17, and 21, the program consistently throws a `StackOverflowError` as expected.
This bug highlights an inconsistency in how OpenJDK 8 handles recursive method invocations via reflection. However, it seems that this issue is resolved in later versions, but remains unsolved in OpenJDK8.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the `Test.java` file using `javac`.
2. Run the `Test` class multiple times using OpenJDK 8 to observe the inconsistent behavior.
- Alternatively, use the following shell script to run the program 50 times and observe the output:
```
for i in {1..50}; do
pathToOpenJDK8/java -cp . Test
done
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The output should be consistent
ACTUAL -
Inconsistent output
---------- BEGIN SOURCE ----------
public class Test {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
java.util.function.IntConsumer consumer = (int value) -> {
try {
java.lang.reflect.Method method = Test.class.getMethod("vMeth", int.class);
method.invoke(this, value);
} catch (NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
};
consumer.accept(N);
}
}
public static void main(String[] args) {
new Test().vMeth(N);
}
}
---------- END SOURCE ----------
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 "1.8.0_442"
OpenJDK Runtime Environment (Temurin)(build 1.8.0_442-b06)
OpenJDK 64-Bit Server VM (Temurin)(build 25.442-b06, mixed mode)
A DESCRIPTION OF THE PROBLEM :
The provided test program demonstrates inconsistent behavior when invoking a method recursively via reflection in OpenJDK 8. The program is designed to recursively call the vMeth method using reflection, which should ideally result in a StackOverflowError. However, the program exhibits inconsistent outputs across different runs on OpenJDK 8, while it behaves consistently on OpenJDK 11, 17, and 21. Additionally, the behavior is consistent on OpenJ9.
```
public class Test {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
java.util.function.IntConsumer consumer = (int value) -> {
try {
java.lang.reflect.Method method = Test.class.getMethod("vMeth", int.class);
method.invoke(this, value);
} catch (NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
};
consumer.accept(N);
}
}
public static void main(String[] args) {
new Test().vMeth(N);
}
}
```
### Observed Behavior:
1. **Inconsistent Output on OpenJDK 8**:
(1)In some runs, the program throws a `NoClassDefFoundError`:
```
Exception in thread "main"
Exception: java.lang.NoClassDefFoundError thrown from the UncaughtExceptionHandler in thread "main"
```
(2)In other runs, it throws an `InvocationTargetException`:
```
java.lang.reflect.InvocationTargetExceptionjava.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at Test.lambda$vMeth$0(Test.java:12)
at Test.vMeth(Test.java:17)
```
2. **Consistent Output Without Reflection**:
When the recursive invocation is performed directly (without reflection), the program consistently throws a `StackOverflowError`:
```
public class Normal {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
try {
vMeth(b);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Normal().vMeth(N);
}
}
```
Output:
```
Exception in thread "main" java.lang.StackOverflowError
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
at Normal.vMeth(Normal.java:11)
```
3. **Consistent Behavior on OpenJ9**:
On OpenJ9, the program consistently throws an `InvocationTargetException`:
```
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:503)
at Test.lambda$vMeth$0(Test.java:12)
at Test.vMeth(Test.java:17)
```
4. **Consistent Behavior on OpenJDK 11, 17, and 21**:
On OpenJDK 11, 17, and 21, the program consistently throws a `StackOverflowError` as expected.
This bug highlights an inconsistency in how OpenJDK 8 handles recursive method invocations via reflection. However, it seems that this issue is resolved in later versions, but remains unsolved in OpenJDK8.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the `Test.java` file using `javac`.
2. Run the `Test` class multiple times using OpenJDK 8 to observe the inconsistent behavior.
- Alternatively, use the following shell script to run the program 50 times and observe the output:
```
for i in {1..50}; do
pathToOpenJDK8/java -cp . Test
done
```
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The output should be consistent
ACTUAL -
Inconsistent output
---------- BEGIN SOURCE ----------
public class Test {
public static final int N = 1;
public void vMeth(int b) {
for (int f = 1; f < 10000; ++f) {
java.util.function.IntConsumer consumer = (int value) -> {
try {
java.lang.reflect.Method method = Test.class.getMethod("vMeth", int.class);
method.invoke(this, value);
} catch (NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
};
consumer.accept(N);
}
}
public static void main(String[] args) {
new Test().vMeth(N);
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8196055 [linux,mac] Stackoveflow error wasn't thrown
-
- Closed
-