United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4684279 Collections.EMPTY_* can be duplicated in system with serialization
JDK-4684279 : Collections.EMPTY_* can be duplicated in system with serialization

Details
Type:
Enhancement
Submit Date:
2002-05-13
Status:
Closed
Updated Date:
2002-11-27
Project Name:
JDK
Resolved Date:
2002-11-20
Component:
core-libs
OS:
windows_2000
Sub-Component:
java.util
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.4.0
Fixed Versions:
1.4.2 (mantis)

Related Reports

Sub Tasks

Description

Name: nt126004			Date: 05/13/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
When I serialize Collections.EMPTY_LIST and then deserialize
it, I get a different object.  The two objects are equal via
the equals method, however == doesn't consider them equal.
Since the EMPTY_* variables are defined constants I would
think that deserializing the objects would return the exact
same reference.  This can be accomplised by overriding the
readResolve method in the Empty* class implementations.
Then checking for equality would be quicker.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package foo.bugs.jdk;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;


public class SerializeEmptyCollections {
  
  static public void main(final String[] args) {
    try {
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(Collections.EMPTY_LIST);
    oos.writeObject(Collections.EMPTY_SET);
    oos.writeObject(Collections.EMPTY_MAP);
    oos.close();

    final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    final ObjectInputStream ois = new ObjectInputStream(bais);
    final List emptyList = (List)ois.readObject();
    final Set emptySet = (Set)ois.readObject();
    final Map emptyMap = (Map)ois.readObject();
    ois.close();

    System.out.println("empty list == " + (Collections.EMPTY_LIST == emptyList));
    System.out.println("empty list equals " +
(Collections.EMPTY_LIST.equals(emptyList)));

    System.out.println("empty set == " + (Collections.EMPTY_SET == emptySet));
    System.out.println("empty set equals " +
(Collections.EMPTY_SET.equals(emptySet)));

    System.out.println("empty map == " + (Collections.EMPTY_MAP == emptyMap));
    System.out.println("empty map equals " +
(Collections.EMPTY_MAP.equals(emptyMap)));

    } catch(final IOException ioe) {
      ioe.printStackTrace();
    } catch(final ClassNotFoundException cnfe) {
      cnfe.printStackTrace();
    }
  }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Use equals to compare these lists, rather than ==.
(Review ID: 146455) 
======================================================================

                                    

Comments
EVALUATION

   In the absence of a specific notation in the spec, it would be reckless to write code that depends on the identity of a deserialized value.  That said, this is a reasonable request from a performance and cleanliness perspective.

###@###.### 2002-05-13
                                     
2002-05-13
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mantis

FIXED IN:
mantis

INTEGRATED IN:
mantis
mantis-b08

VERIFIED IN:
mantis-beta


                                     
2004-06-14



Hardware and Software, Engineered to Work Together