Takže nevím, zda je root ideální server pro tento dotaz, ale zkusím to
Mám v javě
package cz.exambuilder.entity.domain.calendar;
(...)
public class Calendar {
protected static final Set<Image> imagesQueue = new LinkedHashSet<>();
(...)
}
a ten set imagesQueue je neprázdný:
imagesQueue.isEmpty(); // dává false
imagesQueue.size(); // dává 1
Problém je, že položky toho setu nemůžu získat:
imagesQueue.iterator().hasNext(); // dává false
imagesQueue.iterator().next(); // hodí java.util.NoSuchElementException.
Podstatné, že k
tomuto stavu dojde až po cca měsíčním běhu aplikace, zprvu to funguje normálně.
Čichal bych tady nějaký problém v implementaci equals(), hashCode() nebo compareTo(), ale na nic jsem nepřišel, používám výchozí implementace z frameworku. Možná vstoupí do hry nějaký JIT nebo přesun instancí do jiné oblasti paměti a změní se hashcode nebo něco podobného? Na co se mám zaměřit? Uvažoval jsem ještě nad tím, zda se to do tohoto stavu nemůže dostat špatně ošetřeným konkurenčním přístupem, ale nedokážu si to představit.
Pozitivní je, že mám k dispozici testovací prostředí, kde to ještě funguje i prostředí, kde to už nefunguje - do obou se můžu se připojit debuggerem nebo z vývojové konzole umožňující spouštět interaktivně kód.
Na co se mám zaměřit?
Kdy k něčemu takovému může v principu vůbec dojít?Používám java version "1.8.0_161", apache-tomcat-8.5.5, Debian 4.8.4-1 a
Brightspot ve verzi v3.2.7178-2110f8
Aktuální testovací kód:
import cz.exambuilder.entity.domain.calendar.Calendar;
import java.util.stream.*;
import java.lang.reflect.*;
import org.slf4j.*;
public class Code {
public static Object main() throws Throwable {
Logger log = LoggerFactory.getLogger(Code.class);
// tady získám tu privátní instanci imagesQueue, abych se na ní mohl podívat:
Calendar calendar = Query.from(Calendar.class).first();
Field field = Calendar.class.getDeclaredField("imagesQueue");
field.setAccessible(true);
Set<Image> imagesQueue = (Set<Image>) field.get(calendar);
// tady zkouším, co imagesQueue obsahuje:
log.info("*** imagesQueue.isEmpty(): " + imagesQueue.isEmpty()); // false
log.info("*** imagesQueue.size(): " + imagesQueue.size()); // 1
log.info("*** imagesQueue.stream(): " + imagesQueue.stream().map(i -> String.format("%s (%s)", i.getTitle(), i.getId())).collect(Collectors.toList())); // prázdná kolekce
log.info("*** imagesQueue.iterator().hasNext(): " + imagesQueue.iterator().hasNext()); // false
try {
log.info("*** imagesQueue.iterator().next(): " + imagesQueue.iterator().next()); // NoSuchElementException
} catch(Exception e){
log.info("*** exception: " + e);
}
return "SEE LOGS";
}
}
Dík za nápady!