1

Here is my openj9 version:

openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.24.0, JRE 11 Linux amd64-64-Bit Compressed References 20210120_910 (JIT enabled, AOT enabled)
OpenJ9   - 345e1b09e
OMR      - 741e94ea8
JCL      - 0a86953833 based on jdk-11.0.10+9)

When I run the following program in some other JVMs like HotSpot:

package dacapo6_26;

class Option {
    public boolean isRequired() {
        try {
            OutOfMemoryError var6 = new OutOfMemoryError("java.lang.OutOfMemoryError in ThrowCatch without counter");
            var6.initCause(new OutOfMemoryError("java.lang.OutOfMemoryError as cause exception"));
            throw var6;
        } catch (OutOfMemoryError var3) {
            /*
                The calling of var3.initCause would throw an IllegalStateException,
                since var6 has EXPLICITLY set a cause exception at line 7.
             */
            var3.initCause(new NoSuchMethodException("Cause Exception"));
        }
        return true;
    }
}

public class Harness {
    public static void main(String[] args) {
        try {
            Option option = new Option();
            System.out.println(option.isRequired());
        } catch (Exception var11) {
            /*
                The calling of var11.initCause would throw an IllegalStateException,
                since var11 has IMPLICITLY set a cause exception at line 14.
             */
            var11.initCause(new NoSuchMethodException("Cause Exception"));
            System.err.println("should not reach here");
        }
    }
}

The result is:

Exception in thread "main" java.lang.IllegalStateException: Can't overwrite cause with java.lang.NoSuchMethodException: Cause Exception
    at java.base/java.lang.Throwable.initCause(Throwable.java:462)
    at dacapo6_26.Harness.main(Harness.java:33)
Caused by: java.lang.IllegalStateException: Can't overwrite cause with java.lang.NoSuchMethodException: Cause Exception
    at java.base/java.lang.Throwable.initCause(Throwable.java:462)
    at dacapo6_26.Option.isRequired(Harness.java:12)
    at dacapo6_26.Harness.main(Harness.java:29)
Caused by: java.lang.OutOfMemoryError: java.lang.OutOfMemoryError in ThrowCatch without counter
    at dacapo6_26.Option.isRequired(Harness.java:6)
    ... 1 more
Caused by: java.lang.OutOfMemoryError: java.lang.OutOfMemoryError as cause exception
    at dacapo6_26.Option.isRequired(Harness.java:7)
    ... 1 more

But when running on the OpenJ9, the result is:

should not reach here

Is the result expected, or a bug in OpenJ9?

Does OpenJ9 miss the cause field information gained at line var3.initCause(new NoSuchMethodException("Cause Exception"));?

Thanks!

cbcwestwolf
  • 51
  • 1
  • 7
  • Maybe they do some sort of interning of OutOfMemoryError-s? What if you call the first initCause (`var6.initCause`) with some other exception like RuntimeException? – Juraj Martinka May 02 '22 at 03:51
  • Thx for your reply. I replace the `OutOfMemoryError` with `RuntimeException` in `var6.initCause`, and the result retains the same. – cbcwestwolf May 02 '22 at 04:36
  • That is strange. I have not tried with OpenJ9 but reading the source, it looks like the same behavior: https://github.com/eclipse-openj9/openj9/blob/master/jcl/src/java.base/share/classes/java/lang/Throwable.java#L383-L386 – Juraj Martinka May 02 '22 at 06:56
  • 1
    Generally, your main method catches the `IllegalStateException` thrown by the failed `initCause` at `Harness.java:12`. The specification of `initCause` says that it will throw an `IllegalStateException` if the cause is already initialized but it doesn’t say whether that `IllegalStateException` will have an initialized cause. So it has in OpenJDK, but it might not have in a different implementation. – Holger May 02 '22 at 07:46
  • @Holger So is it an undefined behavior? Could you please post the link to the specification of `initCause`? Thanks! – cbcwestwolf May 02 '22 at 11:34
  • 1
    The specification is the javadoc. https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html#initCause(java.lang.Throwable) which everyone should have bookmarked already. But to verify that this explanation is on the right track, just insert something like `System.err.println("old cause: " + var11.getCause());` before `var11.initCause(…` – Holger May 02 '22 at 12:51
  • @Holger Thanks! I think I have found a discussion for this problem: https://github.com/eclipse-openj9/openj9/issues/14873 – cbcwestwolf May 03 '22 at 11:15

1 Answers1

1

This difference has been corrected; see https://github.com/eclipse-openj9/openj9/pull/14877. The fix should be in the next (0.33.0) release of OpenJ9.