diff --git a/README.md b/README.md index 8ee6d8f..2ae70a7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ BungeeIPC is a set of APIs and plugins meant for BungeeCord proxies and their ba ## Obtaining BungeeIPC You can obtain a copy of BungeeIPC via the following methods: -- Download a pre-built copy from the [Releases page](https://github.com/bspfsystems/BungeeIPC/releases/latest/). The latest version is release 3.0.4. +- Download a pre-built copy from the [Releases page](https://github.com/bspfsystems/BungeeIPC/releases/latest/). The latest version is release 3.1.0. - Build from source (see below). If you need to use BungeeIPC as a dependency for your project, please see the Development API section below. @@ -58,7 +58,7 @@ Include the following in your `pom.xml` file:
org.bspfsystems.bungeeipc bungeeipc-common-api - 3.0.4 + 3.1.0 provided @@ -68,7 +68,7 @@ Include the following in your `pom.xml` file:
org.bspfsystems.bungeeipc bungeeipc-client-api - 3.0.4 + 3.1.0 provided @@ -78,7 +78,7 @@ Include the following in your `pom.xml` file:
org.bspfsystems.bungeeipc bungeeipc-server-api - 3.0.4 + 3.1.0 provided @@ -95,17 +95,17 @@ repositories { // For both Bukkit and BungeeCord dependencies { - compileOnly "org.bspfsystems.bungeeipc:bungeeipc-common-api:3.0.4" + compileOnly "org.bspfsystems.bungeeipc:bungeeipc-common-api:3.1.0" } // For Bukkit dependencies { - compileOnly "org.bspfsystems.bungeeipc:bungeeipc-client-api:3.0.4" + compileOnly "org.bspfsystems.bungeeipc:bungeeipc-client-api:3.1.0" } // For BungeeCord dependencies { - compileOnly "org.bspfsystems.bungeeipc:bungeeipc-server-api:3.0.4" + compileOnly "org.bspfsystems.bungeeipc:bungeeipc-server-api:3.1.0" } ``` diff --git a/bukkit/pom.xml b/bukkit/pom.xml index ad2a198..9106018 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -24,7 +24,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 bungeeipc-bukkit @@ -37,13 +37,13 @@ org.bspfsystems.bungeeipc bungeeipc-client-api - 3.0.4 + 3.1.0 compile org.jetbrains annotations - 23.0.0 + 23.1.0 provided @@ -59,7 +59,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0 + 3.4.1 diff --git a/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitClientIPCSocket.java b/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitClientIPCSocket.java index 14089f8..d35400a 100644 --- a/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitClientIPCSocket.java +++ b/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitClientIPCSocket.java @@ -93,7 +93,9 @@ final class BukkitClientIPCSocket implements ClientIPCSocket { final String addressValue = config.getString("bungeecord_ip", "localhost"); final int portValue = config.getInt("port", -1); - BukkitClientIPCSocket.validateNotBlank(addressValue, "IP address cannot be blank."); + if (addressValue.trim().isEmpty()) { + throw new IllegalArgumentException("IP address cannot be blank."); + } if (portValue == -1) { throw new IllegalArgumentException("Port must be specified in the config."); } @@ -103,7 +105,7 @@ final class BukkitClientIPCSocket implements ClientIPCSocket { try { this.address = InetAddress.getByName(addressValue); - } catch (UnknownHostException e) { + } catch (final UnknownHostException e) { throw new IllegalArgumentException("Unable to decipher IP address from config value.", e); } this.port = portValue; @@ -165,7 +167,7 @@ public void run() { this.connected.set(true); this.logger.log(Level.INFO, "Connected to the IPC server."); - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.INFO, "Unable to connect to IPC server."); this.logger.log(Level.CONFIG, "IP Address - " + this.address.getHostAddress()); @@ -185,7 +187,7 @@ public void run() { final IPCMessage message = SimpleClientIPCMessage.read(fromBungee.readUTF()); this.scheduler.runTask(this.ipcPlugin, () -> this.ipcPlugin.receiveMessage(message)); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.INFO, "IPC connection broken."); this.logger.log(Level.CONFIG, "IP Address - " + this.address.getHostAddress()); @@ -196,7 +198,7 @@ public void run() { if (this.toBungee != null) { this.toBungee.close(); } - } catch (IOException e1) { + } catch (final IOException e1) { this.logger.log(Level.WARNING, "Failure for IPC client."); this.logger.log(Level.WARNING, "Unable to close the DataOutputStream after the IPC connection was broken."); this.logger.log(Level.WARNING, e1.getClass().getSimpleName() + " thrown.", e1); @@ -206,7 +208,7 @@ public void run() { if (this.socket != null) { this.socket.close(); } - } catch (IOException e1) { + } catch (final IOException e1) { this.logger.log(Level.WARNING, "Failure for IPC client."); this.logger.log(Level.WARNING, "Unable to close the Socket after the IPC connection was broken."); this.logger.log(Level.WARNING, e1.getClass().getSimpleName() + " thrown.", e1); @@ -229,18 +231,21 @@ private static class SimpleClientIPCMessage extends AbstractIPCMessage { /** * Constructs a new {@link IPCMessage}. - * + * * @param origin The origin {@link IPCSocket}. * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link Queue}. Order will be * maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) * @throws IllegalArgumentException If {@code origin}, * {@code destination}, and/or * {@code channel} are blank, or if any * element in {@code data} is * {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) */ private SimpleClientIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) { super(origin, destination, channel, data); @@ -253,11 +258,17 @@ private SimpleClientIPCMessage(@NotNull final String origin, @NotNull final Stri * @param message The serialized {@link IPCMessage} as a {@link String}. * @return The deserialized {@link IPCMessage}. * @throws IllegalArgumentException If the given message is blank. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. */ @NotNull - private static IPCMessage read(@NotNull String message) { + private static IPCMessage read(@NotNull String message) throws IllegalArgumentException, IllegalStateException { + + if (message.trim().isEmpty()) { + throw new IllegalArgumentException("IPCMessage data cannot be blank, cannot recreate IPCMessage: " + message); + } - AbstractIPCMessage.validateNotBlank(message, "IPCMessage data cannot be blank, cannot recreate IPCMessage: " + message); final Queue split = new LinkedList(); int index = message.indexOf(AbstractIPCMessage.SEPARATOR); @@ -304,7 +315,7 @@ public void stop() { if (this.toBungee != null) { this.toBungee.close(); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Failure for IPC client."); this.logger.log(Level.WARNING, "Unable to close the DataOutputStream during shutdown."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -314,7 +325,7 @@ public void stop() { if (this.socket != null) { this.socket.close(); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Failure for IPC client."); this.logger.log(Level.WARNING, "Unable to close the Socket during shutdown."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -355,23 +366,9 @@ private synchronized void send(@NotNull final IPCMessage message) { try { this.toBungee.writeUTF(message.write()); - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Cannot send IPC message to Bungee proxy."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); } } - - /** - * Validates that the given {@link String value} is not empty (or only - * whitespace). - * - * @param value The {@link String value} to check for being blank. - * @param message The error message to display if the value is blank. - * @throws IllegalArgumentException If the given value is blank. - */ - private static void validateNotBlank(@Nullable final String value, @NotNull final String message) throws IllegalArgumentException { - if (value != null && value.trim().isEmpty()) { - throw new IllegalArgumentException(message); - } - } } diff --git a/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitIPCPlugin.java b/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitIPCPlugin.java index 2da0b7c..f53ec34 100644 --- a/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitIPCPlugin.java +++ b/bukkit/src/main/java/org/bspfsystems/bungeeipc/bukkit/BukkitIPCPlugin.java @@ -122,7 +122,7 @@ public void onEnable() { this.logger.log(Level.SEVERE, "IPC Client will not be started."); return; } - } catch (SecurityException e) { + } catch (final SecurityException e) { this.logger.log(Level.SEVERE, "Unable to validate if the BungeeIPC data directory has been properly created at " + dataDirectory.getPath()); this.logger.log(Level.SEVERE, "IPC Client will not be started."); this.logger.log(Level.SEVERE, e.getClass().getSimpleName() + " thrown.", e); @@ -368,7 +368,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com } return; } - } catch (SecurityException | IOException e) { + } catch (final SecurityException | IOException e) { this.logger.log(Level.WARNING, "Unable to load the BungeeIPC configuration file at " + configFile.getPath()); this.logger.log(Level.WARNING, "IPC Client will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -381,7 +381,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com final YamlConfiguration config = new YamlConfiguration(); try { config.load(configFile); - } catch (IOException | InvalidConfigurationException | IllegalArgumentException e) { + } catch (final IOException | InvalidConfigurationException | IllegalArgumentException e) { this.logger.log(Level.WARNING, "Unable to load BungeeIPC configuration."); this.logger.log(Level.WARNING, "IPC Client will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -395,7 +395,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com Level rawLoggingLevel; try { rawLoggingLevel = Level.parse(config.getString("logging_level", "INFO")); - } catch (NullPointerException | IllegalArgumentException e) { + } catch (final NullPointerException | IllegalArgumentException e) { this.logger.log(Level.WARNING, "Unable to load the BungeeIPC logging level."); this.logger.log(Level.WARNING, "Will use the default level (INFO)."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -456,7 +456,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com sslContext.init(null, null, null); sslSocketFactory = sslContext.getSocketFactory(); - } catch (NoSuchAlgorithmException | KeyManagementException e) { + } catch (final NoSuchAlgorithmException | KeyManagementException e) { this.logger.log(Level.WARNING, "Unable to create SSLSocketFactory."); this.logger.log(Level.WARNING, "IPC Client will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + "thrown.", e); @@ -471,7 +471,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com try { this.socket = new BukkitClientIPCSocket(this, config, sslSocketFactory, tlsVersionWhitelist, tlsCipherSuiteWhitelist); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { this.logger.log(Level.WARNING, "Unable to create IPC Client."); this.logger.log(Level.WARNING, "IPC Client will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index 81ee1e1..477906e 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -2,7 +2,7 @@ name: BungeeIPC main: org.bspfsystems.bungeeipc.bukkit.BukkitIPCPlugin author: mciolkosz website: https://github.com/bspfsystems/BungeeIPC/ -version: 3.0.4 +version: 3.1.0 commands: ipc: diff --git a/bungeecord/pom.xml b/bungeecord/pom.xml index c78a95c..a51ccf1 100644 --- a/bungeecord/pom.xml +++ b/bungeecord/pom.xml @@ -24,7 +24,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 bungeeipc-bungeecord @@ -37,13 +37,13 @@ org.bspfsystems.bungeeipc bungeeipc-server-api - 3.0.4 + 3.1.0 compile org.jetbrains annotations - 23.0.0 + 23.1.0 provided @@ -59,7 +59,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0 + 3.4.1 diff --git a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeIPCPlugin.java b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeIPCPlugin.java index f7fe5ae..fd842fb 100644 --- a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeIPCPlugin.java +++ b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeIPCPlugin.java @@ -169,7 +169,7 @@ public void onEnable() { this.logger.log(Level.WARNING, "IPC Client will not be started."); return; } - } catch (SecurityException e) { + } catch (final SecurityException e) { this.logger.log(Level.WARNING, "Unable to validate if the BungeeIPC data directory has been properly created at " + dataDirectory.getPath()); this.logger.log(Level.WARNING, "IPC Client will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -465,7 +465,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com } return; } - } catch (SecurityException | IOException e) { + } catch (final SecurityException | IOException e) { this.logger.log(Level.WARNING, "Unable to load the BungeeIPC configuration file at " + configFile.getPath()); this.logger.log(Level.WARNING, "None of the IPC Servers will be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -478,7 +478,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com final Configuration config; try { config = provider.load(configFile); - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Unable to load the BungeeIPC configuration."); this.logger.log(Level.WARNING, "None of the IPC Servers will be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -499,7 +499,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com Level loggingLevel; try { loggingLevel = Level.parse(config.getString("logging_level", "INFO")); - } catch (NullPointerException | IllegalArgumentException e) { + } catch (final NullPointerException | IllegalArgumentException e) { this.logger.log(Level.WARNING, "Unable to load the BungeeIPC logging level."); this.logger.log(Level.WARNING, "Will use the default level (INFO)."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -611,7 +611,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); sslServerSocketFactory = sslContext.getServerSocketFactory(); - } catch (KeyStoreException | SecurityException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException e) { + } catch (final KeyStoreException | SecurityException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException e) { this.logger.log(Level.WARNING, "Unable to create SSLServerSocketFactory."); this.logger.log(Level.WARNING, "None of the IPC Servers will be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -660,7 +660,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com for (final NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) { localAddresses.addAll(Collections.list(iface.getInetAddresses())); } - } catch (SocketException e) { + } catch (final SocketException e) { this.logger.log(Level.WARNING, "Unable to load all local network interfaces."); this.logger.log(Level.WARNING, "None of the IPC Servers will be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -676,7 +676,7 @@ private void reloadConfig(@NotNull final CommandSender sender, final boolean com final BungeeServerIPCSocket serverSocket; try { serverSocket = new BungeeServerIPCSocket(this, serverName, serverConfig, localAddresses, sslServerSocketFactory, tlsVersionWhitelist, tlsCipherSuiteWhitelist); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { this.logger.log(Level.WARNING, "Failure while attempting to create ServerIPCSocket " + serverName + "."); this.logger.log(Level.WARNING, "IPC Server " + serverName + " will not be started."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); diff --git a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeProxyIPCReader.java b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeProxyIPCReader.java index fadf9d2..3bb0552 100644 --- a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeProxyIPCReader.java +++ b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeProxyIPCReader.java @@ -74,7 +74,7 @@ public void readMessage(@NotNull final IPCMessage message) { final UUID proxySenderId; try { proxySenderId = UUID.fromString(proxySenderName); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { this.logger.log(Level.WARNING, "Unable to decipher proxy command sender UUID."); this.logger.log(Level.WARNING, "Incoming value: " + proxySenderName); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); diff --git a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeServerIPCSocket.java b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeServerIPCSocket.java index 3bc351b..5b92ed4 100644 --- a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeServerIPCSocket.java +++ b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/BungeeServerIPCSocket.java @@ -101,7 +101,9 @@ final class BungeeServerIPCSocket implements ServerIPCSocket { this.ipcPlugin = ipcPlugin; this.logger = this.ipcPlugin.getLogger(); - BungeeServerIPCSocket.validateNotBlank(name, "Server name cannot be blank."); + if (name.trim().isEmpty()) { + throw new IllegalArgumentException("Server name cannot be blank."); + } if (name.equalsIgnoreCase(IPCMessage.PROXY_SERVER)) { throw new IllegalArgumentException("Server name cannot be the proxy name (" + IPCMessage.PROXY_SERVER + ")."); } @@ -118,11 +120,13 @@ final class BungeeServerIPCSocket implements ServerIPCSocket { this.name = name; final String addressValue = config.getString("bind_address", "localhost"); - BungeeServerIPCSocket.validateNotBlank(addressValue, "IP address cannot be blank."); + if (addressValue.trim().isEmpty()) { + throw new IllegalArgumentException("IP address cannot be blank."); + } try { this.address = InetAddress.getByName(addressValue); - } catch (UnknownHostException e) { + } catch (final UnknownHostException e) { throw new IllegalArgumentException("Unable to decipher IP address from config value.", e); } if (!localAddresses.contains(this.address)) { @@ -191,7 +195,7 @@ public void run() { } else { this.serverSocket = new ServerSocket(this.port, 2, this.address); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.SEVERE, "IOException thrown while setting up the IPC server.", e); throw new RuntimeException(e.getClass().getSimpleName() + " thrown while setting up the IPC server.", e); } @@ -220,7 +224,7 @@ public void run() { final IPCMessage message = SimpleServerIPCMessage.read(fromBukkit.readUTF(), this.name); this.scheduler.runAsync(this.ipcPlugin, () -> this.ipcPlugin.receiveMessage(message)); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.INFO, "IPC server " + this.name + " connection broken."); this.logger.log(Level.FINE, "Server Name - " + this.name); @@ -232,7 +236,7 @@ public void run() { if (this.toBukkit != null) { this.toBukkit.close(); } - } catch (IOException e1) { + } catch (final IOException e1) { this.logger.log(Level.WARNING, "Failure for IPC server " + this.name + "."); this.logger.log(Level.WARNING, "Unable to close the DataOutputStream after the IPC connection was broken."); this.logger.log(Level.WARNING, e1.getClass().getSimpleName() + " thrown.", e1); @@ -242,7 +246,7 @@ public void run() { if (this.socket != null) { this.socket.close(); } - } catch (IOException e1) { + } catch (final IOException e1) { this.logger.log(Level.WARNING, "Failure for IPC server " + this.name + "."); this.logger.log(Level.WARNING, "Unable to close the Socket after the connection was broken."); this.logger.log(Level.WARNING, e1.getClass().getSimpleName() + " thrown.", e1); @@ -262,18 +266,21 @@ private static class SimpleServerIPCMessage extends AbstractIPCMessage { /** * Constructs a new {@link IPCMessage}. - * + * * @param origin The origin {@link IPCSocket}. * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link Queue}. Order will be * maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) * @throws IllegalArgumentException If {@code origin}, * {@code destination}, and/or * {@code channel} are blank, or if any * element in {@code data} is * {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) */ private SimpleServerIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) { super(origin, destination, channel, data); @@ -288,11 +295,17 @@ private SimpleServerIPCMessage(@NotNull final String origin, @NotNull final Stri * read in by. * @return The deserialized {@link IPCMessage}. * @throws IllegalArgumentException If the given message is blank. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. */ @NotNull - private static IPCMessage read(@NotNull String message, @NotNull final String serverName) { + private static IPCMessage read(@NotNull String message, @NotNull final String serverName) throws IllegalArgumentException, IllegalStateException { + + if (message.trim().isEmpty()) { + throw new IllegalArgumentException("IPCMessage data cannot be blank, cannot recreate IPCMessage: " + message); + } - AbstractIPCMessage.validateNotBlank(message, "IPCMessage data cannot be blank, cannot recreate IPCMessage: " + message); final Queue split = new LinkedList(); int index = message.indexOf(AbstractIPCMessage.SEPARATOR); @@ -342,7 +355,7 @@ public void stop() { if (this.toBukkit != null) { this.toBukkit.close(); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Failure for IPC server " + this.name + "."); this.logger.log(Level.WARNING, "Unable to close the DataOutputStream during shutdown."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -352,7 +365,7 @@ public void stop() { if (this.socket != null) { this.socket.close(); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Failure for IPC server " + this.name + "."); this.logger.log(Level.WARNING, "Unable to close the Socket during shutdown."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -362,7 +375,7 @@ public void stop() { if (this.serverSocket != null) { this.serverSocket.close(); } - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Failure for IPC server " + this.name + "."); this.logger.log(Level.WARNING, "Unable to close the ServerSocket during shutdown."); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); @@ -403,7 +416,7 @@ private synchronized void send(@NotNull final IPCMessage message) { try { this.toBukkit.writeUTF(message.write()); - } catch(IOException e) { + } catch (final IOException e) { this.logger.log(Level.WARNING, "Cannot send IPC message to Bukkit server " + this.name); this.logger.log(Level.WARNING, e.getClass().getSimpleName() + " thrown.", e); } @@ -440,18 +453,4 @@ InetAddress getAddress() { int getPort() { return this.port; } - - /** - * Validates that the given {@link String value} is not empty (or only - * whitespace). - * - * @param value The {@link String value} to check for being blank. - * @param message The error message to display if the value is blank. - * @throws IllegalArgumentException If the given value is blank. - */ - private static void validateNotBlank(@Nullable final String value, @NotNull final String message) { - if (value != null && value.trim().isEmpty()) { - throw new IllegalArgumentException(message); - } - } } diff --git a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/ServerStatusUpdater.java b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/ServerStatusUpdater.java index 11bfa6e..0c6610c 100644 --- a/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/ServerStatusUpdater.java +++ b/bungeecord/src/main/java/org/bspfsystems/bungeeipc/bungeecord/ServerStatusUpdater.java @@ -80,7 +80,7 @@ public void run() { this.ipcPlugin.setOnlineStatus(server.getName(), true); continue; - } catch (IOException e) { + } catch (final IOException e) { this.logger.log(Level.FINE, e.getClass().getSimpleName() + " thrown while updating status.", e); } this.ipcPlugin.setOnlineStatus(server.getName(), false); diff --git a/bungeecord/src/main/resources/plugin.yml b/bungeecord/src/main/resources/plugin.yml index d7cc866..71eef9e 100644 --- a/bungeecord/src/main/resources/plugin.yml +++ b/bungeecord/src/main/resources/plugin.yml @@ -1,4 +1,4 @@ name: BungeeIPC main: org.bspfsystems.bungeeipc.bungeecord.BungeeIPCPlugin -version: 3.0.4 +version: 3.1.0 author: mciolkosz diff --git a/client-api/pom.xml b/client-api/pom.xml index 011ad04..330ec0e 100644 --- a/client-api/pom.xml +++ b/client-api/pom.xml @@ -23,7 +23,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 bungeeipc-client-api @@ -36,13 +36,13 @@ org.bspfsystems.bungeeipc bungeeipc-common-api - 3.0.4 + 3.1.0 compile org.jetbrains annotations - 23.0.0 + 23.1.0 provided diff --git a/client-api/src/main/java/org/bspfsystems/bungeeipc/api/client/ClientIPCMessage.java b/client-api/src/main/java/org/bspfsystems/bungeeipc/api/client/ClientIPCMessage.java index 361e6b8..1df9764 100644 --- a/client-api/src/main/java/org/bspfsystems/bungeeipc/api/client/ClientIPCMessage.java +++ b/client-api/src/main/java/org/bspfsystems/bungeeipc/api/client/ClientIPCMessage.java @@ -37,11 +37,14 @@ public final class ClientIPCMessage extends AbstractIPCMessage { * * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String) */ - public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException { + public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PLACEHOLDER_SERVER, destination, channel); } @@ -53,12 +56,15 @@ public ClientIPCMessage(@NotNull final String destination, @NotNull final String * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link List}. Order will be maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank, or if any * element in {@code data} is {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) */ - public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException { + public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PLACEHOLDER_SERVER, destination, channel, data); } @@ -71,12 +77,15 @@ public ClientIPCMessage(@NotNull final String destination, @NotNull final String * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link Queue}. Order will be * maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank, or if any * element in {@code data} is {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) */ - public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) throws IllegalArgumentException { + public ClientIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PLACEHOLDER_SERVER, destination, channel, data); } } diff --git a/common-api/pom.xml b/common-api/pom.xml index dab0cfe..d13853c 100644 --- a/common-api/pom.xml +++ b/common-api/pom.xml @@ -23,7 +23,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 bungeeipc-common-api @@ -36,7 +36,7 @@ org.jetbrains annotations - 23.0.0 + 23.1.0 compile diff --git a/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/AbstractIPCMessage.java b/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/AbstractIPCMessage.java index 90bdfb4..e711965 100644 --- a/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/AbstractIPCMessage.java +++ b/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/AbstractIPCMessage.java @@ -19,13 +19,13 @@ package org.bspfsystems.bungeeipc.api.common; +import java.io.DataOutputStream; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; import java.util.Queue; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * An abstract implementation of an {@link IPCMessage}. @@ -39,17 +39,22 @@ public abstract class AbstractIPCMessage implements IPCMessage { private final String channel; private final Queue data; + private int length; + /** * Constructs a new {@link IPCMessage} containing no data. * * @param origin The origin {@link IPCSocket}. * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) * @throws IllegalArgumentException If {@code origin}, {@code destination}, * and/or {@code channel} are blank. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) */ - protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException { + protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException, IllegalStateException { this(origin, destination, channel, new ArrayList()); } @@ -62,13 +67,16 @@ protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link List}. Order will be maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) * @throws IllegalArgumentException If {@code origin}, {@code destination}, * and/or {@code channel} are blank, or if * any element in {@code data} is * {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) */ - protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException { + protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException, IllegalStateException { this(origin, destination, channel, (Queue) new LinkedList(data)); } @@ -86,13 +94,27 @@ protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String * and/or {@code channel} are blank, or if * any element in {@code data} is * {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. */ protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) throws IllegalArgumentException { - AbstractIPCMessage.validateNotBlank(origin, "IPCMessage origin cannot be blank."); - AbstractIPCMessage.validateNotBlank(destination, "IPCMessage destination cannot be blank."); - AbstractIPCMessage.validateNotBlank(channel, "IPCMessage channel cannot be blank."); - AbstractIPCMessage.validateNotNull(data, "IPC data cannot have null entries: " + data); + if (origin.trim().isEmpty()) { + throw new IllegalArgumentException("IPCMessage origin cannot be blank."); + } + if (destination.trim().isEmpty()) { + throw new IllegalArgumentException("IPCMessage destination cannot be blank."); + } + if (channel.trim().isEmpty()) { + throw new IllegalArgumentException("IPCMessage channel cannot be blank."); + } + + for (final String item : data) { + if (item == null) { + throw new IllegalArgumentException("IPCMessage data cannot have null items."); + } + } if (origin.equals(IPCMessage.BROADCAST_SERVER)) { throw new IllegalArgumentException("IPCMessage origin cannot be the broadcast server."); @@ -106,7 +128,15 @@ protected AbstractIPCMessage(@NotNull final String origin, @NotNull final String this.channel = channel; this.data = data; - this.validateDataLength(null); + this.length = this.getLength(this.origin); + this.length += this.getLength(this.destination); + this.length += this.getLength(this.channel); + + for (final String item : this.data) { + this.length += this.addLength(item); + } + + this.checkLength(0); } /** @@ -140,9 +170,39 @@ public final String getChannel() { * {@inheritDoc} */ @Override - public final void add(@NotNull final String message) throws IllegalArgumentException { - this.validateDataLength(message); - this.data.offer(message); + public final void add(@NotNull final String data) throws IllegalStateException { + + final int length = this.addLength(data); + this.checkLength(length); + + this.length += length; + this.data.offer(data); + } + + /** + * {@inheritDoc} + */ + @Override + public final void add(@NotNull final List data) throws IllegalStateException { + this.add((Queue) new LinkedList(data)); + } + + /** + * {@inheritDoc} + */ + @Override + public final void add(@NotNull final Queue data) throws IllegalStateException { + + int length = 0; + for (final String item : data) { + length += this.addLength(item); + } + this.checkLength(length); + + this.length += length; + for (final String item : data) { + this.data.offer(item); + } } /** @@ -159,11 +219,11 @@ public final boolean hasNext() { @Override @NotNull public final String next() throws NoSuchElementException { - final String message = this.data.poll(); - if (message == null) { + final String data = this.data.poll(); + if (data == null) { throw new NoSuchElementException(); } - return message; + return data; } /** @@ -195,78 +255,68 @@ public final String toString() { } /** - * Checks the length of the data contained {@link String} generated by the - * {@link IPCMessage#write()} method. If the length is larger than 65535, - * this {@link IPCMessage} will not be able to be sent. + * Gets the length of the given {@link String} via the same methods as + * {@code DataOutputStream#writeUTF(String, DataOutput)}. * - * @param message If not {@code null}, the message will be calculated along - * with the data already in this {@link IPCMessage}, as if - * the message was part of this {@link IPCMessage}. If it is - * {@code null}, only the data currently in this - * {@link IPCMessage} will be checked. - * @throws IllegalArgumentException If the length of the data contained in - * this {@link IPCMessage} is too long. + * @param string The {@link String} to get the length of. + * @return The length of the {@link String}. */ - private void validateDataLength(@Nullable final String message) throws IllegalArgumentException { + private int getLength(@NotNull final String string) { - final StringBuilder builder = new StringBuilder(); - builder.append(this.write()); - if (message != null) { - builder.append(AbstractIPCMessage.SEPARATOR).append(message); - } - - final String data = builder.toString(); - - // This is from DataOutputStream#writeUTF(String, DataOutput) - final int length = data.length(); - int checkLength = 0; - int c = 0; + final int stringLength = string.length(); + int length = stringLength; - for (int index = 0; index < length; index++) { - c = data.charAt(index); - if ((c >= 0x0001) && (c <= 0x007F)) { - checkLength++; - } else if (c > 0x07FF) { - checkLength += 3; - } else { - checkLength += 2; + for (int index = 0; index < stringLength; index++) { + final char c = string.charAt(index); + if (c >= 0x80 || c == 0) { + length += (c >= 0x800) ? 2 : 1; } } - if (checkLength > 65535) { - throw new IllegalArgumentException("Encoded IPCMessage is too long: " + checkLength + " bytes."); - } + return length; } /** - * Validates that the given {@link String value} is not empty (or only - * whitespace). + * Gets the length of the given {@link String} added to the length of + * {@link AbstractIPCMessage#SEPARATOR}. This uses the same methods as + * {@code DataOutputStream#writeUTF(String, DataOutput)} to calculate the + * length. * - * @param value The {@link String value} to check for being blank. - * @param message The error message to display if the value is blank. - * @throws IllegalArgumentException If the given value is blank. + * @param string The {@link String} to get the length of. + * @return The length of the {@link String} combined with the length of + * {@link AbstractIPCMessage#SEPARATOR}. */ - protected static void validateNotBlank(@NotNull final String value, @NotNull final String message) throws IllegalArgumentException { - if (value.trim().isEmpty()) { - throw new IllegalArgumentException(message); + + private int addLength(@NotNull final String string) { + + final String fullString = AbstractIPCMessage.SEPARATOR + string; + final int stringLength = fullString.length(); + int length = stringLength; + + for (int index = 0; index < stringLength; index++) { + final char c = fullString.charAt(index); + if (c >= 0x80 || c == 0) { + length += (c >= 0x800) ? 2 : 1; + } } + + return length; } /** - * Validates that the given {@link Queue} has no data in it that is - * {@code null}. + * Checks the length of this {@link IPCMessage} added to the given length. + * If the total is too long (greater than 65535), then it will throw an + * {@link IllegalStateException}, as this {@link IPCMessage} cannot be sent + * via a {@link DataOutputStream} when its length is greater than that. * - * @param data The {@link Queue} of data to check. - * @param message The error message to display if the given {@link Queue} - * has {@code null} data in it. - * @throws IllegalArgumentException If the given {@link Queue} has - * {@code null} data in it. + * @param length The additional length to check. + * @throws IllegalStateException If the current length of this + * {@link IPCMessage} added to the given + * length is greater than 65535. */ - private static void validateNotNull(@NotNull final Queue data, @NotNull final String message) throws IllegalArgumentException { - for (final String item : data) { - if (item == null) { - throw new IllegalArgumentException(message); - } + private void checkLength(final int length) throws IllegalStateException { + if (this.length + length > 65535) { + throw new IllegalStateException("IPCMessage is too long."); } } } diff --git a/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/IPCMessage.java b/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/IPCMessage.java index 028d90c..35b6afa 100644 --- a/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/IPCMessage.java +++ b/common-api/src/main/java/org/bspfsystems/bungeeipc/api/common/IPCMessage.java @@ -19,6 +19,8 @@ package org.bspfsystems.bungeeipc.api.common; +import java.io.DataOutputStream; +import java.util.List; import java.util.NoSuchElementException; import java.util.Queue; import org.jetbrains.annotations.NotNull; @@ -82,13 +84,53 @@ public interface IPCMessage { /** * Adds the next message to this {@link IPCMessage}. + *

+ * An {@link IllegalStateException} will be thrown if the additional data + * pushes the total length of this {@link IPCMessage} beyond its maximum + * allowable number of bytes to be processed. See + * {@code DataOutputStream#writeUTF(String, DataOutput)} for more + * information. + * + * @param data The next message to add to this {@link IPCMessage}. + * @throws IllegalStateException If adding the given message causes this + * {@link IPCMessage} to be too long to be + * sent via a {@link DataOutputStream}. + */ + void add(@NotNull final String data) throws IllegalStateException; + + /** + * Adds the next messages to this {@link IPCMessage}. + *

+ * An {@link IllegalStateException} will be thrown if the additional data + * pushes the total length of this {@link IPCMessage} beyond its maximum + * allowable number of bytes to be processed. See + * {@code DataOutputStream#writeUTF(String, DataOutput)} for more + * information. + * + * @param data The {@link List} of messages to add to this + * {@link IPCMessage}. + * @throws IllegalStateException If adding the given messages causes this + * {@link IPCMessage} to be too long to be + * sent via a {@link DataOutputStream}. + */ + void add(@NotNull final List data) throws IllegalStateException; + + /** + * Adds the next messages to this {@link IPCMessage}. + *

+ * An {@link IllegalStateException} will be thrown if the additional data + * pushes the total length of this {@link IPCMessage} beyond its maximum + * allowable number of bytes to be processed. See + * {@code DataOutputStream#writeUTF(String, DataOutput)} for more + * information. * - * @param message The next message to add to this {@link IPCMessage}. - * @throws IllegalArgumentException If adding the message to this - * {@link IPCMessage} would make it too - * long to be sent. + * @param data The {@link Queue} of messages to add to this + * {@link IPCMessage}. + * @throws IllegalStateException If adding the given messages causes this + * {@link IPCMessage} to be too long to be + * sent via a {@link DataOutputStream}. */ - void add(@NotNull final String message) throws IllegalArgumentException; + void add(@NotNull final Queue data) throws IllegalStateException; /** * Checks to see if there is any remaining data to be read. diff --git a/pom.xml b/pom.xml index cd48c0e..248418a 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 pom BungeeIPC @@ -178,7 +178,7 @@ maven-deploy-plugin 3.0.0 - true + false diff --git a/server-api/pom.xml b/server-api/pom.xml index 6edd95b..5d32e6f 100644 --- a/server-api/pom.xml +++ b/server-api/pom.xml @@ -23,7 +23,7 @@ org.bspfsystems.bungeeipc bungeeipc-parent - 3.0.4 + 3.1.0 bungeeipc-server-api @@ -36,13 +36,13 @@ org.bspfsystems.bungeeipc bungeeipc-common-api - 3.0.4 + 3.1.0 compile org.jetbrains annotations - 23.0.0 + 23.1.0 provided diff --git a/server-api/src/main/java/org/bspfsystems/bungeeipc/api/server/ServerIPCMessage.java b/server-api/src/main/java/org/bspfsystems/bungeeipc/api/server/ServerIPCMessage.java index 71bc63f..eead747 100644 --- a/server-api/src/main/java/org/bspfsystems/bungeeipc/api/server/ServerIPCMessage.java +++ b/server-api/src/main/java/org/bspfsystems/bungeeipc/api/server/ServerIPCMessage.java @@ -37,11 +37,14 @@ public final class ServerIPCMessage extends AbstractIPCMessage { * * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String) */ - public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException { + public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PROXY_SERVER, destination, channel); } @@ -53,12 +56,15 @@ public ServerIPCMessage(@NotNull final String destination, @NotNull final String * @param destination The destination {@link IPCSocket}. * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link List}. Order will be maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank, or if any * element in {@code data} is {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, List) */ - public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException { + public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final List data) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PROXY_SERVER, destination, channel, data); } @@ -71,12 +77,15 @@ public ServerIPCMessage(@NotNull final String destination, @NotNull final String * @param channel The channel the {@link IPCMessage} will be read by. * @param data The initial data as a {@link Queue}. Order will be * maintained. - * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) * @throws IllegalArgumentException If {@code destination} and/or * {@code channel} are blank, or if any * element in {@code data} is {@code null}. + * @throws IllegalStateException If the given parameters contain too much + * data to send in a single + * {@link IPCMessage}. + * @see AbstractIPCMessage#AbstractIPCMessage(String, String, String, Queue) */ - public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) throws IllegalArgumentException { + public ServerIPCMessage(@NotNull final String destination, @NotNull final String channel, @NotNull final Queue data) throws IllegalArgumentException, IllegalStateException { super(IPCMessage.PROXY_SERVER, destination, channel, data); } }