On 09/27/2015 10:49 PM, Mikolaj Izdebski wrote: > On 09/27/2015 09:45 PM, Gerard Ryan wrote: >> Hi, >> >> I'm encountering a test failure for the minimal-json package in mock, >> and I'm hoping someone can help me understand it. The assertions that >> fail are at [1]. >> >> If I take one of the assertions as an example, the first one on line 44: >> >> assertSame(Json.NULL, JsonValue.NULL); >> >> This is trying to assert that both of the objects refer to the same >> objects in memory. I think this is a perfectly fine thing to expect in >> this case, since the NULL field in JsonValue[3] refers directly to the >> NULL field in the Json class[4]. >> >> The test works fine if I just run mvn test in the upstream project, and >> I'm not applying any patches or changes in the spec file[2]. >> >> To compound my confusion, where this doesn't work in local mock for me >> at all for any release (f24, f23,f22), it works in koji **sometimes**: >> >> * a passing build from a couple of weeks ago in rawhide[5] >> * a passing scratch build from just now in rawhide[6] >> * a failing scratch build from just now in f23 [7] >> * a passing scratch build from just now in f23 [8] >> >> I _assume_ that my consistent failures locally and the intermittent >> failures in koji are related. >> >> If anyone has any idea what the cause of this is (also, solution ;)), >> I'd be delighted for any advice. I've been out of the Java head space >> for 6+ months now, so it's very possible that I'm overlooking something >> something obvious! > > It's a race condition - bug in upstream code. You can get different > results depending on the order of initialization of Json and JsonValue > classes. > > Consider the following example: > > class A { > static B x = new B(); > } > > class B { > static B x = A.x; > } > > public class Main { > public static void main(String[] args) { > System.out.println(A.x == B.x); > } > } > > What do you think the above program will print when executed? "true"? > Wrong. It prints "false". > > That's not all, try swapping arguments of comparison operator (i.e > replace "A.x == B.x" with "B.x == A.x"). Now it prints "true"! Magic? :) > > In case it's still not clear, this is how "false" result is produced: > > 1. JVM starts initializing class A. All fields are initially filled with > zeros. A.x is null at this point. > 2. JVM starts executing static field initializer for class A. It sees > reference to class B. > 3. JVM starts initializing class B. It then executes static field > initializer for class B - B.x is set to A.x, which is null. > 4. JVM continues with running static field initializer for class A. New > instance of class B is created and assigned to A.x > > End result: B.x is null, A.x is not null. > Hi Mikolaj, Thanks for your quick (yet thorough) response! I had hoped that Java would allow for people like me to do silly things like this :-/ For now, unless you have a better idea, I'll change the problematic class to also instantiate a new instance, and I'll change the test to assert equality rather than sameness (and propose the change upstream). Thanks again, Gerard. -- java-devel mailing list java-devel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/java-devel