Checking Proxy with CDI 1.2

Is there a way in CDI 1.2 to check if an instance of a class is checked? I need this because I need to get the name of the source class, not the name of the proxy.

@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 the Weld classes, I can do this work:

 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()); } 

There is no way to do this in CDI 1.1. I am looking in CDI 1.2 docs if a method was added about this, but I did not find anything.

So ... I missed something, and CDI 1.2 is there a way to get the original class name and instance? Or, if not, is there a simple way to add this function to the nearest function?

+5
source share
3 answers

For Weld on WildFly, do the following:

 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 extract the actual object instead of the 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)); } } 

Remember that this is the darkest magic, as far as possible, they have very low performance and can break during any WildFly update, if they change classes, methods for fields in it.

+2
source

This is a terrible hack, but for Weld (and possibly for other implementations) you can check if the class name is “Proxy”: possibleProxy.getClass().getSimpleName().contains("Proxy") . I use it only for logging to get a cleaned version of the wrapped class name:

 /** * Get the actual simple name of the objects class that might be wrapped by * a proxy. A "simple" class name is not fully qualified (no package name). * * @param possibleProxy an object that might be a proxy to the actual * object. * @return the simple name of the actual object class */ public static String getActualSimpleClassName(final Object possibleProxy) { final String outerClassName = possibleProxy.getClass().getSimpleName(); final String innerClassName; if (outerClassName.contains("Proxy")) { innerClassName = outerClassName.substring(0, outerClassName.indexOf('$')); } else { innerClassName = outerClassName; } return innerClassName; } 
0
source

you can make a method inside your cdi bean proxy e.g.

 public String getClassName() { return this.getClass().getName(); } 

this is not the best solution, but a simple pragmatic way to get the class name through a proxy server ... the disadvantage of this is that the method should be in every implementation ...

0
source

Source: https://habr.com/ru/post/1201433/


All Articles