0

I'm building a javafx application, but I stumbled upon an error I can't find the solution to due to its random nature. When using the app, I sometimes run into this error at random parts of my code:

Exception in thread "Thread-20" java.lang.NoClassDefFoundError: view/gui/GameViewController$8
    at view.gui.GameViewController.handleEvent(GameViewController.java:876)
    at view.gui.GameViewController.lambda$initialize$0(GameViewController.java:161)
    at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ClassNotFoundException: view.gui.GameViewController$8
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/jdk.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 3 more

Important to say that the number of the affected thread seems to be completely random, I just put this error log in which the Thread is number 20, but that should not be relevant to the issue. The classes in which the error occurs are the javafx controllers I use to manage the scenes of my app with. In this case the issue came from handleEvent(), a method called from a thread created in the initialize method of the controller, which is used to receive events from the server during a game and update the GUI based on the information received.

Here are the code snippets cited in the error, even though the random nature of the issue makes me think it might not be important:

        serverThread = new Thread(() -> {  //thread in the initialize method of the controller  
            while (state != ClientStatus.Disconnected) {
                synchronized (networkManager) {
                    try {
                        while (!networkManager.hasEvent()) {
                            networkManager.wait();
                        }
                    } catch (InterruptedException e) {
                        break;
                    }
                }
                handleEvent(); //This is line 161
            }
        });
        serverThread.start();
                Platform.runLater(new Runnable() { //line 876, snippet from handleEvent method
                    @Override
                    public void run() {
                        fillScene(gameData.getTableTop()); //lines to update gui
                        fillShelf(gameData.getMyShelf());
                        selectedImages.clear();
                    }
                });

Also important to say that in this instance, the bug apparently happened at the Platform.runLater, but other times happened at random lines.

I tried to find what would cause the issue but it's really difficult. The problem is that it seems to be completely random and happened to other classes in the project, so I have no real way to reproduce it. I only once managed to reproduce the bug following a series of certain actions using the app, but a more recent instance of this bug in a completely unrelated part of the project makes me think it's just a sleeping issue that could be anywhere and said series of actions might just make it more likely to happen than others actions. After managing to reproduce it, I tried many times to make it fire again, but with no success.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • 1
    It sems really odd that you're starting a thread in the initialize method of your controller. I strongly suspect you'll need to create a complete working example that can reproduce the issue. Are you noticing any consequences of the bug, or just you get an error message? – matt Jun 27 '23 at 08:23
  • You could probably get the error message to change if you switch from `new Runnable()...` to `()->{}` since the `new Runnable()` creates an anonymous inner class presumably ` GameViewController$8.class` is the class file not getting included on the classpath? – matt Jun 27 '23 at 08:28
  • Thanks for you response. To answer: 1) Due to its random nature, i have no way to reproduce the bug constantly. The bug actually had consequences, as it stopped the normal flow of the javafx thread and prevented the gui from updating with the information received from the server. 2) I switched all the runlater in the project as suggested, now i'm waiting to see if the bug occurs again. – Ludovico Maltagliati Jun 27 '23 at 11:34
  • Are you using a framework other than JavaFX (e.g., Spring, CDI, etc.)? Are there any custom class loaders/module layers being used? How is your application deployed/built? How are you running the application? – Slaw Jun 27 '23 at 22:00
  • Just as a background FYI, review [java compiled classes contain dollar signs](https://stackoverflow.com/questions/11388840/java-compiled-classes-contain-dollar-signs), to understand what `view.gui.GameViewController$8` is. It is almost as though you don't have the correct binary version of your compiled code available, leading to runtime incompatibilities in calls due to an expected binary interface (e.g. a lambda definition on anonymous inner class in GameViewController) being unavailable (why I don't know). – jewelsea Jun 28 '23 at 21:28
  • Check your build target output (or contents of the jar file you are executing). Is there a file there named `view/gui/GameViewController$8.class`? – jewelsea Jun 28 '23 at 21:40
  • If you use lambda syntax rather than an anonymous inner class, a dollar class won't be generated. It may not solve your underlying issue, but it should at least result in a different error message (if you can reproduce the exact conditions which lead to the error, which might be difficult or impossible to do). e.g. try `Platform.runLater(() -> { /** your code */ });` – jewelsea Jun 28 '23 at 21:44

0 Answers0