From ac1ff26365a7519da966ca3a903a423f8e6c9b5d Mon Sep 17 00:00:00 2001 From: rjenkinsjr Date: Mon, 28 Mar 2016 19:58:32 -0400 Subject: [PATCH] Improve Javadocs and initialization routine --- .../slf4j/impl/BukkitPluginLoggerAdapter.java | 155 ++++++++++-------- 1 file changed, 89 insertions(+), 66 deletions(-) diff --git a/src/main/java/org/slf4j/impl/BukkitPluginLoggerAdapter.java b/src/main/java/org/slf4j/impl/BukkitPluginLoggerAdapter.java index f35153a..31f8b80 100644 --- a/src/main/java/org/slf4j/impl/BukkitPluginLoggerAdapter.java +++ b/src/main/java/org/slf4j/impl/BukkitPluginLoggerAdapter.java @@ -66,62 +66,92 @@ import org.yaml.snakeyaml.Yaml; /** *

* A merger of SLF4J's {@code SimpleLogger} and {@code JDK14LoggerAdapter}, - * wired to log all messages to the Bukkit plugin found in this class's - * classloader (by way of reading plugin.yml). + * wired to log all messages to the enclosing Bukkit plugin. The plugin is + * identified by reading the "name" attribute from {@code plugin.yml} in the + * current classloader. *

* *

- * SLF4J messages at level {@code TRACE} or {@code DEBUG} are logged to Bukkit - * at level {@link Level#INFO} because Bukkit does not enable any levels higher - * than {@code INFO}. Therefore, only SLF4J messages at level {@code TRACE} or - * {@code DEBUG} show their SLF4J level in the message that is logged to the - * server console. - *

- * - *

- * Plugins that shade SLF4Bukkit can use the following values in config.yml to - * configure the behavior of this logger: + * Plugins that include SLF4Bukkit can use the following values in + * {@code config.yml} to configure the behavior of SLF4Bukkit. SLF4Bukkit uses + * Bukkit's plugin configuration API to retrieve config values, so both on-disk + * and built-in {@code config.yml} behavior is supported. *

* * * *

- * Because SLF4Bukkit's configuration comes from the plugin configuration, - * SLF4Bukkit supports configuration reloading (assuming the containing plugin - * supports config reloading). To achieve this, call {@link #init()} after - * calling {@link Plugin#reloadConfig()}. + * SLF4J messages at level {@code TRACE} or {@code DEBUG} are logged to Bukkit + * at level {@code INFO} because Bukkit does not enable any levels higher than + * {@code INFO}. Therefore, only SLF4J messages at level {@code TRACE} or + * {@code DEBUG} show their SLF4J level in the message that is logged to the + * server console. *

* *

- * With no configuration, the default output includes the thread name, the SLF4J - * level (only if it differs from the Bukkit level; see above), logger name, and - * the message followed by the line separator for the host. + * Because SLF4Bukkit's configuration comes from the plugin configuration, + * SLF4Bukkit supports configuration reloading. To achieve this, call + * {@link #init()} with argument {@code true} after calling + * {@link Plugin#reloadConfig()}. + *

+ * + *

+ * It is possible for SLF4J loggers to be used before the plugin is registered + * with Bukkit's plugin manager. SLF4Bukkit is considered to be + * uninitialized as long as the plugin cannot be retrieved from Bukkit's + * plugin manager. While in the uninitialized state, SLF4Bukkit: + *

+ * + * + * + *

+ * For this reason, it is strongly recommended that you not emit any log + * messages via SLF4Bukkit until your plugin's {@link Plugin#onLoad() onLoad()} + * method has begun execution. (You can safely log messages inside the + * {@code onLoad()} method, because your plugin is registered by that time.) + * Logging inside static initializers, the plugin class constructor and other + * pre-plugin-registration areas of your code is discouraged. + *

+ * + *

+ * With no configuration, the default output includes the logger short name and + * the message, followed by the line separator for the host. *

* * @author Ceki Gülcü @@ -138,6 +168,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase // Plugin reference. private static transient Plugin BUKKIT_PLUGIN; + private static transient String BUKKIT_PLUGIN_NAME; // Constants for JUL record creation. private static final String CLASS_SELF = BukkitPluginLoggerAdapter.class.getName(); private static final String CLASS_SUPER = MarkerIgnoringBase.class.getName(); @@ -158,8 +189,6 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase private static boolean CONFIG_SHOW_LOG_NAME; private static boolean CONFIG_SHOW_SHORT_LOG_NAME; private static boolean CONFIG_SHOW_THREAD_NAME; - // Initialization status. - private static boolean INIT_FAILURE_WARNED = false; // Initialization lock. private static final Object INITIALIZATION_LOCK = new Object(); // Logging level constants. @@ -189,7 +218,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase /** * (Re)initializes all SLF4Bukkit loggers, relying on the YAML configuration - * of the containing plugin. + * of the enclosing plugin. * * @param reinitialize * set to {@code true} to reinitialize all loggers, e.g. after @@ -200,43 +229,37 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase // Do not re-initialize unless requested. if (reinitialize) { BukkitPluginLoggerAdapter.BUKKIT_PLUGIN = null; + BUKKIT_PLUGIN_NAME = null; } else if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN != null) { return; } // Get a reference to the plugin in this classloader. - InputStream pluginYmlFile = null; - String pluginName; - try { - pluginYmlFile = BukkitPluginLoggerAdapter.class.getClassLoader() - .getResource("plugin.yml") - .openStream(); - final Yaml yaml = new Yaml(); - @SuppressWarnings("rawtypes") - final Map pluginYml = (Map) yaml.load(pluginYmlFile); - pluginName = (String) pluginYml.get("name"); - } catch (final IOException e) { - throw new IllegalStateException(e); - } finally { - if (pluginYmlFile != null) { - try { - pluginYmlFile.close(); - } catch (final IOException e) { - e.printStackTrace(); + if (BUKKIT_PLUGIN_NAME == null) { + InputStream pluginYmlFile = null; + try { + pluginYmlFile = BukkitPluginLoggerAdapter.class.getClassLoader() + .getResource("plugin.yml") + .openStream(); + final Yaml yaml = new Yaml(); + @SuppressWarnings("rawtypes") + final Map pluginYml = (Map) yaml.load(pluginYmlFile); + BUKKIT_PLUGIN_NAME = (String) pluginYml.get("name"); + } catch (final IOException e) { + throw new IllegalStateException(e); + } finally { + if (pluginYmlFile != null) { + try { + pluginYmlFile.close(); + } catch (final IOException e) { + e.printStackTrace(); + } } } } - // Get the plugin. + // Try to get the plugin. The logging system will be considered + // uninitialized until this becomes non-null. While it is null, the Bukkit + // server logger will be used instead of the plugin logger, and all + // default configuration options will be used. BukkitPluginLoggerAdapter.BUKKIT_PLUGIN = Bukkit.getPluginManager() - .getPlugin(pluginName); - if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN == null) { - // Initialization failed. - if (!BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED) { - System.err.println("WARN: SLF4Bukkit could not be initialized for plugin " - + pluginName + "; default configuration assumed!"); - } - BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED = true; - } else { - // Initialization successful. - BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED = false; - } + .getPlugin(BUKKIT_PLUGIN_NAME); // Get the configuration values. // 1. Look in the plugin's on-disk config. // 2. If the value is absent, use the plugin's built-in config.