Setting a Field for a Proxy

Asked

Viewed 86 times

2

Hello, I’m having a problem: I need to change the value of a Field to a proxy.

My proxy works perfectly, but I can’t modify a Field. Whenever I try returns me an Illegalargumentexception saying I can not set the Field of such type to Proxy.

My goal is to set this Field without needing any import, ie without extending or implementing anything.

Example of what is happening:

 public class ClasseAlvo {
      Classe2 con;
 }

I need to set the variable "con" through a proxy made of "Classe2", the proxy is done successfully and my problem is to set the variable with my proxy.

public class ClasseProxy implements InvocationHandler {
    Object pc;
    public ClasseProxy(Object original) {
        this.pc = original;
    }

    public Object invocaFuncao(Method m, Object[] args) {
        try {
            return pc.getClass().getMethod(m.getName(), m.getParameterTypes()).invoke(pc, args);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        if(m.getName().equalsIgnoreCase("teste")) {
            System.out.println("Metodo teste foi executado.");
        } else {
            return invocaFuncao(m, args);
        }
        return null;
    }
}

And my interface:

public interface IClasse {
    public void teste(String nome);
}

My proxy and where is the error:

IClasse pc = (IClasse)Proxy.newProxyInstance(getClass().getClassLoader(),
                                                  new Class[] {IClasse.class},
                                                  new ClasseProxy(obj));
Field f = alvo.getClass().getDeclaredField("con");
f.setAccessible(true);
f.set(alvo, pc); // <--- O PROBLEMA

Any help is welcome.

  • 2

    Could show the code snippet that is in trouble?

  • Edited with code (cleaner version) to show my problem. I also wanted to know if it’s possible to do what I’m trying to do and if there’s another way to do it...

3 answers

1


I found the solution after a long time searching. Cglib has a great API for using Proxies.

I started reading about here

Thank you to everyone who has helped in any way.

1

The problem is that you are creating a proxy for IClasse and trying to put on a property like Classe2.

Just to remind you a little bit of polymorphism: you can assign a more specific type to a more generic variable, but nay can assign a more generic type to a variable of a more specific type.

So this can:

IClasse obj = objetoDoTipoClasse2;

But that nay can:

Classe2 obj = objetoDoTipoIClasse;

I put your code in a test project and with a single change it started to work. The change was in the ClasseAlvo, changing the type of attribute to IClasse, thus:

public class ClasseAlvo {
    IClasse con;
}
  • As I had said, I can’t change Classealvo or Classe2, I would have to do everything through Reflection. But I already found the solution using Cglib, very useful for those who want to use Proxies. Anyway, thanks for the answer, it should help other people.

0

Hello,

If I’m not mistaken, in this case the 'Classe2' should implement the 'Iclasse' interface, right?

You could try to do:

Iclasse pc = (Classe2)Proxy.newProxyInstance(getClass(). getClassLoader(), new Class[] {Iclasse.class}, new classeproxy(obj));

If 'Classe2' is implementing 'Iclasse'...

vlw

  • As I said, I need to interact with Classe2 and Classealvo without any "import", all by proxy, and the classes are not mine and I can’t just add an "Implements" to it... I don’t know if there’s a way to do it the way I want to do it, or if there might be another way to do it. That’s what I want to know.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.