Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Fill bean data from HashMap using Reflection

 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

I was trying on a small example on Reflection by which i had to fill the values in a bean from a HashMap.
This is the code as it goes: -

TempBean.java


ReflectUtil.java


ReflectionTester.java


But on executing ReflectionTester with the arguments, A NullPointerException is getting thrown.
Please suggest where am i going wrong here.

Thanks in advance.
Sree
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If pDescriptors[i].getName().equals("class") you will get a "gap" in your descriptors array; the value will remain null at that point. You will later encounter this null value, and when you try to get its name the exception is thrown. Change descriptors from a PropertyDescriptor[] to a List<PropertyDescriptor> to make sure you won't get any null references in it. Note that you'll need to replace descriptors[i] = pDescriptors[i] with descriptors.add(pDescriptors[i]), descriptors.length with descriptors.size() and descriptors[k] with descriptors.get(k).

That leaves another odd issue. You loop over the number of values given, which can definitely be different from the number of properties. Change the for loop:
The final question: what will you do if a property has no entry in the map?


Oh, and your ReflectionUtil class is superfluous. All it does is forward the call to its arguments. ReflectionUtil.getReadMethod(descriptors[k]) is the same as descriptors[k].getReadMethod(), and ReflectionUtil.invokeMethod(method, tempBean2, value) is the same as method.invoke(tempBean2, value). You won't even need to catch the NoSuchMethodException anymore.
 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are a couple of things weird about your code:




You're not using generics. And probably your problem is that you are iterating over the HashMap size and not over the
descriptors size. And why do you copy all the values into a new array except for the class entries? Why not just skip them?

 
Campbell Ritchie
Sheriff
Pie
Posts: 50248
79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Reflection is hardly a "beginning" topic. Moving thread.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi again,

Thanks for all your comments.

@Rob Prime-
I followed your suggestions, made the changes in the method. and it gave me what i wanted, Thanks friend

ReflectionTester.java


@Wouter Oet
I will make sure i remove the unnecessary code as you said.
Appreciate your help.

The code after undergoing the changes as Rob had suggested, is working without an error.

>
 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could improve your code by merging the two for-loops into one.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wouter Oet wrote:There are a couple of things weird about your code:




You're not using generics. And probably your problem is that you are iterating over the HashMap size and not over the
descriptors size. And why do you copy all the values into a new array except for the class entries? Why not just skip them?



Hi,

I think i have removed unnecessary code as suggested earlier.
But I again ran into another problem similiar like this..
These are the classes : -

FormUtil


BaseForm


LoginForm


BeanUtil


Here i am trying the a similiar example to set values from hashmap to the class,
but i am getting a error(IllegalArgugmentException) while invoking the method,
Please suggest what can be the reason and what to do to correct this...

Thanks in advance.

Regards,
Sree
 
Paul Clapham
Sheriff
Posts: 21416
33
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason? When you called the invoke() method, an error was thrown. Perhaps by the method you were invoking? You don't know because you didn't...

What can be done about it?
Look at the stack trace to see what the error was. Not only will there be a stack trace for the InvocationTargetException, there will also be a stack trace for the actual exception which was thrown by the invoked method.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:The reason? When you called the invoke() method, an error was thrown. Perhaps by the method you were invoking? You don't know because you didn't...

What can be done about it?
Look at the stack trace to see what the error was. Not only will there be a stack trace for the InvocationTargetException, there will also be a stack trace for the actual exception which was thrown by the invoked method.


Hi Paul,

Thanks for replying,
I had written InvocationTargetException for IllegalArgumentException by mistake,
the stacktrace shown is follows:-

java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.utils.BeanUtil.setFromMap(BeanUtil.java:56)
at net.utils.FormUtil.parseRequest(FormUtil.java:44)


I still cant make out what made it to throw this exception.
Please forgive my typeing-mistake and suggest what should be done to correct this.

Regards,
Sree
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your first argument is a Class object, but it needs to be an instance of the class represented by the Class object. For example, if clazz == String.class you would need to pass a String.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:
Your first argument is a Class object, but it needs to be an instance of the class represented by the Class object. For example, if clazz == String.class you would need to pass a String.


Hi Rob,

I did the change


Please suggest if this ok as this working right as i needed.

Regards,
Sree
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It depends. If it's ok to call the method on a new instance that isn't referred to from anywhere else, then that code should work. If you need to call the method on an existing instance then you'll need to pass that instance to the method. Something tells me that's the case.

I'd change your method signature slightly:
You will now be setting the values to an existing object.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:It depends. If it's ok to call the method on a new instance that isn't referred to from anywhere else, then that code should work. If you need to call the method on an existing instance then you'll need to pass that instance to the method. Something tells me that's the case.

I'd change your method signature slightly:
You will now be setting the values to an existing object.


I did the changes as you said,
if i pass the argument as object i get the class after getClass() as of type <java.lang.Class>
and not of the type <net.forms.LoginForm>, and i plan to set this instance in request attribute

I get a hint that i will have to use java Generics here, but am not much aquainted with it.

Please guide about what can be done to make method work right.

Sree
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You no longer should pass the Class object as your first argument but an instance of that class - the instance whose fields you want to set.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:You no longer should pass the Class object as your first argument but an instance of that class - the instance whose fields you want to set.


Could you elaborate with a code sample please.

Sree
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:


Hi ,

I tried to improve the code a bit more,
Even though i have a general idea how the
code should work, I am havent yet appplied
this method successfully.
I think using Java Generics will work here,
so i started with these changes, but couldn't
go any further.

BeanUtil


I plan to send the object to the method,
set the values and return the same object
back, where (object extends BaseForm)

I am missing the core concept of Java Generics here,
but want to clear them too.

Please guide me.

Thanks in advance,
Sree">
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?

quote=Rob Prime]Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?
Hi Rob,
Sorry for replying late.
I followed your suggestion and used it Java Generics
and was able to find the required solution.

Thanks,
Regards,
Sree">
 
Rob Spoor
Sheriff
Pie
Posts: 20667
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see two possible improvements:
- use Map<String,String> instead of HashMap<String,String> in the method signature to allow TreeMap as well.
- check if the method's parameter list expects only one String or Object:
This will prevent issues where the property is not a String property but for instance an Integer.
 
Ravi Sree
Ranch Hand
Posts: 64
Java MySQL Database PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:I see two possible improvements:
- use Map<String,String> instead of HashMap<String,String> in the method signature to allow TreeMap as well.
- check if the method's parameter list expects only one String or Object:
This will prevent issues where the property is not a String property but for instance an Integer.


Hi Rob,

Sorry to reply so late,

I have the made changes to my code as you suggested.

Thanks ,
Sree
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic