hk2
  1. hk2
  2. HK2-78

IllegalArgumentException: not a proxy instance with @Proxiable @Scope config beans

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.*
    • Fix Version/s: 2.1.*
    • Component/s: None
    • Labels:
      None

      Description

      Problem is that for @Proxiable @Scope CGlib is used but hk2.config does not expect this.

      Problem is that for @Proxiable @Scope CGlib is used but hk2.config does not expect this.

      Attached changes for ctm-example to reproduce the problem:

      ConfigSupport.apply throws: java.lang.IllegalArgumentException: not a proxy instance
      at java.lang.reflect.Proxy.getInvocationHandler(Proxy.java:657)
      at org.jvnet.hk2.config.Dom.unwrap(Dom.java:401)
      at org.jvnet.hk2.config.ConfigSupport.apply(ConfigSupport.java:133)
      at org.jvnet.hk2.config.ConfigSupport.apply(ConfigSupport.java:113)
      at org.glassfish.examples.ctm.runme.CTMTest.testProviderEngineUsesCorrectTenant(CTMTest.java:112)

      Transactions.enroll() throws: java.lang.IllegalArgumentException: not a proxy instance
      at java.lang.reflect.Proxy.getInvocationHandler(Proxy.java:657)
      at org.jvnet.hk2.config.Transaction.enroll(Transaction.java:155)
      at org.glassfish.examples.ctm.runme.CTMTest.testProviderEngineUsesCorrectTenant(CTMTest.java:124)

      1. config-CGLib-Enhancer.patch
        5 kB
        andriy.zhdanov
      2. ctm-example.patch
        2 kB
        andriy.zhdanov
      3. proposed-fix-complete.patch
        11 kB
        andriy.zhdanov

        Activity

        Hide
        andriy.zhdanov added a comment -

        Attached proposed draft fix - reveal enhanced object.
        May be if hk2-locator used java.lang.reflect.Proxy (instead of CGLib) it could be a bit simpler.
        Core fix revealProxy() may need to be moved somewhere else also.

        Show
        andriy.zhdanov added a comment - Attached proposed draft fix - reveal enhanced object. May be if hk2-locator used java.lang.reflect.Proxy (instead of CGLib) it could be a bit simpler. Core fix revealProxy() may need to be moved somewhere else also.
        Hide
        jwells added a comment -

        So, we cannot use java.lang.reflect.Proxy because we are often proxying objects, not interfaces.

        Show
        jwells added a comment - So, we cannot use java.lang.reflect.Proxy because we are often proxying objects, not interfaces.
        Hide
        andriy.zhdanov added a comment -

        Attached complete proposed fix - improved suggested fix itself and changes to pom.xml files to make ctm-example test work in maven. Using hk2-config test-jar is needed for SimpleConfigBeanDomDecorator which is needed to make config beans be writable.

        Show
        andriy.zhdanov added a comment - Attached complete proposed fix - improved suggested fix itself and changes to pom.xml files to make ctm-example test work in maven. Using hk2-config test-jar is needed for SimpleConfigBeanDomDecorator which is needed to make config beans be writable.
        Hide
        jwells added a comment -

        Unfortunately, I don't like the way you did this. MethodInterceptorImpl is a detail of the implementation of the HK2 API that the config subsystem should not know anything about. It further assumes that cglib is being used to generate the proxy, which it should also not assume (we may use something different in the future). However, there is a mechanism to do this, though it does require a small change to the underlying API (which I will make).

        That way is to use ProxyCtl#__make. All proxies generated for @Proxiable implement the ProxyCtl interface.

        A lot of the code you have up there can be simplified (and all of the cglib specific stuff can be removed). All you would need to do is something like:

        if (service instanceof ProxyCtl)

        { ProxyCtl pc = (ProxyCtl) service; return pc.__make(); }

        This will give you back the "unwrapped" service (well, after I make my little change that will have __make return the underlying service anyway... which I will do in about five minutes).

        I hope this helps!

        Show
        jwells added a comment - Unfortunately, I don't like the way you did this. MethodInterceptorImpl is a detail of the implementation of the HK2 API that the config subsystem should not know anything about. It further assumes that cglib is being used to generate the proxy, which it should also not assume (we may use something different in the future). However, there is a mechanism to do this, though it does require a small change to the underlying API (which I will make). That way is to use ProxyCtl#__make. All proxies generated for @Proxiable implement the ProxyCtl interface. A lot of the code you have up there can be simplified (and all of the cglib specific stuff can be removed). All you would need to do is something like: if (service instanceof ProxyCtl) { ProxyCtl pc = (ProxyCtl) service; return pc.__make(); } This will give you back the "unwrapped" service (well, after I make my little change that will have __make return the underlying service anyway... which I will do in about five minutes). I hope this helps!
        Hide
        jwells added a comment -

        I have checked in the change to ProxyCtl#__make so that it now returns the underlying service. So there should be no more need to know about cglib or MethodInterceptorImpl at all, which should remain as implementation details.

        Show
        jwells added a comment - I have checked in the change to ProxyCtl#__make so that it now returns the underlying service. So there should be no more need to know about cglib or MethodInterceptorImpl at all, which should remain as implementation details.
        Hide
        andriy.zhdanov added a comment -

        Thank you, works perfectly!

        if (proxy instanceof ProxyCtl) {
          ProxyCtl proxyCtl = (ProxyCtl) proxy;
          proxy = (T) proxyCtl.__make();
        }
        

        Committed revision 3927: reveal ConfigBeanProxy from @Proxiable object

        Show
        andriy.zhdanov added a comment - Thank you, works perfectly! if (proxy instanceof ProxyCtl) { ProxyCtl proxyCtl = (ProxyCtl) proxy; proxy = (T) proxyCtl.__make(); } Committed revision 3927: reveal ConfigBeanProxy from @Proxiable object
        Hide
        tlcksnyder added a comment -

        completed & available.

        Show
        tlcksnyder added a comment - completed & available.

          People

          • Assignee:
            Mahesh Kannan
            Reporter:
            andriy.zhdanov
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: