DWR

MapConverter - handle null keys

Details

  • Type: Improvement Improvement
  • Status: Resolved Resolved
  • Priority: Normal Normal
  • Resolution: Fixed
  • Affects Version/s: 2.0.6
  • Fix Version/s: 3.0.RC2
  • Component/s: Converters
  • Documentation Required:
    No
  • Description:
    Hide
    Null keys are legal in Java for some map implementations, although in JavaScript they are not.

    It seems that when null keys are used, the logging line @ line 191 of the MapConverter creates a NullPointerException due to calling key.getClass().getName()

    It would be better if the null key values were replaced with some kind of place holder - eg "null" or similar to ensure that data is not lost in conversation.

    Please see this thread for more info: https://dwr.dev.java.net/servlets/ReadMsg?list=users&msgNo=19611

    Thanks,

    Will
    Show
    Null keys are legal in Java for some map implementations, although in JavaScript they are not. It seems that when null keys are used, the logging line @ line 191 of the MapConverter creates a NullPointerException due to calling key.getClass().getName() It would be better if the null key values were replaced with some kind of place holder - eg "null" or similar to ensure that data is not lost in conversation. Please see this thread for more info: https://dwr.dev.java.net/servlets/ReadMsg?list=users&msgNo=19611 Thanks, Will

Activity

Hide
David Marginian added a comment - 23/Jul/10 4:59 AM

Mike any comments here?

Show
David Marginian added a comment - 23/Jul/10 4:59 AM Mike any comments here?
Hide
Mike Wilson added a comment - 08/Aug/10 4:11 AM

Yes, this is a tricky choice. Whatever placeholder we choose will risk conflicting with a "real" key with the same name as JS map keys are strings, ie using "null" as placeholder will conflict with a real "null" key.
It might be more intuitive to replace null keys with an empty string ("") but they will of course also be subject to conflicts.

I could live with either:

  • blocking these items completely and issue a MarshallException
    or something like:
  • replace null keys with empty string and issue a warning in the log
  • let docs say that maps with both null keys and empty string keys will conflict and be subject to "last item wins"

WDYT?

Show
Mike Wilson added a comment - 08/Aug/10 4:11 AM Yes, this is a tricky choice. Whatever placeholder we choose will risk conflicting with a "real" key with the same name as JS map keys are strings, ie using "null" as placeholder will conflict with a real "null" key. It might be more intuitive to replace null keys with an empty string ("") but they will of course also be subject to conflicts. I could live with either:
  • blocking these items completely and issue a MarshallException or something like:
  • replace null keys with empty string and issue a warning in the log
  • let docs say that maps with both null keys and empty string keys will conflict and be subject to "last item wins"
WDYT?
Hide
David Marginian added a comment - 08/Aug/10 6:58 AM

I think we can handle this. We can check the Java map for a "null" key - if it doesn't exist we are safe to use that as the JS key. If it does we can attempt to use "" key, if it does not exist. If both already exist we can issue a warning or error in the log.

Show
David Marginian added a comment - 08/Aug/10 6:58 AM I think we can handle this. We can check the Java map for a "null" key - if it doesn't exist we are safe to use that as the JS key. If it does we can attempt to use "" key, if it does not exist. If both already exist we can issue a warning or error in the log.
Hide
Mike Wilson added a comment - 26/Aug/10 5:46 PM

Thinking a bit more on this I think the only sane thing is to do the following:

By default keep the behaviour we have now, ie not forward null keys at all, and issue a warning.

Then offer a parameter on the MapConverter which controls null key replacement, so the map behaviour can be overridden from the application's dwr.xml, and the application can choose what string to use (which is a delicate matter).
If there is both a null key and a key corresponding to the null key replacement, then we guarantee that the null key is dropped and we issue a warning just like for the default behaviour.

Show
Mike Wilson added a comment - 26/Aug/10 5:46 PM Thinking a bit more on this I think the only sane thing is to do the following: By default keep the behaviour we have now, ie not forward null keys at all, and issue a warning. Then offer a parameter on the MapConverter which controls null key replacement, so the map behaviour can be overridden from the application's dwr.xml, and the application can choose what string to use (which is a delicate matter). If there is both a null key and a key corresponding to the null key replacement, then we guarantee that the null key is dropped and we issue a warning just like for the default behaviour.
Hide
Mike Wilson added a comment - 27/Aug/10 2:12 AM

A nice mapping for null replacement is to map it against a JS key string containing one Unicode null character (\u0000). It looks nice when you want to set it yourself in JavaScript:

mymap["\u0000"] = ...

or shorter:

mymap["\0"] = ...

and the key also displays nicely in Firebug (a square with four zeros like a real null code).

I'm still undecided on whether this key is used rarely enough by user code to offer conversion as default behaviour, or if we should make it an explicit config in dwr.xml. Thoughts?

Show
Mike Wilson added a comment - 27/Aug/10 2:12 AM A nice mapping for null replacement is to map it against a JS key string containing one Unicode null character (\u0000). It looks nice when you want to set it yourself in JavaScript: mymap["\u0000"] = ... or shorter: mymap["\0"] = ... and the key also displays nicely in Firebug (a square with four zeros like a real null code). I'm still undecided on whether this key is used rarely enough by user code to offer conversion as default behaviour, or if we should make it an explicit config in dwr.xml. Thoughts?
Hide
David Marginian added a comment - 27/Aug/10 9:46 PM

I like the dwr.xml config option the best. Where were you thinking we would put this option, at the individual converter level (allow) or do you want to force the user to redefine the map converter in the init section of dwr.xml?

Show
David Marginian added a comment - 27/Aug/10 9:46 PM I like the dwr.xml config option the best. Where were you thinking we would put this option, at the individual converter level (allow) or do you want to force the user to redefine the map converter in the init section of dwr.xml?
Hide
David Marginian added a comment - 28/Aug/10 3:38 PM

Disregard my previous post - not sure what I was thinking.

I am checking in a fix for this. I have also checked in a test case to the testdwr.war that covers the change (marshall test number 50 - null key hashmap.

The code change is minor:
// If the key is null, retrieve the configured null key value from the configuration of this converter.
if (null == key && null != nullKey) { log.debug("MapConverter: A null key was encountered DWR is using the configured nullKey string: " + nullKey); key = nullKey; }

Then override the map converter in the allow:

<convert converter="map" match="java.util.Map">
<param name="nullKey" value="null"/>
</convert>

Mike if you can review this and let me know I will resolve the issue.

Also, I am not going to backport this to 2.x since we will be releasing 3 soon.

Show
David Marginian added a comment - 28/Aug/10 3:38 PM Disregard my previous post - not sure what I was thinking. I am checking in a fix for this. I have also checked in a test case to the testdwr.war that covers the change (marshall test number 50 - null key hashmap. The code change is minor: // If the key is null, retrieve the configured null key value from the configuration of this converter. if (null == key && null != nullKey) { log.debug("MapConverter: A null key was encountered DWR is using the configured nullKey string: " + nullKey); key = nullKey; } Then override the map converter in the allow: <convert converter="map" match="java.util.Map"> <param name="nullKey" value="null"/> </convert> Mike if you can review this and let me know I will resolve the issue. Also, I am not going to backport this to 2.x since we will be releasing 3 soon.
Hide
David Marginian added a comment - 28/Aug/10 3:39 PM

Need to update the map conversion docs.

Show
David Marginian added a comment - 28/Aug/10 3:39 PM Need to update the map conversion docs.
Hide
Mike Wilson added a comment - 28/Aug/10 4:17 PM

It probably doesn't make a big difference for the user as the map converter is usually "allowed" only once, on the java.util.Map interface. So it's one clause in dwr.xml either way. Do you have any preference, looking at how other converters use parameters?

Show
Mike Wilson added a comment - 28/Aug/10 4:17 PM It probably doesn't make a big difference for the user as the map converter is usually "allowed" only once, on the java.util.Map interface. So it's one clause in dwr.xml either way. Do you have any preference, looking at how other converters use parameters?

People

Dates

  • Created:
    23/Jul/10 3:06 AM
    Updated:
    09/Nov/10 7:53 PM
    Resolved:
    29/Aug/10 2:50 PM