This discussion is archived
10 Replies Latest reply: Nov 21, 2010 2:59 AM by dr_nik RSS

Problem with dynamic proxy

dr_nik Newbie
Currently Being Moderated
Hi everyone!

I'm starting with dynamic object proxy and after some reading I wrote this sample code for Invocation Handler :

class Proxer implements InvocationHandler {
Object own;
public Proxer(Comparable own) {
this.own = own;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName()=="compareTo")
System.out.println("Comparing " + own + " with " + args[0]);
return method.invoke(own, args);
}
}

This proxy works well if I try this sample:

Comparable cml=(Comparable) Proxy.newProxyInstance(
Comparable.class.getClassLoader(),
new Class[] { Comparable.class },
new Proxer(new String("String1")));
System.out.println(cml.compareTo("Another String"));

Output:

Comparing String1 with Another String
18

But if I try this:

Comparable cml=(Comparable) Proxy.newProxyInstance(
Comparable.class.getClassLoader(),
new Class[] { Comparable.class },
new Proxer(new String("String1")));
System.out.println(((Comparable)("Another String")).compareTo(cml));

I got this error stack:

Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to java.lang.String
at java.lang.String.compareTo(String.java:92)
at MainClass.main(MainClass.java:147)

Is it possible to use proxy on the right side of compareTo and somehow make this typecast ?*

Thanks in advance.
  • 1. Re: Problem with dynamic proxy
    EJP Guru
    Currently Being Moderated
    What happens if you remove the cast to (Comparable)?
  • 2. Re: Problem with dynamic proxy
    dr_nik Newbie
    Currently Being Moderated
    It's not the case of ascending typecast, that's why I must show exact type to compiler: Object (from newProxyInstance) to Comparable.

    If I remove this typecast it give me type mismatch error...
  • 3. Re: Problem with dynamic proxy
    EJP Guru
    Currently Being Moderated
    But you're not doing that. You are casting String to Comparable.
  • 4. Re: Problem with dynamic proxy
    dr_nik Newbie
    Currently Being Moderated
    EJP wrote:
    But you're not doing that. You are casting String to Comparable.
    Why do you think so?

    System.out.print("Proxy is instance of Comparable? ");
    System.out.println(Proxy.newProxyInstance(Comparable.class.getClassLoader(), new Class[] { Comparable.class },new Proxer(new String("String1"))) instanceof Comparable);

    System.out.print("Proxy is instance of String? ");
    System.out.println(Proxy.newProxyInstance(Comparable.class.getClassLoader(), new Class[] { Comparable.class },new Proxer(new String("String1"))) instanceof String);
              
    System.out.print("Proxy is instance of Object? ");
    System.out.println(Proxy.newProxyInstance(Comparable.class.getClassLoader(), new Class[] { Comparable.class },new Proxer(new String("String1"))) instanceof Object);

    Output:

    Proxy is instance of Comparable? true
    Proxy is instance of String? false
    Proxy is instance of Object? true
  • 5. Re: Problem with dynamic proxy
    jtahlborn Expert
    Currently Being Moderated
    the problem comes because in your code which fails, you are calling the String.compareTo() method, which requires its argument to be a String. there is no way you will be able to generate any class or proxy (other than a String instance, of course) which you will be able to (successfully) pass into the String.compareTo() method.

    note, calling "((Comparable)myString).compareTo()" is not going to change anything. you will still be invoking the String.compareTo() method.

    Edited by: jtahlborn on Nov 20, 2010 4:48 PM
  • 6. Re: Problem with dynamic proxy
    dr_nik Newbie
    Currently Being Moderated
    Thank for your help, jtahlborn

    Cause of this exception is clear, it's just incomprehensible for me that I can invoke some specific methods that proxy implements and I can't use proxy like other "instantiated interfaces"...
  • 7. Re: Problem with dynamic proxy
    EJP Guru
    Currently Being Moderated
    You are casting String to Comparable.
    Why do you think so?
    (Comparable)"AnotherString"
    is why I think so. That's your code and that is where you are casting String to Comparable. The thing inside the quotes is a String, and the thing inside the parentheses is a typecast.

    The String.compareTo(String) method is as a result trying to cast the proxy to String, but that isn't you, that's the JRE.
    Proxy is instance of Comparable? true
    Proxy is instance of String? false
    Proxy is instance of Object? true
    These results are entirely as expected. They have nothing to do with what I wrote.

    The problem here, getting back to the point, is that compareTo(String) requires a String. Not a Comparable<String>.

    Edited by: EJP on 21/11/2010 13:52
  • 8. Re: Problem with dynamic proxy
    jtahlborn Expert
    Currently Being Moderated
    user12119858 wrote:
    Thank for your help, jtahlborn

    Cause of this exception is clear, it's just incomprehensible for me that I can invoke some specific methods that proxy implements and I can't use proxy like other "instantiated interfaces"...
    you can use a proxy like other "instantiated interfaces". it's just that in this situation the method you are trying to invoke requires a String not a Comparable. if you invoked a method which only required a Comparable, then the proxy would work just fine.
  • 9. Re: Problem with dynamic proxy
    EJP Guru
    Currently Being Moderated
    This is leading to a new train of thought. What if Comparable had been genericized like this:
    public interface Comparable<T>
    {
      int compareTo(Comparable<T>);
    }
    Not sure that would have been binary-compatible ... Anyway the point is that it wasn't, and that's why this code is failing.

    It's also curious why anybody would want to build a dynamic proxy for String. Not something that ever occurred to me in the ten years roughly that we've had the facility.
  • 10. Re: Problem with dynamic proxy
    dr_nik Newbie
    Currently Being Moderated
    Thanks both of you, I think that all clear now.

    EJP, String class has been involved in this question just for simplification of real deal.

    Edited by: user12119858 on 21.11.2010 2:41

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points