[JIRA] Created: (HUDSON-5776) CopyOnWriteMap.Tree cannot be serialized if it is empty

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[JIRA] Created: (HUDSON-5776) CopyOnWriteMap.Tree cannot be serialized if it is empty

Hudson issues mailing list
CopyOnWriteMap.Tree cannot be serialized if it is empty
-------------------------------------------------------

                 Key: HUDSON-5776
                 URL: http://issues.hudson-ci.org/browse/HUDSON-5776
             Project: Hudson
          Issue Type: Bug
          Components: core
            Reporter: mdillon
            Priority: Minor
         Attachments: CopyOnWriteMap.diff

Under some circumstances, the "core" field of a hudson.util.CopyOnWriteMap.Tree instance can be an instance of java.util.Collections.EmptyMap, which is not a subclass of TreeMap. When this happens, the following error is seen during serialization:

{noformat}
2010-02-25 00:43:09,238 ERROR [hudson.model.Executor] Executor throw an exception unexpectedly
java.lang.RuntimeException: Failed to serialize com.example.MyBuild#detailsMap for class com.example.MyBuild
        at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:160)
        at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:131)
        at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:130)
        at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:116)
        at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:89)
        at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
        at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
        at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
        at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
        at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
        at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
        at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)
        at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)
        at hudson.XmlFile.write(XmlFile.java:161)
        at hudson.model.Run.save(Run.java:1235)
        at hudson.model.Run.run(Run.java:1162)
        at hudson.model.Build.run(Build.java:74)
        at hudson.model.ResourceController.execute(ResourceController.java:93)
        at hudson.model.Executor.run(Executor.java:122)
Caused by: java.lang.ClassCastException: java.util.Collections$EmptyMap cannot be cast to java.util.TreeMap
        at com.thoughtworks.xstream.converters.collections.TreeMapConverter.marshal(TreeMapConverter.java:50)
        at hudson.util.CopyOnWriteMap$Tree$ConverterImpl.marshal(CopyOnWriteMap.java:221)
        at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
        at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
        at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
        at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:168)
        at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:156)
        ... 18 more
{noformat}

It looks like this can happen either when the Tree() or Tree(Comparator) constructors are called or when clear() is called. In those cases, if you don't add any elements, you'll get the wrong kind of map in the core and serialization will fail. The one case that should work is if you do putAll() with an empty Map after creation; that will successfully replace the core with a TreeMap.

I've attached a proposed patch. It adds an emptyMap() method to CopyOnWriteMap that is implemented by the two subclasses. All calls that previously went to Collections.emptyMap() now let the subclass decide what type of map to return. It also adds a test for serializing an empty CopyOnWriteMap.Tree. This patch takes the naive approach of creating a new TreeMap every time that emptyMap() is called. It may or not be worthwhile to try to reuse a TreeMap instance for this purpose since CopyOnWriteMap guarantees that the core itself won't be updated.

--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.hudson-ci.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[JIRA] Assigned: (HUDSON-5776) CopyOnWriteMap.Tree cannot be serialized if it is empty

Hudson issues mailing list

     [ http://issues.hudson-ci.org/browse/HUDSON-5776?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

mindless reassigned HUDSON-5776:
--------------------------------

    Assignee: mindless

> CopyOnWriteMap.Tree cannot be serialized if it is empty
> -------------------------------------------------------
>
>                 Key: HUDSON-5776
>                 URL: http://issues.hudson-ci.org/browse/HUDSON-5776
>             Project: Hudson
>          Issue Type: Bug
>          Components: core
>            Reporter: mdillon
>            Assignee: mindless
>            Priority: Minor
>         Attachments: CopyOnWriteMap.diff
>
>
> Under some circumstances, the "core" field of a hudson.util.CopyOnWriteMap.Tree instance can be an instance of java.util.Collections.EmptyMap, which is not a subclass of TreeMap. When this happens, the following error is seen during serialization:
> {noformat}
> 2010-02-25 00:43:09,238 ERROR [hudson.model.Executor] Executor throw an exception unexpectedly
> java.lang.RuntimeException: Failed to serialize com.example.MyBuild#detailsMap for class com.example.MyBuild
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:160)
>         at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:131)
>         at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:130)
>         at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:116)
>         at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:89)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)
>         at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)
>         at hudson.XmlFile.write(XmlFile.java:161)
>         at hudson.model.Run.save(Run.java:1235)
>         at hudson.model.Run.run(Run.java:1162)
>         at hudson.model.Build.run(Build.java:74)
>         at hudson.model.ResourceController.execute(ResourceController.java:93)
>         at hudson.model.Executor.run(Executor.java:122)
> Caused by: java.lang.ClassCastException: java.util.Collections$EmptyMap cannot be cast to java.util.TreeMap
>         at com.thoughtworks.xstream.converters.collections.TreeMapConverter.marshal(TreeMapConverter.java:50)
>         at hudson.util.CopyOnWriteMap$Tree$ConverterImpl.marshal(CopyOnWriteMap.java:221)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:168)
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:156)
>         ... 18 more
> {noformat}
> It looks like this can happen either when the Tree() or Tree(Comparator) constructors are called or when clear() is called. In those cases, if you don't add any elements, you'll get the wrong kind of map in the core and serialization will fail. The one case that should work is if you do putAll() with an empty Map after creation; that will successfully replace the core with a TreeMap.
> I've attached a proposed patch. It adds an emptyMap() method to CopyOnWriteMap that is implemented by the two subclasses. All calls that previously went to Collections.emptyMap() now let the subclass decide what type of map to return. It also adds a test for serializing an empty CopyOnWriteMap.Tree. This patch takes the naive approach of creating a new TreeMap every time that emptyMap() is called. It may or not be worthwhile to try to reuse a TreeMap instance for this purpose since CopyOnWriteMap guarantees that the core itself won't be updated.

--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.hudson-ci.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[JIRA] Resolved: (HUDSON-5776) CopyOnWriteMap.Tree cannot be serialized if it is empty

Hudson issues mailing list
In reply to this post by Hudson issues mailing list

     [ http://issues.hudson-ci.org/browse/HUDSON-5776?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

scm_issue_link resolved HUDSON-5776.
------------------------------------

    Resolution: Fixed

> CopyOnWriteMap.Tree cannot be serialized if it is empty
> -------------------------------------------------------
>
>                 Key: HUDSON-5776
>                 URL: http://issues.hudson-ci.org/browse/HUDSON-5776
>             Project: Hudson
>          Issue Type: Bug
>          Components: core
>            Reporter: mdillon
>            Assignee: mindless
>            Priority: Minor
>         Attachments: CopyOnWriteMap.diff
>
>
> Under some circumstances, the "core" field of a hudson.util.CopyOnWriteMap.Tree instance can be an instance of java.util.Collections.EmptyMap, which is not a subclass of TreeMap. When this happens, the following error is seen during serialization:
> {noformat}
> 2010-02-25 00:43:09,238 ERROR [hudson.model.Executor] Executor throw an exception unexpectedly
> java.lang.RuntimeException: Failed to serialize com.example.MyBuild#detailsMap for class com.example.MyBuild
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:160)
>         at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:131)
>         at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:130)
>         at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:116)
>         at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:89)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)
>         at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)
>         at hudson.XmlFile.write(XmlFile.java:161)
>         at hudson.model.Run.save(Run.java:1235)
>         at hudson.model.Run.run(Run.java:1162)
>         at hudson.model.Build.run(Build.java:74)
>         at hudson.model.ResourceController.execute(ResourceController.java:93)
>         at hudson.model.Executor.run(Executor.java:122)
> Caused by: java.lang.ClassCastException: java.util.Collections$EmptyMap cannot be cast to java.util.TreeMap
>         at com.thoughtworks.xstream.converters.collections.TreeMapConverter.marshal(TreeMapConverter.java:50)
>         at hudson.util.CopyOnWriteMap$Tree$ConverterImpl.marshal(CopyOnWriteMap.java:221)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:168)
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:156)
>         ... 18 more
> {noformat}
> It looks like this can happen either when the Tree() or Tree(Comparator) constructors are called or when clear() is called. In those cases, if you don't add any elements, you'll get the wrong kind of map in the core and serialization will fail. The one case that should work is if you do putAll() with an empty Map after creation; that will successfully replace the core with a TreeMap.
> I've attached a proposed patch. It adds an emptyMap() method to CopyOnWriteMap that is implemented by the two subclasses. All calls that previously went to Collections.emptyMap() now let the subclass decide what type of map to return. It also adds a test for serializing an empty CopyOnWriteMap.Tree. This patch takes the naive approach of creating a new TreeMap every time that emptyMap() is called. It may or not be worthwhile to try to reuse a TreeMap instance for this purpose since CopyOnWriteMap guarantees that the core itself won't be updated.

--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.hudson-ci.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[JIRA] Commented: (HUDSON-5776) CopyOnWriteMap.Tree cannot be serialized if it is empty

Hudson issues mailing list
In reply to this post by Hudson issues mailing list

    [ http://issues.hudson-ci.org/browse/HUDSON-5776?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=136332#action_136332 ]

scm_issue_link commented on HUDSON-5776:
----------------------------------------

Code changed in hudson
User: : mindless
Path:
 trunk/hudson/main/core/src/main/java/hudson/util/CopyOnWriteMap.java
 trunk/hudson/main/core/src/test/java/hudson/util/CopyOnWriteListTest.java
 trunk/hudson/main/core/src/test/java/hudson/util/CopyOnWriteMapTest.java
 trunk/www/changelog.html
http://hudson-ci.org/commit/28026
Log:
[FIXED HUDSON-5776] fix serialization problem with empty CopyOnWriteMap.Tree,
also add/update tests for CopyOnWriteMap and CopyOnWriteList.


> CopyOnWriteMap.Tree cannot be serialized if it is empty
> -------------------------------------------------------
>
>                 Key: HUDSON-5776
>                 URL: http://issues.hudson-ci.org/browse/HUDSON-5776
>             Project: Hudson
>          Issue Type: Bug
>          Components: core
>            Reporter: mdillon
>            Assignee: mindless
>            Priority: Minor
>         Attachments: CopyOnWriteMap.diff
>
>
> Under some circumstances, the "core" field of a hudson.util.CopyOnWriteMap.Tree instance can be an instance of java.util.Collections.EmptyMap, which is not a subclass of TreeMap. When this happens, the following error is seen during serialization:
> {noformat}
> 2010-02-25 00:43:09,238 ERROR [hudson.model.Executor] Executor throw an exception unexpectedly
> java.lang.RuntimeException: Failed to serialize com.example.MyBuild#detailsMap for class com.example.MyBuild
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:160)
>         at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:131)
>         at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:130)
>         at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:116)
>         at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:89)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
>         at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:837)
>         at com.thoughtworks.xstream.XStream.marshal(XStream.java:826)
>         at com.thoughtworks.xstream.XStream.toXML(XStream.java:801)
>         at hudson.XmlFile.write(XmlFile.java:161)
>         at hudson.model.Run.save(Run.java:1235)
>         at hudson.model.Run.run(Run.java:1162)
>         at hudson.model.Build.run(Build.java:74)
>         at hudson.model.ResourceController.execute(ResourceController.java:93)
>         at hudson.model.Executor.run(Executor.java:122)
> Caused by: java.lang.ClassCastException: java.util.Collections$EmptyMap cannot be cast to java.util.TreeMap
>         at com.thoughtworks.xstream.converters.collections.TreeMapConverter.marshal(TreeMapConverter.java:50)
>         at hudson.util.CopyOnWriteMap$Tree$ConverterImpl.marshal(CopyOnWriteMap.java:221)
>         at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
>         at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
>         at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:168)
>         at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:156)
>         ... 18 more
> {noformat}
> It looks like this can happen either when the Tree() or Tree(Comparator) constructors are called or when clear() is called. In those cases, if you don't add any elements, you'll get the wrong kind of map in the core and serialization will fail. The one case that should work is if you do putAll() with an empty Map after creation; that will successfully replace the core with a TreeMap.
> I've attached a proposed patch. It adds an emptyMap() method to CopyOnWriteMap that is implemented by the two subclasses. All calls that previously went to Collections.emptyMap() now let the subclass decide what type of map to return. It also adds a test for serializing an empty CopyOnWriteMap.Tree. This patch takes the naive approach of creating a new TreeMap every time that emptyMap() is called. It may or not be worthwhile to try to reuse a TreeMap instance for this purpose since CopyOnWriteMap guarantees that the core itself won't be updated.

--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.hudson-ci.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]