Setting a Field for a Proxy

2

Hello, I have a problem: I need to change the value of a Field to a proxy.

My proxy works perfectly, but I can not modify a Field. Whenever I try it returns an IllegalArgumentException saying that 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's happening:

 public class ClasseAlvo {
      Classe2 con;
 }

I need to set the variable "con" through a Proxy made of "Class2", the proxy is successfully done 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 the error is:

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.

    
asked by anonymous 11.07.2014 / 03:39

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

Thanks to all who have helped in some way.

    
15.07.2014 / 03:22
1

The problem is that you are creating a proxy for IClasse and trying to put it in a property of type Classe2 .

Just to recall a bit of polymorphism: you can assign a more specific type to a more generic variable, but not can assign a more generic type to a variable of a more specific type. p>

So, this can:

IClasse obj = objetoDoTipoClasse2;

But not can:

Classe2 obj = objetoDoTipoIClasse;

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

public class ClasseAlvo {
    IClasse con;
}
    
16.07.2014 / 15:25
0

Hello,

If I am not mistaken, in this case 'Class2' should implement the 'IClasse' interface, right?

You could try doing:

IClasse pc = (Class2) Proxy.newProxyInstance (getClass (). getClassLoader (),                                                   new Class [] {IClasse.class},                                                   new ClassProxy (obj));

If Class2 is implementing 'IClasse' ...

vlw

    
13.07.2014 / 02:13