Event manager is registering something in listener that shouldn't be registered
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 2.3k
- Forks
- 959
- Avg merge
- 5d 10h
- Merged PRs (30d)
- 2
Description
The problem
Since if i want multi platform support i tend to create API not to be depend on proxy that used which I create
ITestEvent.java and ITestListener.java which then i implement in it proxy api which can be seen in steps to reproduce.
what i should expect that event to be handled single time but instead it fired 2 times, well this was weird so i checked if i didn't double register the listener or something, and it wasn't so i kept debugging until i reached idea it could be velocity problem,
so after debugging with velocity, so IN VelocityEventManager at registerInternally after collectMethods i inserted this debug code
public void registerInternally(final PluginContainer pluginContainer, final Object listener) {
final Class<?> targetClass = listener.getClass();
final Map<String, MethodHandlerInfo> collected = new HashMap<>();
collectMethods(targetClass, collected);
collected.forEach((clazz, coll) -> {
logger.info("ID? {} | method {}", clazz, coll.method);
});
final List<HandlerRegistration> registrations = new ArrayList<>();
after adding debug messages i could see 2 methods registered
[18:26:39] [Velocity Async Event Executor - #0/INFO] [com.velocitypowered.proxy.event.VelocityEventManager]: ID? doSomething(net.limework.test.TestEvent): method public void net.limework.test.TestListener.doSomething(net.limework.test.TestEvent)
[18:26:39] [Velocity Async Event Executor - #0/INFO] [com.velocitypowered.proxy.event.VelocityEventManager]: ID? doSomething(net.limework.test.ITestEvent): method public void net.limework.test.TestListener.doSomething(net.limework.test.ITestEvent)
doSomething(net.limework.test.ITestEvent) shouldn't be registered since it does not have @Subscribe
steps to reproduce
- create classes in this type of configuration
- ITestEvent.java
package net.limework.test;
public interface ITestEvent {
int x();
}
- TestEvent.java
package net.limework.test;
public record TestEvent(int x) implements ITestEvent {
}
- ITestListener.java
package net.limework.test;
public interface ITestListener<E extends ITestEvent> {
void doSomething(E event);
}
- TestListener.java
package net.limework.test;
import com.velocitypowered.api.event.Subscribe;
public class TestListener implements ITestListener<TestEvent> {
@Override
@Subscribe
public void doSomething(TestEvent event) {
System.out.println("test event fired " + event.x());
}
}
-
register TestListener.java
-
fire the event TestEvent.java with example Code used to trigger the event
AtomicInteger i = new AtomicInteger(0);
server.getEventManager().register(this, new TestListener());
server.getScheduler().buildTask(this, () -> {
server.getEventManager().fireAndForget(new TestEvent(i.getAndIncrement()));
}).repeat(Duration.ofSeconds(1)).schedule();
- see the console output
[22:19:03 INFO]: test event fired 0
[22:19:03 INFO]: test event fired 0
[22:19:03 INFO]: Listening on /[0:0:0:0:0:0:0:0%0]:25577
[22:19:03 INFO]: Done (0.62s)!
[22:19:04 INFO]: test event fired 1
[22:19:04 INFO]: test event fired 1
[22:19:05 INFO]: test event fired 2
[22:19:05 INFO]: test event fired 2
[22:19:06 INFO]: test event fired 3
[22:19:06 INFO]: test event fired 3
[22:19:07 INFO]: test event fired 4
[22:19:07 INFO]: test event fired 4
[22:19:08 INFO]: test event fired 5
[22:19:08 INFO]: test event fired 5
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in VelocityEventManager.registerInternally, especially collectMethods, and reproduce the issue with the ITestEvent, TestEvent, ITestListener, and TestListener classes shown. Check why both the annotated TestEvent method and the inherited ITestEvent signature are collected. Done means the listener is registered once for the concrete event and the reproduction prints each event only once.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100