CDV ❯ Sharing java.util.Currency objects breaks equality
-
Bug
-
Status: Closed
-
2 Major
-
Resolution: Fixed
-
-
-
hhuynh
-
Reporter: andersb
-
May 24, 2007
-
0
-
Watchers: 0
-
June 11, 2007
-
June 04, 2007
Description
When I mix java.util.Currency instances that come from the shared environment with those created locally, equals() returns false for identical currencies.
java.util.Currency doesn’t override equals() from java.lang.Object, so it’s using object identities to compare instances.
I believe this instance cache, in Currency, would need to be shared for Currency to work correctly:
private static HashMap instances = new HashMap(7);
Another option would be to modify the behavior of the equals() method on Currency.
Comments
Anders Bengtsson 2007-05-25
Steve Harris 2007-05-31
You did the right stuff. I would have tried making it a root too. We’ll see what we can come up with on this.
Antonio Si 2007-06-04
The problem is that SimpleDateFormat does a Currency.getInstance(), and this is being called way early before a TC Manager is being initialized; thus, a NullManager is being used and when it tries to create a root for the instances static field of Currency, it blows.
Since Currency is not mutatble, it is treated as literal now.
New test case ShareCurrencyTest is added.
We’ve tried to come around it by making java.util.Currency.instances a shared root, but that gets us this problem instead. It causes Terracotta’s own startup to go haywire:
java.lang.ExceptionInInitializerError at java.text.DecimalFormatSymbols.initialize(DecimalFormatSymbols.java:433) at java.text.DecimalFormatSymbols.(DecimalFormatSymbols.java:62)
at java.text.NumberFormat.getInstance(NumberFormat.java:671)
at java.text.NumberFormat.getIntegerInstance(NumberFormat.java:397)
at java.text.SimpleDateFormat.initialize(SimpleDateFormat.java:508)
at java.text.SimpleDateFormat.(SimpleDateFormat.java:446)
at java.text.SimpleDateFormat.(SimpleDateFormat.java:427)
at com.tc.util.ProductInfo.(ProductInfo.java:31)
at com.tc.logging.TCLogging.writeVersion(TCLogging.java:414)
at com.tc.logging.TCLogging.(TCLogging.java:395)
at com.tc.object.bytecode.hook.impl.DSOContextImpl.(DSOContextImpl.java:46)
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:585)
at com.tc.object.bytecode.hook.impl.ClassProcessorHelper.createGlobalContext(ClassProcessorHelper.java:380)
at com.tc.object.bytecode.hook.impl.ClassProcessorHelper.init(ClassProcessorHelper.java:274)
at com.tc.object.bytecode.hook.impl.ClassProcessorHelper.defineClass0Pre(ClassProcessorHelper.java:408)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at javax.management.remote.rmi.NoCallStackClassLoader.findClass(NoCallStackClassLoader.java:108)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at javax.management.remote.rmi.RMIConnector$1.run(RMIConnector.java:1993)
at java.security.AccessController.doPrivileged(Native Method)
at javax.management.remote.rmi.RMIConnector.(RMIConnector.java:2002)
at javax.management.remote.rmi.RMIConnectorServer.objectToBind(RMIConnectorServer.java:738)
at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:394)
at sun.management.jmxremote.ConnectorBootstrap.exportMBeanServer(ConnectorBootstrap.java:517)
at sun.management.jmxremote.ConnectorBootstrap.initialize(ConnectorBootstrap.java:353)
at sun.management.Agent.premain(Agent.java:90)
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:585)
at sun.management.Agent.startAgent(Agent.java:197)
Caused by: java.lang.UnsupportedOperationException
at com.tc.object.bytecode.NullManager.lookupOrCreateRoot(NullManager.java:39)
at com.tc.object.bytecode.ManagerUtil.lookupOrCreateRoot(ManagerUtil.java:82)
at java.util.Currency.\_\_tc\_setinstances(Currency.java)
at java.util.Currency.(Currency.java:50)
... 35 more