• Documentation
  • Status: Closed
  • 2 Major
  • Resolution: Fixed
  • Documentation
  • kkannaiy
  • Reporter: amiller
  • April 03, 2009
  • 0
  • Watchers: 1
  • February 12, 2013
  • May 14, 2009

Description

The original tests for AtomicReference use string literals (like “nugent”) for testing the CAS operations. Internally, AtomicReference relies on comparing those string literals for reference equality (==). In a single JVM, that is guaranteed for string literals due to interning. But in Terracotta, it is not.

This is a gotcha in AtomicReference, but also possibly more widely as well. You should not (necessarily) expect “abc” == “abc” to be true if the source of those strings are different JVMs.

Tim points out that this extends to other tc literal types as well.

Maybe something for the gotchas page?

Comments

Taylor Gautier 2009-04-04

Isn’t it always bad practice to compare == for Strings? Unless I am mistaken this is not a guarantee that the JLS gives you and while it works some or most of the time it’s certainly not good practice in my understanding.

What does Effective Java have to say about it?

Alex Miller 2009-04-06

Sure, it’s bad practice. But if you know what you’re doing and you are relying on the expectation (in normal Java) that string literal are interned, then it is a gotcha that the same app with Terracotta will not work. We do handle the explicit intern() case (assuming you instrument the class) so that’s a useful workaround to mention.

In the specific AtomicReference case, the tricky thing is that relying on reference equality is how AtomicReference and CAS work internally (it doesn’t make sense to talk about equals() in that context). However, I think it would be somewhat unusual to use an AtomicReference to store a String but if you did, it might be surprising that it didn’t work. Again, intern() ing the string before using it in the AtomicReference would be a workaround.

Alex Miller 2009-04-06

Oh, and regarding JLS, section 3.10.5 (http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5) says:

“Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are “interned” so as to share unique instances, using the method String.intern.”

So interning is guaranteed by the JLS for “strings that are the values of constant expressions” like: “foo”

Tim Eck 2009-04-06

I think it should be listed as a gotcha since we do get it “right” for some intern()’d Strings (those for which there is an explicit intern() call in an instrumented class). The inconsistency is warrant enough for me to list this as a gotcha

ilevy 2009-05-08

here’s a draft of what i wrote up so far:

String Equality in Distributed Applications

Summary In applications distributed with Terracotta, reference equality for string literals may not behave as expected. In applications that are not distributed, the following is expected to be true since all existing String literals are interned at compile time:

"abc" == "abc"

However, when the application is distributed with Terracotta, the statement above could be false because the references being compared may have been generated on different JVMs.

Example If an application passes string literals to AtomicReference, which uses the == operator internally to find reference equality, errors could occur because references that are expected to match may not.

{note} This type of error could occur with other types of literals, as well. {note}

Solution: Intern String literals to store a single canonical value Terracotta recognizes and works with interned strings. Since all references to an interned String object point to the canonical value, reference equality checks will work as expected even for distributed applications.

For related issues and information, see: * Uninstrumented Access * Literals (Concept and Architecture Guide)

ilevy 2009-05-08

please have engineering review this and then reassign to me.

Fiona OShea 2009-05-08

Alex can you or someone on your team verify that the text is correct? thanks Fiona

Chris Dennis 2009-05-11

Strictly speaking we don’t check for an interned String, we check for a call of the intern method. This is why compile time constant Strings which are interned automatically are not detected as such by the L1 when sharing them, and so are therefore we don’t intern them on the faulting L1. I believe if we did detect whether the string weas actually interned then this loophole would not exist (or would at least be smaller).

I’d propose something like (with better English):

Solution: Explicitly intern String literals to store a single canonical value Terracotta recognizes and works with explicitly interned strings (instances on which String.intern() has been called). Since all explicitly interned Strings are automatically interned on each L1 during object faulting, reference equality checks will work as expected even for distributed applications.

Alex Miller 2009-05-11

In the Example, I think I would say: “If an application manages a string literal with an AtomicReference, which uses the == operator internally to find reference equality, errors could occur because references that are expected to match may not. “

In the Solution, I think it’s important to distinguish between an automatically interned string defined as a constant “abc” from one in which the intern() method has been called. The workaround is basically to replace the former with the latter. Something like:

“Terracotta tracks calls to String.intern() and guarantees reference equality for those Strings. Since all references to an interned String object point to the canonical value, reference equality checks will work as expected even for distributed applications.”

ilevy 2009-05-14

“String Equality in Distributed Applications” is the name of the gotcha in http://www.terracotta.org/web/display/docs/Gotchas (will be published by 5/16/09).

Kalai Kannaiyan 2009-05-18

Verified the text in the Gotchas doc under “String Equality in Distributed Applications”

http://www.terracotta.org/web/display/docs/Gotchas#Gotchas-StringEqualityinDistributedApplications.