Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if class is proxified with CDI 1.2

Tags:

java

cdi

weld

In CDI 1.2 there is a way to check if a class instance is proxified? I need this because I need to get the name of original class, not the proxy name.

@Inject Bean bean;

public void sysout() {
    // will print something like com.Bean$$Weld9239823
    System.out.println(bean.getClass()); 

    // I don't know how to check if the bean instance if a proxy or real class instance
}

Using Weld classes I can do this job:

public void sysout() {
    // will print true because this is a proxy
    System.out.println(ProxyObject.class.isAssignableFrom(bean)); 

    // will print com.Bean
    System.out.println(((TargetInstanceProxy) bean).getTargetInstance());
}

In CDI 1.1 there is no method to do this. I search inside CDI 1.2 docs if a method was added about this, but I don't found anything.

So... I miss something and CDI 1.2 there is a method to get original class name and instance? Or if not, there is a plain to add this feature in near feature?

like image 908
Otávio Garcia Avatar asked Aug 29 '14 17:08

Otávio Garcia


1 Answers

For Weld on WildFly do this:

public boolean isProxy(Object obj) {
    try{
        return Class.forName("org.jboss.weld.bean.proxy.ProxyObject").isInstance(obj);
    } catch (Exception e) {
        log.error("Unable to check if object is proxy", e);
    }
    return false;
}

To retrive actual object instead of proxy (I need to serialize it) I do this:

public Object getObject(Object obj) {
    Field f = null;
    boolean isAccessible = false;
    try {
        for(Field fi : Class.forName(handler).getDeclaredFields()) {
            if(fi.getName().equals(field)) {
                f = fi;
                isAccessible = f.isAccessible();
                f.setAccessible(true);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    if(f == null) {
        throw new RuntimeException(new NoSuchFieldException(String.format(
                "The required field '%s' not found in '%s'. " +
                        "May be the code is obsolete for running on this application server.",
                field, method)));
    } else {
        try{
            obj = f.get(getHandler(obj));
            for(Method m : Class.forName(instance).getMethods()) {
                if(m.getName().equals(value)) {
                    return m.invoke(obj);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            f.setAccessible(isAccessible);
        }
        throw new NoSuchMethodError(String.format(
               "The required method '%s' not found in '%s'. " +
                       "May be the code is obsolete for running on this application server.",
                value, instance));
    }
}

Be aware, that it is the darkest magic as possible, have very poor performance and can break at any WildFly update, if they change classes, methods for fields in it.

like image 106
Anton Ermolenko Avatar answered Sep 24 '22 02:09

Anton Ermolenko