Search code examples
javajersey-2.0hk2dynamic-proxy

Strange behavior calling package-private method of proxied object in Jersey 2


Following class

public class MaskHolder {

    private Mask mask;
    private UUID id = UUID.randomUUID()

    void store() {
        System.out.println(id);
    }

    public void get() {
        System.out.println(id);
    }

}

is bound to HK2 like this

bind(MaskHolder.class).to(MaskHolder.class)
            .proxy(true).proxyForSameScope(false).in(RequestScoped.class);

Proxy injected to bean with @Context behaves as expected for public method but executes package-private method as well. The problem is package-private method does not trigger MethodInterceptor so it actually does not reach the same instance get() does. The question is what is this "default" instance to which proxy forwards package-private method call. Calling get() method I reach different instance on different requests but calling store method ends up in the same instance every time so it behaves like singleton.


Solution

  • There was one more thing I didn't mention - proxy behaving like singleton was injected into JacksonJsonProvider subclass. So as far as I understand this subclass of JacksonJsonProvider is created only once in Jersey so instance of proxy injected into it does not change between requests.

    Proxy is basically an artificial subclass of MaskHolder with interceptor on public methods but it basically is MaskHolder with it's UUID field. So if interceptor does not provide RequestScope bean we access "parent" MaskHolder. And because the proxy instance is injected only once to JacksonJsonProvider it is the same across requests.

    Injecting MaskHolder into resource results in different proxy instance (different UUID) across requests.