weird variable loss of scope(??) in java

we’ve run into an odd situation today with a piece of code.

below is the method (some irrelevant detail changed for readability)

if (this.isValid(newStatus,this.getHeader())){
String currentStatus = this.getStatusCode();

if(!currentStatus.equals(newStatus)){
if(currentStatus.equals(BPConstants.CONST)) {
this.setStatusCode(newStatus);
DBUtil.updateBusinessObject(this);
}
}
} else {
throw new BMException ("invalid state from" + this.getStatusCode() + " to " + newStatus);
}

the most bizarre thing, while stepping through the debugger, however, is that with the code formatted as such, and the code doesn’t not get executed (it should never go into the condition since it is false), it jumps directly to the

DBUtil.updateBusinessObject

statement, within the condition!

only, after moving the declaration of currentStatus *outside* of the if, did the code behave properly! i realized that apparently, “currentStatus” somehow got weirdly in some twilight zone between being in scope and out of scope, so that

!currentStatus.equals(newStatus)

wasn’t getting evaluated properly…but wait, in the debugger, this piece of code *is* getting evaluated properly, and

currentStatus.equals(BPConstants.CONST)

never gives an NPE, although my debugger now tells me that

currentStatus

cannot be evaluated at that point.

is this some wierd issue with J2SE 1.3?

either way, don’t let that kind of thing get you. took me about 2 hours (well part of it is because of the crummy development setup wherein i have to stop my container, compile, then restart) to test various scenarios to come to that conclusion.

erg.

UPDATE (even before i post)

we ran into a similar situation later in the day–this looks like it *has* to be a bug in the JVM. even worse this time, the declaration wasn’t even inside of an if. i.e. the following code causes the if to be evaluated weirdly (it doesn’t seem to evaluate either correctly or incorrectly :), and the code would jump to the DBUtil line:

[some code here]

String currentStatus = this.getStatusCode();

//only make the change if there IS a change
if(!currentStatus.equals(newStatus)){
if(currentStatus.equals(BPConstants.CONST)) {
this.setStatusCode(newStatus);
DBUtil.updateBusinessObject(this);
//no upstream changes.
}

}

moving the declaration before the [some code here]


String currentStatus = this.getStatusCode();
[some code here]

//only make the change if there IS a change
if(!currentStatus.equals(newStatus)){
if(currentStatus.equals(BPConstants.CONST)) {
this.setStatusCode(newStatus);
DBUtil.updateBusinessObject(this);
//no upstream changes.
}

}

worked!

ah the joy of having to use a particular JVM with no upgrading with Quite A Bit of Ceremony.

  • http://joy.madisons.com joy

    uh, yeah, frazzle snazzle!