On 26/01/2023 7:49 pm, Tagir Valeev wrote:
Hello!
Not sure if this should be considered as a problem that requires
attention but there's an initialization loop between
There are probably still quite a number of "initialization loops" in the
core libraries. But they can only trigger if you explicitly load and
initialize internal implementation classes. So no, this is not generally
considered a problem.
Cheers,
David
java.util.Collections$UnmodifiableNavigableMap and
java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
classes. E.g., the following program may stuck in a classloader
deadlock (happens to me in ~30% of launches):
import static java.util.concurrent.CompletableFuture.supplyAsync;
public class Test {
public static void main(String[] args) {
var future1 = supplyAsync(() ->
loadClass("java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap"));
var future2 = supplyAsync(() ->
loadClass("java.util.Collections$UnmodifiableNavigableMap"));
System.out.println(future1.join()+":"+future2.join());
}
private static Class<?> loadClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
This is due to the EMPTY_NAVIGABLE_MAP which is declared in
UnmodifiableNavigableMap but its type is a subclass of
UnmodifiableNavigableMap. Moving the field inside EmptyNavigableMap
will likely solve the problem. On the other hand, I was not able to
reproduce the problem without explicit Class.forName call, and given
that EmptyNavigableMap class is an implementation detail, we probably
can ignore this.
With best regards,
Tagir Valeev.