diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java
index 285f6f3..47e03c3 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/backend/InputHandler.java
@@ -22,10 +22,11 @@ import org.lwjgl.glfw.GLFW;
import com.google.common.eventbus.EventBus;
import ru.windcorp.progressia.client.graphics.input.*;
+import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
public class InputHandler {
- private static final EventBus INPUT_EVENT_BUS = new EventBus("Input");
+ private static final EventBus INPUT_EVENT_BUS = ReportingEventBus.create("Input");
// KeyEvent
diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java
index 7424bd9..e1034be 100644
--- a/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java
+++ b/src/main/java/ru/windcorp/progressia/client/graphics/gui/Component.java
@@ -40,6 +40,7 @@ import ru.windcorp.progressia.client.graphics.input.bus.InputBus;
import ru.windcorp.progressia.client.graphics.input.bus.InputListener;
import ru.windcorp.progressia.common.util.Named;
import ru.windcorp.progressia.common.util.crash.CrashReports;
+import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
public class Component extends Named {
@@ -455,7 +456,7 @@ public class Component extends Named {
public void addListener(Object listener) {
if (eventBus == null) {
- eventBus = new EventBus(getName());
+ eventBus = ReportingEventBus.create(getName());
}
eventBus.register(listener);
diff --git a/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java
new file mode 100644
index 0000000..48ffade
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/hacks/GuavaEventBusHijacker.java
@@ -0,0 +1,55 @@
+package ru.windcorp.progressia.common.hacks;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.SubscriberExceptionHandler;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import ru.windcorp.progressia.common.util.crash.CrashReports;
+
+/**
+ * This class had to be written because there is not legal way to instantiate a non-async
+ * {@link EventBus} with both a custom identifier and a custom exception handler. Which
+ * is a shame. Guava maintainers know about the issue but have rejected solutions multiple
+ * times without a clearly stated reason; looks like some dirty reflection will
+ * have to do.
+ * @author javapony
+ */
+public class GuavaEventBusHijacker {
+
+ public static final Constructor THE_CONSTRUCTOR;
+ public static final Method DISPATCHER__PER_THREAD_DISPATCH_QUEUE;
+
+ static {
+ try {
+ Class> dispatcherClass = Class.forName("com.google.common.eventbus.Dispatcher");
+
+ THE_CONSTRUCTOR = EventBus.class.getDeclaredConstructor(
+ String.class, Executor.class, dispatcherClass, SubscriberExceptionHandler.class
+ );
+ THE_CONSTRUCTOR.setAccessible(true);
+
+ DISPATCHER__PER_THREAD_DISPATCH_QUEUE = dispatcherClass.getDeclaredMethod("perThreadDispatchQueue");
+ DISPATCHER__PER_THREAD_DISPATCH_QUEUE.setAccessible(true);
+ } catch (Exception e) {
+ throw CrashReports.report(e, "Something went horribly wrong when setting up EventBus hijacking. Has Guava updated?");
+ }
+ }
+
+ public static EventBus newEventBus(String identifier, SubscriberExceptionHandler exceptionHandler) {
+ try {
+ return THE_CONSTRUCTOR.newInstance(
+ identifier,
+ MoreExecutors.directExecutor(),
+ DISPATCHER__PER_THREAD_DISPATCH_QUEUE.invoke(null),
+ exceptionHandler
+ );
+ } catch (Exception e) {
+ throw CrashReports.report(e, "Something went horribly wrong when hijacking EventBus. Has Guava updated?");
+ }
+ }
+
+}
diff --git a/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java
new file mode 100644
index 0000000..0633085
--- /dev/null
+++ b/src/main/java/ru/windcorp/progressia/common/util/crash/ReportingEventBus.java
@@ -0,0 +1,18 @@
+package ru.windcorp.progressia.common.util.crash;
+
+import com.google.common.eventbus.EventBus;
+
+import ru.windcorp.progressia.common.hacks.GuavaEventBusHijacker;
+
+public class ReportingEventBus {
+
+ private ReportingEventBus() {}
+
+ public static EventBus create(String identifier) {
+ return GuavaEventBusHijacker.newEventBus(identifier, (throwable, context) -> {
+ // Makes sense to append identifier to messageFormat because different EventBuses are completely unrelated
+ throw CrashReports.crash(throwable, "Unexpected exception in EventBus " + identifier);
+ });
+ }
+
+}