I tried to register the channel exactly as Sponge does, but without the check that create the issue.
To do it, I use Java Reflection like that :
RawDataChannel spongeChannel = null; // declare channel
try {
// firstly, try default channel registration to go faster
spongeChannel = Sponge.getChannelRegistrar().getOrCreateRaw(plugin, channel);
} catch (ChannelRegistrationException e) { // error -> can't register
try {
// load class
Class<?> vanillaRawChannelClass = Class.forName("org.spongepowered.server.network.VanillaRawDataChannel");
Class<?> vanillaChannelRegistrarClass = Class.forName("org.spongepowered.server.network.VanillaChannelRegistrar");
Class<?> vanillaBindingClass = Class.forName("org.spongepowered.server.network.VanillaChannelBinding");
// get constructor of raw channel
Constructor<?> rawChannelConstructor = vanillaRawChannelClass.getConstructor(ChannelRegistrar.class, String.class, PluginContainer.class);
spongeChannel = (RawDataChannel) rawChannelConstructor.newInstance(Sponge.getChannelRegistrar(), channel, plugin.getContainer()); // new channel instance
// now register channel
Method registerChannel = vanillaChannelRegistrarClass.getDeclaredMethod("registerChannel", vanillaBindingClass); // get the method to register
registerChannel.setAccessible(true); // it's a private method, so set as accessible
registerChannel.invoke(Sponge.getChannelRegistrar(), spongeChannel); // run channel registration
} catch (Exception exc) {
exc.printStackTrace(); // reflection failed
}
}
if(spongeChannel == null) // channel not registered
return;
// my channel is now registered, by one of both available method. That's perfect
spongeChannel.addListener((data, connection, side) -> { // my listener
if(side == Type.CLIENT) {
// do something
}
});;
If there already have an error, specially when the reflection failed, I suggest you to check for new version, maybe method have change her parameter or class have been moved.
You can find Sponge code on their github.