Volt ma egy szép debug köröm. Nagyon nem értettem, miért nem működik egy kód – ami ráaásul régebben (július végén) szépen ment, és azóta nem nyúltam hozzá, és elvileg a kapcsolódó libekben sem volt lényegi változás azóta.

Úgy gondolom, bemutatom a kódot, és felteszem a kérdést, látja-e más is a hibát benne.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private ICoreNotificationObject notificationObject;

public void actionPerformed(ICoreNotificationObject notification) {
  this.notificationObject = notification;
  Display.getDefault().aSyncExec(new Runnable() {

  public void run() {
    String action = notificationObject.getActionType();
    if (isOneOf(action, new String[] {
          ICoreNotificationObject.TA_TRANSACTION_END,
          ICoreNotificationObject.TA_UNDO_END,
          ICoreNotificationObject.TA_SUBTRANSACTION_END})) {
       updateGraph();
       transactions.pop();
    } else if (isOneOf(action, new String[] {...}){
       //...
    }
  });

Még némi információ a kód működéséről: a kód egy eseményfigyelő osztály belsejében van, és a Runnable adatváltozásokat próbál követni, amely tranzakciókba van szervezve, ill. a tranzakciók során visszavonás események is érkezhetnek.

Na, kinek van tippje, mi lehet a hiba? Ha nincs tipp véges időn belül (előre nem specifikálnám), akkor majd megosztom a helyes megfejtést. Annyit mondok előre, hogy fejet falbaverős hiba :D .

Update: először is helyesbítettem a kódot, mert sikeresen a javított változatot töltöttem fel.

A problémát az okozta, hogy az asyncExec() hívás indított egy új jobot, amit valamikor majd végrehajt. Csak közben visszaadja a vezérlést, és ezzel lehetővé teszi a rendszer számára, hogy felülírja a run() metóduson belül is használt notificationObject változót.

Az asyncExec() hívás syncExec()-re cserélése megoldotta a problémát, ugyanis az megvárja, hogy visszatérjen a meghívott thread.

Ez a hiba kifejezetten mocskos dolog, mert eredetileg működött, míg a környezet refactoringja előhozta a bugot…