Question

Yes, I know there are plenty of articles on the topic, but it's not that simple.

I've got a wrapper class which is used for generically passing arguments to methods and subsequently retrieving values. This wrapper class (called IDVariant) has a default type which indicates the principal type of variable stored.

Hence, I can have:

IDVariant v = new IDVariant(1);
boolean b = v.booleanValue();
String s = v.stringValue();
int i = v.integerValue();

and so on, but the default type would be int, as per the type of the parameter used to create the instance.

Now, this class, as mentioned, is used as a general placeholder in much bigger and more complex classes. I need to create a tool which parses a super-structure of classes recursively and recreate this structure in XML. Obviously, the way to go is Reflection, and I have been successful so far in recreating the structure of the whole thing. The only problem is, I have not come up with a way to find out the default type of the IDVariant, and thus having the correct type for each variable of the XML tree.

What I have tried doing is retrieving the get method for each property of each class, then invoking it and checking the default type of each IDVariant. It seemed like a good idea, but it's not working: I am getting an InvocationTargetException which, I presume, is due to the fact that the instance of the class I create in order to call the method, is in fact not populated with data. It's the only logical explanation I have been able to give.

If anyone has any idea, I would be most appreciative! :)

Following is a sample code fragment:

// Edit of the code, as correctly indicated by cyon. Tha variable className is given.
Class<?> toParse = Class.forName(className);
Object o = toParse.newInstance();   // There is a default constructor with no values, the object is not null

Class cl = ... // given class
Class[] noparams = {};

String s = "getSomeValue";
Method method = null;
for(Method m : cl.getMethods()) {
    if (m.getName().equals(s)) {
        method = m;
        break;
    }
}

if (method != null) {
    try {
        Object idv = method.invoke(o, noparams);  // exception occurs at this point
        String type = decodeType((IDVariant)idv); // function which maps internal codes of IDVariant default type to primitive and internal types
        return type;
    } catch (InvocationTargetException ex) {
        System.out.println(ex.getCause());
    }
}

NOTE: The function returns indeed a variable of type IDVariant, I have checked the source code out. I cannot change that code, however, as it is coming from an external tool which generates it automatically.

Thank you in advance :)

EDIT: Okay, so I've had a better look at the source produced by the external tool, and this is what I gather:

I am invoking a sample method, say getSomeValue. In the source of the class where the method is declared, here is the declaration of the method:

public IDVariant getSomeValue() { return GetPropDirect(externalValue); }

So, perhaps it's internally trying to invoke another method which belongs to a superclass, and I do not instantiate the superclass. Is it possible that this is the issue? And if yes, is there a workaround?

EDIT 2: As requested, here is the Stack Trace for the exception I am getting:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at prove.Reflector.getImplicitType(Reflector.java:275)
    at prove.Reflector.recurr(Reflector.java:134)
    at prove.Reflector.ParseToXml(Reflector.java:69)
    at prove.Main.main(Main.java:12)
Caused by: java.lang.NullPointerException
    at com.progamma.doc.IDDocument.GetPropDirect(IDDocument.java:739)
    at it.zerounoesse.Calcolo7302013.Contribuente.getSomeValue(Contribuente.java:70)
... 8 more
Était-ce utile?

La solution

Your IDVariant class is of course instantiated, thats what you do with toParse.newInstance() method, but since you do not cast the instantiated object to its original class type and then initialize it, there is a big probability of exception, for example NullPointerEx.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top