1

I am using java reflection in my code and iterating inside a class. On iteration I am getting an invalid class name for a particular object. PFB the code of reflection and the the logs i am getting.

LOGGERS :

2018-12-26 12:38:04,878 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- given class is : class com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- fields are : private javassist.util.proxy.MethodHandler com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e.handler
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- fields are : public static byte[] com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e._filter_signature
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- fields are : public static final long com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e.serialVersionUID
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- fields are : private static java.lang.reflect.Method[] com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e._methods_
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- field is : handler path is : relatedBusinessSolutionMapping
2018-12-26 12:38:04,879 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- field is : _filter_signature path is : relatedBusinessSolutionMapping
2018-12-26 12:38:04,880 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- field is : serialVersionUID path is : relatedBusinessSolutionMapping
2018-12-26 12:38:04,880 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- field is : _methods_ path is : relatedBusinessSolutionMapping
2018-12-26 12:38:04,880 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- field is : solutionType path is : null
2018-12-26 12:38:04,880 INFO  [http-nio-8180-exec-4] [] [] [diy-CJ] []- Path in non-primitive type is : null for field : solutionType

As you can clearly see, the first line of logger prints class name as : com.paytm.oe.entity.RelatedBusinessSolutionMapping_$$_jvst3bb_5e which should instead be :

com.paytm.oe.entity.RelatedBusinessSolutionMapping

Code for reflection :

public static void setNullFieldInAnObject(Object object, Set<String> value, String path) throws Exception {
    LOGGER.info("In merge diff according to the given set function");
    LOGGER.info("Set is : " + value);
    LOGGER.info("Object is : " + object.toString());
    Class classA = object.getClass();
    LOGGER.info("given class is : " + classA.toString());
    Field fields[] = classA.getDeclaredFields();
    for (int i = 0; i < fields.length; i++) {
        LOGGER.info("fields are : " + fields[i].toString());
    }
}

Only in this case it gives a wrong class name which hinders me in iterating inside the class.For all other cases,it's working fine. Please help.

11
  • Could it be that this class is an anonymous class? --- A remark on your code: Field fields[] = classA.getDeclaredFields(); - the C-style of aray declaration is highly discouraged in Java. The array-brackets should be written after the type, not after the variable name: Field[] fields = ...;. Commented Dec 26, 2018 at 7:29
  • @Turing85 nope...this is a private class Please refer logs : 2018-12-26 12:38:04,857 INFO [http-nio-8180-exec-4] [] [] [diy-CJ] []- fields are : private com.paytm.oe.entity.RelatedBusinessSolutionMapping com.paytm.oe.entity.UserBusinessMapping.relatedBusinessSolutionMapping Commented Dec 26, 2018 at 7:31
  • 2
    The JVM doesn't lie. If it tells you that this is the class name of the object, then this is the class name of the object. The object is an instance of a dynamic proxy class generated by javassist. Commented Dec 26, 2018 at 7:34
  • 1
    It is the class name. Because you're using a framework that generates and uses dynamic proxies generated by javassist. Commented Dec 26, 2018 at 7:38
  • 1
    If it wasn't the class name for sure, why would Java tell you that it is the class name? Have you seen somewhere in the javadoc that says "returns the class name, but sometimes with _$$_jvst3bb_5e appended just to annoy you"? It is the class name of the dynamic proxy generated by your framework (Hibernate probably). Just because you don't understand what proxies are and why they're used doesn't change that fact. Commented Dec 26, 2018 at 7:48

3 Answers 3

1

As is pointed out in the comments the class your code is failing on is not because the class name is wrong but because it's a javaassist proxy class. As far as I am aware javaassist only proxies by creating subclasses so if you know the class is a proxy then you simply need to call Class.getSuperclass(). To retrieve the original class, javaassist proxies all implement the javassist Proxy interface so something like this probably does what you want:

Class<?> classA = object.getClass();
if(javassist.util.proxy.Proxy.isAssignableFrom(classA)) {
    classA = classA.getSuperclass();
}
Sign up to request clarification or add additional context in comments.

Comments

0

your object should be a dynamic proxy target which generated by spring(I guess ,cuz there is no relative code).

then you can try this

Class clazz = AopUtils.getTargetClass(proxy);
Arrays.stream(clazz.getDeclaredFields()).forEach(field -> System.out.println(field.getName()));

AopUtils is under org.springframework.aop.support

Comments

0
if (object instanceof HibernateProxy) {
            object = ((HibernateProxy) object).getHibernateLazyInitializer()
                    .getImplementation();
        }

This piece of code worked for me!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.