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. -- Mikolaj Izdebski Software Engineer, Red Hat IRC: mizdebsk -- java-devel mailing list java-devel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/java-devel