b2-sdk-java icon indicating copy to clipboard operation
b2-sdk-java copied to clipboard

bug: class initialization can re-enter `B2JsonHandlerMap.getHandler`

Open bwbeach opened this issue 5 years ago • 1 comments

This test case triggers the problem:

    /**
     * A regression test for a case where a class has a field with a default value,
     * and the class of the default value has a class initializer.
     */
    @Test
    public void testClassInitializationInDefaultValue() {
        B2Json.fromJsonOrThrowRuntime("{}", TestClassInit_ClassWithDefaultValue.class);
    }

    private static class TestClassInit_ClassWithDefaultValue {

        @B2Json.optionalWithDefault(defaultValue = "{}")
        private final TestClassInit_ClassThatDoesInitializition objThatDoesInit;

        @B2Json.constructor(params = "objThatDoesInit")
        private TestClassInit_ClassWithDefaultValue(TestClassInit_ClassThatDoesInitializition objThatDoesInit) {
            this.objThatDoesInit = objThatDoesInit;
        }
    }

    private static class TestClassInit_ClassThatDoesInitializition {

        private static TestClassInit_ClassThatDoesInitializition defaultValue =
                B2Json.fromJsonOrThrowRuntime("{}", TestClassInit_ClassThatDoesInitializition.class);

        @B2Json.constructor(params = "")
        TestClassInit_ClassThatDoesInitializition() {}
    }

bwbeach avatar Sep 06 '19 20:09 bwbeach

I hadn't thought about class initialization before. Apparently you can use reflection on a class, like B2Json does, without triggering initialization. But when you try and create an instance, it does have to initialize the class. (That part was clear.)

When the B2JsonHandlerMap is checking default values, it's still holding the lock, and hasn't yet committed to using the handlers it's setting up, but the class initialization code is trying to use them.

Not sure how to fix this.

bwbeach avatar Sep 06 '19 20:09 bwbeach