ServerPlugin ConcurrentModificationError außerhalb meines Plugins

Dieses Thema im Forum "Programmierung" wurde erstellt von G.A.F, 28. Juli 2015.

  1. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Heyho Leute,

    ich bin gerade dabei ein Plugin zu schreiben (Mit der Bukkit Lib) und verzweifle grade.
    Ein Spiel beginnt, alles läuft normal und dann nach einer unbestimmten Zeit gibt es > diesen < Error...

    Ich habe also die Stelle dem Error entnommen und gleich die Bukkit decompiled und > diese < Klasse als Quelle des Fehlers ausfindig machen können...
    (Hier ist es die Zeile 245)

    Leider habe ich weder eine Ahnung was der Fehler ist, noch wie der Fehler mit meinem Plugin zusammenhängt, noch wie ich ihn beheben kann :/
    Übrigens: Wenn ich mein Plugin rausnehme gibt es keinen Error, soweit ich das sehen konnte.

    Ich hoffe jemand kann mir helfen :)

    MfG Mineworker08 ~ G.A.F
     
    #1
  2. ShareLock
    Offline

    ShareLock

    Registriert seit:
    2. November 2011
    Beiträge:
    70
    Wenn du noch komprimierter schreibst, ist es nicht möglich das Problem zu analysieren. Wenn wegen deinem Plugin diese Fehlermeldung kommt, dann liegt es nicht an einer NMS Klasse. [Auch wenn dort der Fehler geworfen wird.]

    Ich rate aber mal ins blaue: Rufst du zufällig in einem Thread (außer dem main thread) eine Bukkit API / NMS Api auf, die nicht Threadsicher ist?
     
    #2
    [Dev] iTzSasukeHDxLP gefällt das.
  3. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Wenn ja, woran würde ich das erkennen? Ich habe mehrere Threads die nicht der Main Thread sind geöffnet, wenn die Fehlermeldung kommt, allerdings startet keiner davon grade erst, wenn sie auftritt! Das ist es ja was es mir so schwer macht den Fehler zu finden...

    Was würdest du denn erwarten noch zu posten?
     
    #3
  4. ShareLock
    Offline

    ShareLock

    Registriert seit:
    2. November 2011
    Beiträge:
    70
    Überleg doch mal: Der decompilierte Source ist nicht dafür verantwortlich. Das habe ich oben bereits erklärt. Die Verantwortung liegt derzeit in deinem Sourcecode und daher müsste man dies dort überprüfen.

    Das Problem mit Bukkit ist, dass es vielfach doch eher schwach entwickelt wurde und daher keine vernünftige Basis für ein gutes System ist.
     
    #4
    [Dev] iTzSasukeHDxLP gefällt das.
  5. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    #5
  6. Bukkit hat quasi keine Thread sicheren Methoden - Ich würde mich auch darauf nie wirklich verlassen.
     
    #6
  7. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Das ist schlecht...Wie soll man denn damit klarkommen, wenn ich nicht mal die Online-Players abrufen kann? Bisher hat es mit Bukkit-Methoden in Threads keine Probleme gegeben...

    Was ist denn das Problem mit diesen Methoden? Wieso sind sie nicht sicher?
     
    #7
  8. Threadsicherheit ist ein grundlegendes IT Problem. (Manche Spitzzungen würden jetzt mit "Das passiert halt, wenn man nicht programmieren kann" kommen)

    Die oben genannte Exception umgeht dieses Problem 'relativ' einfach.

    Mehr dazu hier.

    Bukkit hat sich nie darum gekümmrt richtig zu synchronisieren. Daher geben viele Methoden Probleme. - Bukkit.getAllPlayers() sollte afaik Thread sicher sein.
     
    #8
  9. 可愛い
    Offline

    可愛い

    Registriert seit:
    19. Mai 2014
    Beiträge:
    655
    Ich glaub es gibt 2 Methoden die offiziell Threadsafe sind, der Rest kann dir beliebig um die Ohren fliegen und wirft sogar Exceptions alleine aufgrund der Tatsache, dass dein Thread nicht der Mainthread is unabhängig davon ob die Methode ansonsten sogar Threadsafe wär. Das Beste ist daher einfach alles im Mainthread zu machen, was auf die Bukkit API zugreift.
     
    #9
  10. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Danke für eure Antworten, helfen tut mir das nun aber nicht so sehr...
    Muss ich nun extra einen Workaround ausarbeiten, mit dem ich niemals einen Thread schlafen schicken muss?

    Mal zurück zur Ausgangsfrage: Was ist die Klasse PlayerTracker ? Wenn ich das weiß werde ich das Problem ja wohl identifizieren können, oder ?
     
    #10
  11. Victini151
    Online

    Victini151

    Du kannst (und solltest) Threads nutzen, wenn es an blockierende IO-Operationen geht (Datenbank zB).
    Dabei solltest du aber einige Konzepte zur Threadsicherheit beachten, welche ich hier aufgrund der Fülle nicht weiter ausführe.
    Im Internet findet man diese aber relativ einfach. Ich weiß nicht wofür du in diesem Fall Threads benutzt - überprüfe jedoch einmal ob eine Task mit dem Bukkit-Scheduler nicht den Thread ersetzen könnte. Hierbei ist eben hauptsächlich auf Zeitintensive Algorithmen und Abfragen zu achten.
     
    #11
  12. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Ich sag mal so...
    Vermutlich werde ich hier gleich erschossen, allerdings nutze ich den Bukkit-Scheduler für die "Threads". Ist das die falsche Bezeichnung? Und ändert das was an der Situation?
     
    #12
  13. ShareLock
    Offline

    ShareLock

    Registriert seit:
    2. November 2011
    Beiträge:
    70
    Der Scheduler ist dafür da Threads zu verwalten. Du musst diese nur eben Synchron laufen lassen, wenn du auf eine Methode zugreifen willst, die nicht Threadsicher ist. Synchron heißt hier: Im Mainthread.
     
    #13
    [Dev] iTzSasukeHDxLP gefällt das.
  14. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Grr..den Mainthread kann ich aber nicht schlafen lassen, sonst ratzt mir der Server weg :/ Es muss doch eine Möglichkeit geben einen Asynchronen Thread laufen zu lassen den ich auch schlafen lassen kann, ohne dass ich diesen Error bekommen :(
     
    #14
  15. Victini151
    Online

    Victini151

    Warum willst du den Thread schlafen lassen?
     
    #15
  16. ShareLock
    Offline

    ShareLock

    Registriert seit:
    2. November 2011
    Beiträge:
    70
    Es ist nicht schwer einen Thread schlafen zu lassen. Das sind reine Basics:

    [ Block A - Threadsafe Methoden / Thread interne Zugriffe ]
    [ Sleep ]
    [ Block B - Feuern eines Sync-Task mit 1 Tick Delay ]
     
    #16
    [Dev] iTzSasukeHDxLP gefällt das.
  17. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Hat man davon, wenn man mit YouTube lernt...

    Diese Methode macht eigentlich das gesamte Spiel aus. Und bis dieser ConcurrentModificationError zu einer vollkommen willkürlichen Zeit auftritt läuft das auch Problemlos!
    http://hastebin.com/peyateseso.avrasm

    Ich verstehe leider weder was du mir mit deinem Post sagen willst, noch was ich tun soll :/ Wäre dankbar wenn du mir helfen könntest :)
     
    #17
  18. [Dev] iTzSasukeHDxLP
    Offline

    [Dev] iTzSasukeHDxLP Ehem. Teammitglied

    Registriert seit:
    5. Januar 2014
    Beiträge:
    938
    Warum lagerst du soetwas auch in einen asynchronen Thread aus? Du lässt praktisch ein ganzes Spiel in einem eigenen Thread laufen. Das ist zwar vom Grundgedanken kein Totalausfall, aber im Fall von Bukkit einfach nur unsinnig.
     
    #18
  19. ShareLock
    Offline

    ShareLock

    Registriert seit:
    2. November 2011
    Beiträge:
    70
    Also ich verstehe ja, dass du dich bemühst zu lernen [Im Gegensatz zu den meisten anderen Anfängern hier, sieht man sogar, dass du dir wirklich mühe gibst, auch die Thematik zu verstehen und du recherchierst sogar selber. Andere Personen, die ich kritisierte habe deswegen verstehen nicht einmal wieso...], aber du hast noch einen weiten Weg vor dir. Zuerst solltest du etwas refactorn. Das bedeutet deinen Sourcecode besser zu strukturieren.

    Im Übrigen wird der Fehler wahrscheinlich durch dropItemNaturally ausgelöst. Die Welt API ist nicht Thread-Safe.

    Folgende Tipps sollten den Code leserlicher gestallten:
    1. Zeit NIEMALS durch Thread.sleep und einem Zähler machen. System.currentTimeMillis liefert dir die aktuelle Zeit.
    2. Du kannst die Itemdrops durch einen Synchronen Thread ersetzen, den du alle X Ticks (20 Ticks = 1s) laufen lässt. (syncRepeatingTask)
    3. Versuche Methoden zu verwenden. Vieles sieht ähnlich aus. [Item dropping sieht sogar komplett gleich aus. ]
    4. %1 also modulo 1 ist immer 0.

    Asynchron ist hier sogar ziemlich sinnig. Nachrichten sind auch Asynchron.
     
    #19
    [Dev] iTzSasukeHDxLP gefällt das.
  20. G.A.F
    Offline

    G.A.F

    Registriert seit:
    13. Oktober 2013
    Beiträge:
    38
    Vielen Dank für Deine Tipps..
    Es ist wirklich schwer das zu verstehen, denn YouTube liefert nicht immer die intelligentesten Antworten ;)

    Allerdings wäre es suuper nett wenn du mir noch eben grob erklären könntest, was jetzt ein Synchroner und was ein Asynchroner Thread ist und wieso man keine asynchronen Threads verwenden sollte.
     
    #20