From 34b7cef2c96152433da6f380656baf9d27c9579a Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Fri, 20 Nov 2015 23:10:19 +0000
Subject: [PATCH] OPENDJ-2441, OPENDJ-2443: Make sure extensions can be loaded from both install and instance directories, includes a little bit of refactoring and code cleanup

---
 opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties           |    2 
 opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties           |    2 
 opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties  |    4 
 opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties           |    2 
 opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java |  389 ++++++++++---------------------
 opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java |  278 ++++++++--------------
 opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties           |    2 
 opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties           |    2 
 opendj-server-legacy/src/messages/org/opends/messages/admin.properties              |    2 
 9 files changed, 236 insertions(+), 447 deletions(-)

diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java b/opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java
index c58e5b1..6560458 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java
@@ -44,6 +44,8 @@
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -57,7 +59,6 @@
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.config.server.ConfigException;
 import org.forgerock.opendj.server.config.meta.RootCfgDefn;
-import org.forgerock.util.Reject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,24 +69,20 @@
  * <ul>
  * <li>loading core components during application initialization
  * <li>loading extensions during and after application initialization
- * <li>changing the property validation strategy based on whether the
- * application is a client or server.
+ * <li>changing the property validation strategy based on whether the application is a client or server.
  * </ul>
  * This class defines a class loader which will be used for loading components.
- * For extensions which define their own extended configuration definitions, the
- * class loader will make sure that the configuration definition classes are
- * loaded and initialized.
+ * For extensions which define their own extended configuration definitions, the class loader
+ * will make sure that the configuration definition classes are loaded and initialized.
  * <p>
- * Initially the configuration framework is disabled, and calls to the
- * {@link #getClassLoader()} will return the system default class loader.
+ * Initially the configuration framework is disabled, and calls to the {@link #getClassLoader()}
+ * will return the system default class loader.
  * <p>
- * Applications <b>MUST NOT</b> maintain persistent references to the class
- * loader as it can change at run-time.
+ * Applications <b>MUST NOT</b> maintain persistent references to the class loader as it can change at run-time.
  */
 public final class ConfigurationFramework {
     /**
-     * Private URLClassLoader implementation. This is only required so that we
-     * can provide access to the addURL method.
+     * Private URLClassLoader implementation. This is only required so that we can provide access to the addURL method.
      */
     private static final class MyURLClassLoader extends URLClassLoader {
 
@@ -143,8 +140,7 @@
     private static final String REVISION_NUMBER = "Revision-Number";
 
     /**
-     * The attribute names for build information is name, version and revision
-     * number.
+     * The attribute names for build information is name, version and revision number.
      */
     private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES = new String[] {
         Attributes.Name.EXTENSION_NAME.toString(),
@@ -163,8 +159,7 @@
     private Set<File> jarFiles = new HashSet<>();
 
     /**
-     * Underlying class loader used to load classes and resources (null
-     * if disabled).
+     * Underlying class loader used to load classes and resources (null if disabled).
      * <p>
      * We contain a reference to the URLClassLoader rather than
      * sub-class it so that it is possible to replace the loader at
@@ -184,58 +179,12 @@
     }
 
     /**
-     * Loads the named extensions into the configuration framework.
-     *
-     * @param extensions
-     *            The names of the extensions to be loaded. The names should not
-     *            contain any path elements and must be located within the
-     *            extensions folder.
-     * @throws ConfigException
-     *             If one of the extensions could not be loaded and initialized.
-     * @throws IllegalStateException
-     *             If the configuration framework has not yet been initialized.
-     * @throws IllegalArgumentException
-     *             If one of the extension names was not a single relative path
-     *             name element or was an absolute path.
-     */
-    public synchronized void addExtension(final String... extensions) throws ConfigException {
-        Reject.ifNull(extensions);
-        ensureInitialized();
-
-        final File libPath = new File(instancePath, LIB_DIR);
-        final File extensionsPath = new File(libPath, EXTENSIONS_DIR);
-
-        final ArrayList<File> files = new ArrayList<>(extensions.length);
-        for (final String extension : extensions) {
-            final File file = new File(extensionsPath, extension);
-
-            // For security reasons we need to make sure that the file name
-            // passed in did not contain any path elements and names a file
-            // in the extensions folder.
-
-            // Can handle potential null parent.
-            if (!extensionsPath.equals(file.getParentFile())) {
-                throw new IllegalArgumentException("Illegal file name: " + extension);
-            }
-
-            // The file is valid.
-            files.add(file);
-        }
-
-        // Add the extensions.
-        addExtension(files.toArray(new File[files.size()]));
-    }
-
-    /**
-     * Returns the class loader which should be used for loading classes and
-     * resources. When this configuration framework is disabled, the system
-     * default class loader will be returned by default.
+     * Returns the class loader which should be used for loading classes and resources. When this configuration
+     * framework is disabled, the system default class loader will be returned by default.
      * <p>
-     * Applications <b>MUST NOT</b> maintain persistent references to the class
-     * loader as it can change at run-time.
+     * Applications <b>MUST NOT</b> maintain persistent references to the class loader as it can change at run-time.
      *
-     * @return Returns the class loader which should be used for loading classes
-     *         and resources.
+     * @return Returns the class loader which should be used for loading classes and resources.
      */
     public synchronized ClassLoader getClassLoader() {
         if (loader != null) {
@@ -246,14 +195,12 @@
     }
 
     /**
-     * Initializes the configuration framework using the application's class
-     * loader as the parent class loader, and the current working directory as
-     * the install and instance path.
+     * Initializes the configuration framework using the application's class loader as the parent class loader,
+     * and the current working directory as the install and instance path.
      *
      * @return The configuration framework.
      * @throws ConfigException
-     *             If the configuration framework could not initialize
-     *             successfully.
+     *             If the configuration framework could not initialize successfully.
      * @throws IllegalStateException
      *             If the configuration framework has already been initialized.
      */
@@ -262,16 +209,14 @@
     }
 
     /**
-     * Initializes the configuration framework using the application's class
-     * loader as the parent class loader, and the provided install/instance
-     * path.
+     * Initializes the configuration framework using the application's class loader
+     * as the parent class loader, and the provided install/instance path.
      *
      * @param installAndInstancePath
      *            The path where application binaries and data are located.
      * @return The configuration framework.
      * @throws ConfigException
-     *             If the configuration framework could not initialize
-     *             successfully.
+     *             If the configuration framework could not initialize successfully.
      * @throws IllegalStateException
      *             If the configuration framework has already been initialized.
      */
@@ -281,9 +226,8 @@
     }
 
     /**
-     * Initializes the configuration framework using the application's class
-     * loader as the parent class loader, and the provided install and instance
-     * paths.
+     * Initializes the configuration framework using the application's class loader
+     * as the parent class loader, and the provided install and instance paths.
      *
      * @param installPath
      *            The path where application binaries are located.
@@ -291,8 +235,7 @@
      *            The path where application data are located.
      * @return The configuration framework.
      * @throws ConfigException
-     *             If the configuration framework could not initialize
-     *             successfully.
+     *             If the configuration framework could not initialize successfully.
      * @throws IllegalStateException
      *             If the configuration framework has already been initialized.
      */
@@ -313,8 +256,7 @@
      *            The parent class loader.
      * @return The configuration framework.
      * @throws ConfigException
-     *             If the configuration framework could not initialize
-     *             successfully.
+     *             If the configuration framework could not initialize successfully.
      * @throws IllegalStateException
      *             If the configuration framework has already been initialized.
      */
@@ -341,8 +283,7 @@
      * value validation than server applications because they do not have
      * resources available such as the server schema.
      *
-     * @return {@code true} if the configuration framework is being used within
-     *         a client application.
+     * @return {@code true} if the configuration framework is being used within a client application.
      */
     public boolean isClient() {
         return isClient;
@@ -364,23 +305,20 @@
      *         <code>null</code> if there is no information available.
      */
     public String printExtensionInformation() {
-        final File extensionsPath =
-                new File(installPath + File.separator + LIB_DIR + File.separator + EXTENSIONS_DIR);
+        final File extensionsPath = buildExtensionPath(installPath);
 
-        if (!extensionsPath.exists() || !extensionsPath.isDirectory()) {
-            // no extensions' directory
-            return null;
+        final List<File> extensions = new ArrayList<>();
+
+        if (extensionsPath.exists() && extensionsPath.isDirectory()) {
+            extensions.addAll(listFiles(extensionsPath));
         }
 
-        final File[] extensions = extensionsPath.listFiles(new FileFilter() {
-            @Override
-            public boolean accept(final File pathname) {
-                // only files with names ending with ".jar"
-                return pathname.isFile() && pathname.getName().endsWith(".jar");
-            }
-        });
+        File instanceExtensionsPath = buildExtensionPath(instancePath);
+        if (!extensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
+            extensions.addAll(listFiles(instanceExtensionsPath));
+        }
 
-        if (extensions.length == 0) {
+        if (extensions.isEmpty()) {
             return null;
         }
 
@@ -390,47 +328,47 @@
         // --
         // Name Build number Revision number
         ps.printf("--%s           %-20s %-20s %-20s%s", EOL, "Name", "Build number",
-                "Revision number", EOL);
+            "Revision number", EOL);
 
         for (final File extension : extensions) {
-            // retrieve MANIFEST entry and display name, build number and
-            // revision number
-            try {
-                final JarFile jarFile = new JarFile(extension);
-                final JarEntry entry = jarFile.getJarEntry(MANIFEST);
-                if (entry == null) {
-                    continue;
-                }
-
-                final String[] information = getBuildInformation(jarFile);
-
-                ps.append("Extension: ");
-                boolean addBlank = false;
-                for (final String name : information) {
-                    if (addBlank) {
-                        ps.append(addBlank ? " " : ""); // add blank if not
-                                                        // first append
-                    } else {
-                        addBlank = true;
-                    }
-
-                    ps.printf("%-20s", name);
-                }
-                ps.append(EOL);
-            } catch (final Exception e) {
-                // ignore extra information for this extension
-            }
+            printExtensionDetails(ps, extension);
         }
 
         return baos.toString();
     }
 
+    private void printExtensionDetails(PrintStream ps, File extension) {
+        // retrieve MANIFEST entry and display name, build number and revision number
+        try {
+            JarFile jarFile = new JarFile(extension);
+            JarEntry entry = jarFile.getJarEntry(MANIFEST);
+            if (entry == null) {
+                return;
+            }
+
+            String[] information = getBuildInformation(jarFile);
+
+            ps.append("Extension: ");
+            boolean addBlank = false;
+            for (String name : information) {
+                if (addBlank) {
+                    ps.append(" ");
+                } else {
+                    addBlank = true;
+                }
+                ps.printf("%-20s", name);
+            }
+            ps.append(EOL);
+        } catch (Exception e) {
+            // ignore extra information for this extension
+        }
+    }
+
     /**
      * Reloads the configuration framework.
      *
      * @throws ConfigException
-     *             If the configuration framework could not initialize
-     *             successfully.
+     *             If the configuration framework could not initialize successfully.
      * @throws IllegalStateException
      *             If the configuration framework has not yet been initialized.
      */
@@ -448,8 +386,7 @@
      * resources available such as the server schema.
      *
      * @param isClient
-     *            {@code true} if the configuration framework is being used
-     *            within a client application.
+     *            {@code true} if the configuration framework is being used within a client application.
      * @return The configuration framework.
      */
     public ConfigurationFramework setIsClient(final boolean isClient) {
@@ -457,7 +394,7 @@
         return this;
     }
 
-    private void addExtension(final File... extensions) throws ConfigException {
+    private void addExtension(final List<File> extensions) throws ConfigException {
         // First add the Jar files to the class loader.
         final List<JarFile> jars = new LinkedList<>();
         for (final File extension : extensions) {
@@ -502,8 +439,8 @@
      *
      * @param extension
      *            the jar file of the extension
-     * @return a String array containing the name, the build number and the
-     *         revision number of the extension given in argument
+     * @return a String array containing the name, the build number and the revision number
+     *            of the extension given in argument
      * @throws java.io.IOException
      *             thrown if the jar file has been closed.
      */
@@ -536,40 +473,32 @@
             loader = new MyURLClassLoader();
         }
 
-        // Forcefully load all configuration definition classes in
-        // OpenDS.jar.
+        // Forcefully load all configuration definition classes in OpenDS.jar.
         initializeCoreComponents();
 
         // Put extensions jars into the class loader and load all
         // configuration definition classes in that they contain.
         // First load the extension from the install directory, then
         // from the instance directory.
-        File libDir;
-        File installExtensionsPath;
-        File instanceExtensionsPath;
+        File installExtensionsPath  = buildExtensionPath(installPath);
+        File instanceExtensionsPath = buildExtensionPath(instancePath);
 
-        // load install dir extension
-        libDir = new File(installPath, LIB_DIR);
-        try {
-            installExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-        } catch (final Exception e) {
-            installExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-        }
         initializeAllExtensions(installExtensionsPath);
 
-        // load instance dir extension
-        libDir = new File(instancePath, LIB_DIR);
-        try {
-            instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-        } catch (final Exception e) {
-            instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-        }
-        if (!installExtensionsPath.getAbsolutePath().equals(
-                instanceExtensionsPath.getAbsolutePath())) {
+        if (!installExtensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
             initializeAllExtensions(instanceExtensionsPath);
         }
     }
 
+    private File buildExtensionPath(String directory)  {
+        File libDir = new File(directory, LIB_DIR);
+        try {
+            return new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
+        } catch (Exception e) {
+            return new File(libDir, EXTENSIONS_DIR);
+        }
+    }
+
     /**
      * Put extensions jars into the class loader and load all configuration
      * definition classes in that they contain.
@@ -584,40 +513,20 @@
     private void initializeAllExtensions(final File extensionsPath) throws ConfigException {
         try {
             if (!extensionsPath.exists()) {
-                // The extensions directory does not exist. This is not a
-                // critical problem.
-                adminLogger.error(ERR_ADMIN_NO_EXTENSIONS_DIR, String.valueOf(extensionsPath));
+                // The extensions directory does not exist. This is not a critical problem.
+                adminLogger.warn(WARN_ADMIN_NO_EXTENSIONS_DIR, String.valueOf(extensionsPath));
                 return;
             }
 
             if (!extensionsPath.isDirectory()) {
-                // The extensions directory is not a directory. This is more
-                // critical.
+                // The extensions directory is not a directory. This is more critical.
                 final LocalizableMessage message =
                         ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(String.valueOf(extensionsPath));
                 throw new ConfigException(message);
             }
 
-            // Get each extension file name.
-            final FileFilter filter = new FileFilter() {
-
-                /**
-                 * Must be a Jar file.
-                 */
-                @Override
-                public boolean accept(final File pathname) {
-                    if (!pathname.isFile()) {
-                        return false;
-                    }
-
-                    final String name = pathname.getName();
-                    return name.endsWith(".jar");
-                }
-
-            };
-
             // Add and initialize the extensions.
-            addExtension(extensionsPath.listFiles(filter));
+            addExtension(listFiles(extensionsPath));
         } catch (final ConfigException e) {
             debugLogger.trace("Unable to initialize all extensions", e);
             throw e;
@@ -630,6 +539,19 @@
         }
     }
 
+    private List<File> listFiles(File path) {
+        if (path.exists() && path.isDirectory()) {
+
+            return Arrays.asList(path.listFiles(new FileFilter() {
+                public boolean accept(File pathname) {
+                    // only files with names ending with ".jar"
+                    return pathname.isFile() && pathname.getName().endsWith(".jar");
+                }
+            }));
+        }
+        return Collections.emptyList();
+    }
+
     /**
      * Make sure all core configuration definitions are loaded.
      *
diff --git a/opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties b/opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties
index cfbf05d..b749871 100644
--- a/opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties
+++ b/opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=The Directory Server jar file %s in \
  directory %s cannot be loaded because an unexpected error occurred while \
  trying to open the file for reading:  %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
  exist, therefore no extensions will be loaded
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Unable to read the Directory \
  Server extensions because the extensions directory %s exists but is not a \
@@ -281,4 +281,4 @@
 WARN_ADMIN_SET_PERMISSIONS_FAILED_137=Failed to set permissions \
  on file %s
 ERR_ADMIN_MERGING_138=The registry information of the servers could not \
- be merged
\ No newline at end of file
+ be merged
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java b/opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
index fc996e3..c95d123 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
@@ -45,11 +45,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -60,37 +56,29 @@
 import org.opends.server.core.DirectoryServer;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.opends.server.types.InitializationException;
-import org.forgerock.util.Reject;
-
 
 
 /**
- * Manages the class loader which should be used for loading
- * configuration definition classes and associated extensions.
+ * Manages the class loader which should be used for loading configuration definition classes and associated extensions.
  * <p>
- * For extensions which define their own extended configuration
- * definitions, the class loader will make sure that the configuration
- * definition classes are loaded and initialized.
+ * For extensions which define their own extended configuration definitions, the class loader will make sure
+ * that the configuration definition classes are loaded and initialized.
  * <p>
- * Initially the class loader provider is disabled, and calls to the
- * {@link #getClassLoader()} will return the system default class
- * loader.
+ * Initially the class loader provider is disabled, and calls to the {@link #getClassLoader()} will return
+ * the system default class loader.
  * <p>
- * Applications <b>MUST NOT</b> maintain persistent references to the
- * class loader as it can change at run-time.
+ * Applications <b>MUST NOT</b> maintain persistent references to the class loader as it can change at run-time.
  */
 public final class ClassLoaderProvider {
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
   /**
-   * Private URLClassLoader implementation. This is only required so
-   * that we can provide access to the addURL method.
+   * Private URLClassLoader implementation.
+   * This is only required so that we can provide access to the addURL method.
    */
   private static final class MyURLClassLoader extends URLClassLoader {
 
-    /**
-     * Create a class loader with the default parent class loader.
-     */
+    /** Create a class loader with the default parent class loader. */
     public MyURLClassLoader() {
       super(new URL[0]);
     }
@@ -115,30 +103,21 @@
      * @param jarFile
      *          The name of the Jar file.
      * @throws MalformedURLException
-     *           If a protocol handler for the URL could not be found,
-     *           or if some other error occurred while constructing
-     *           the URL.
+     *           If a protocol handler for the URL could not be found, or if some other error occurred
+     *           while constructing the URL.
      * @throws SecurityException
-     *           If a required system property value cannot be
-     *           accessed.
+     *           If a required system property value cannot be accessed.
      */
-    public void addJarFile(File jarFile) throws SecurityException,
-        MalformedURLException {
+    public void addJarFile(File jarFile) throws SecurityException, MalformedURLException {
       addURL(jarFile.toURI().toURL());
     }
 
   }
 
-  /**
-   * The name of the manifest file listing the core configuration
-   * definition classes.
-   */
+  /** The name of the manifest file listing the core configuration definition classes. */
   private static final String CORE_MANIFEST = "core.manifest";
 
-  /**
-   * The name of the manifest file listing a extension's configuration
-   * definition classes.
-   */
+  /** The name of the manifest file listing a extension's configuration definition classes. */
   private static final String EXTENSION_MANIFEST = "extension.manifest";
 
   /** The name of the lib directory. */
@@ -153,10 +132,7 @@
   /** Attribute name in jar's MANIFEST corresponding to the revision number. */
   private static final String REVISION_NUMBER = "Revision-Number";
 
-  /**
-   * The attribute names for build information is name, version and revision
-   * number.
-   */
+  /** The attribute names for build information is name, version and revision number. */
   private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES =
                  new String[]{Attributes.Name.EXTENSION_NAME.toString(),
                               Attributes.Name.IMPLEMENTATION_VERSION.toString(),
@@ -166,8 +142,7 @@
   /**
    * Get the single application wide class loader provider instance.
    *
-   * @return Returns the single application wide class loader provider
-   *         instance.
+   * @return Returns the single application wide class loader provider instance.
    */
   public static ClassLoaderProvider getInstance() {
     return INSTANCE;
@@ -177,12 +152,10 @@
   private Set<File> jarFiles = new HashSet<>();
 
   /**
-   * Underlying class loader used to load classes and resources (null
-   * if disabled).<br>
-   * We contain a reference to the URLClassLoader rather than
-   * sub-class it so that it is possible to replace the loader at run-time.
-   * For example, when removing or replacing extension Jar files
-   * (the URLClassLoader only supports adding new URLs, not removal).
+   * Underlying class loader used to load classes and resources (null if disabled).<br>
+   * We contain a reference to the URLClassLoader rather than sub-class it so that it is possible to replace the
+   * loader at run-time. For example, when removing or replacing extension Jar files (the URLClassLoader
+   * only supports adding new URLs, not removal).
    */
   private MyURLClassLoader loader;
 
@@ -196,66 +169,13 @@
 
 
   /**
-   * Add the named extensions to this class loader provider.
-   *
-   * @param extensions
-   *          The names of the extensions to be loaded. The names
-   *          should not contain any path elements and must be located
-   *          within the extensions folder.
-   * @throws InitializationException
-   *           If one of the extensions could not be loaded and
-   *           initialized.
-   * @throws IllegalStateException
-   *           If this class loader provider is disabled.
-   * @throws IllegalArgumentException
-   *           If one of the extension names was not a single relative
-   *           path name element or was an absolute path.
-   */
-  public synchronized void addExtension(String... extensions)
-      throws InitializationException, IllegalStateException,
-      IllegalArgumentException {
-    Reject.ifNull(extensions);
-
-    if (loader == null) {
-      throw new IllegalStateException(
-          "Class loader provider is disabled.");
-    }
-
-    File libPath = new File(DirectoryServer.getInstanceRoot(), LIB_DIR);
-    File extensionsPath = new File(libPath, EXTENSIONS_DIR);
-
-    ArrayList<File> files = new ArrayList<>(extensions.length);
-    for (String extension : extensions) {
-      File file = new File(extensionsPath, extension);
-
-      // For security reasons we need to make sure that the file name
-      // passed in did not contain any path elements and names a file
-      // in the extensions folder.
-
-      // Can handle potential null parent.
-      if (!extensionsPath.equals(file.getParentFile())) {
-        throw new IllegalArgumentException("Illegal file name: "
-            + extension);
-      }
-
-      // The file is valid.
-      files.add(file);
-    }
-
-    // Add the extensions.
-    addExtension(files.toArray(new File[files.size()]));
-  }
-
-
-
-  /**
-   * Disable this class loader provider and removed any registered
-   * extensions.
+   * Disable this class loader provider and removed any registered extensions.
    *
    * @throws IllegalStateException
    *           If this class loader provider is already disabled.
    */
-  public synchronized void disable() throws IllegalStateException {
+  public synchronized void disable()
+      throws IllegalStateException {
     if (loader == null) {
       throw new IllegalStateException(
           "Class loader provider already disabled.");
@@ -267,39 +187,34 @@
 
 
   /**
-   * Enable this class loader provider using the application's
-   * class loader as the parent class loader.
+   * Enable this class loader provider using the application's class loader as the parent class loader.
    *
    * @throws InitializationException
-   *           If the class loader provider could not initialize
-   *           successfully.
+   *           If the class loader provider could not initialize successfully.
    * @throws IllegalStateException
    *           If this class loader provider is already enabled.
    */
-  public synchronized void enable() throws InitializationException,
-      IllegalStateException {
+  public synchronized void enable()
+      throws InitializationException, IllegalStateException {
     enable(RootCfgDefn.class.getClassLoader());
   }
 
 
 
   /**
-   * Enable this class loader provider using the provided parent class
-   * loader.
+   * Enable this class loader provider using the provided parent class loader.
    *
    * @param parent
    *          The parent class loader.
    * @throws InitializationException
-   *           If the class loader provider could not initialize
-   *           successfully.
+   *           If the class loader provider could not initialize successfully.
    * @throws IllegalStateException
    *           If this class loader provider is already enabled.
    */
   public synchronized void enable(ClassLoader parent)
       throws InitializationException, IllegalStateException {
     if (loader != null) {
-      throw new IllegalStateException(
-          "Class loader provider already enabled.");
+      throw new IllegalStateException("Class loader provider already enabled.");
     }
 
     if (parent != null) {
@@ -308,62 +223,38 @@
       loader = new MyURLClassLoader();
     }
 
-    // Forcefully load all configuration definition classes in
-    // OpenDS.jar.
+    // Forcefully load all configuration definition classes in OpenDJ.jar.
     initializeCoreComponents();
 
-    // Put extensions jars into the class loader and load all
-    // configuration definition classes in that they contain.
-    // First load the extension from the install directory, then
-    // from the instance directory.
-    File libDir ;
-    File installExtensionsPath ;
-    File instanceExtensionsPath ;
+    // Put extensions jars into the class loader and load all configuration definition classes in that they contain.
+    // First load the extension from the install directory, then from the instance directory.
+    File installExtensionsPath  = buildExtensionPath(DirectoryServer.getServerRoot());
+    File instanceExtensionsPath = buildExtensionPath(DirectoryServer.getInstanceRoot());
 
-
-    // load install dir extension
-    libDir = new File(DirectoryServer.getServerRoot(), LIB_DIR);
-    try
-    {
-      installExtensionsPath =
-        new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-    }
-    catch (Exception e)
-    {
-      installExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-    }
     initializeAllExtensions(installExtensionsPath);
 
-    // load instance dir extension
-    libDir = new File(DirectoryServer.getInstanceRoot(),LIB_DIR);
-    try
-    {
-      instanceExtensionsPath =
-        new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
-    }
-    catch (Exception e)
-    {
-      instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR);
-    }
-    if (! installExtensionsPath.getAbsolutePath().equals(
-        instanceExtensionsPath.getAbsolutePath()))
-    {
+    if (! installExtensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
       initializeAllExtensions(instanceExtensionsPath);
     }
   }
 
+  private File buildExtensionPath(String directory)  {
+    File libDir = new File(directory, LIB_DIR);
+    try {
+      return new File(libDir, EXTENSIONS_DIR).getCanonicalFile();
+    } catch (Exception e) {
+      return new File(libDir, EXTENSIONS_DIR);
+    }
+  }
 
 
   /**
-   * Gets the class loader which should be used for loading classes
-   * and resources. When this class loader provider is disabled, the
-   * system default class loader will be returned by default.
+   * Gets the class loader which should be used for loading classes and resources. When this class loader provider
+   * is disabled, the system default class loader will be returned by default.
    * <p>
-   * Applications <b>MUST NOT</b> maintain persistent references to
-   * the class loader as it can change at run-time.
+   * Applications <b>MUST NOT</b> maintain persistent references to the class loader as it can change at run-time.
    *
-   * @return Returns the class loader which should be used for loading
-   *         classes and resources.
+   * @return Returns the class loader which should be used for loading classes and resources.
    */
   public synchronized ClassLoader getClassLoader() {
     if (loader != null) {
@@ -378,8 +269,7 @@
   /**
    * Indicates whether this class loader provider is enabled.
    *
-   * @return Returns <code>true</code> if this class loader provider
-   *         is enabled.
+   * @return Returns <code>true</code> if this class loader provider is enabled.
    */
   public synchronized boolean isEnabled() {
     return loader != null;
@@ -391,12 +281,11 @@
    * Add the named extensions to this class loader.
    *
    * @param extensions
-   *          The names of the extensions to be loaded.
+   *          A List of the names of the extensions to be loaded.
    * @throws InitializationException
-   *           If one of the extensions could not be loaded and
-   *           initialized.
+   *           If one of the extensions could not be loaded and initialized.
    */
-  private synchronized void addExtension(File... extensions)
+  private synchronized void addExtension(List<File> extensions)
       throws InitializationException {
     // First add the Jar files to the class loader.
     List<JarFile> jars = new LinkedList<>();
@@ -415,9 +304,8 @@
       } catch (Exception e) {
         logger.traceException(e);
 
-        LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.
-            get(extension.getName(), extension.getParent(),
-                stackTraceToSingleLineString(e));
+        LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE
+            .get(extension.getName(), extension.getParent(), stackTraceToSingleLineString(e));
         throw new InitializationException(message);
       }
       jarFiles.add(extension);
@@ -438,22 +326,19 @@
    *         <code>null</code> if there is no information available.
    */
   public String printExtensionInformation() {
-    String pathname = DirectoryServer.getServerRoot() + File.separator + LIB_DIR + File.separator + EXTENSIONS_DIR;
-    File extensionsPath = new File(pathname);
+    File extensionsPath = buildExtensionPath(DirectoryServer.getServerRoot());
 
-    if (!extensionsPath.exists() || !extensionsPath.isDirectory()) {
-      // no extensions' directory
-      return null;
+    List<File> extensions = new ArrayList<>();
+    if (extensionsPath.exists() && extensionsPath.isDirectory()) {
+      extensions.addAll(listFiles(extensionsPath));
     }
 
-    File[] extensions = extensionsPath.listFiles(new FileFilter(){
-      public boolean accept(File pathname) {
-        // only files with names ending with ".jar"
-        return pathname.isFile() && pathname.getName().endsWith(".jar");
-      }
-    });
+    File instanceExtensionsPath = buildExtensionPath(DirectoryServer.getInstanceRoot());
+    if (!extensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) {
+      extensions.addAll(listFiles(instanceExtensionsPath));
+    }
 
-    if ( extensions.length == 0 ) {
+    if ( extensions.isEmpty() ) {
       return null;
     }
 
@@ -470,38 +355,50 @@
               EOL);
 
     for(File extension : extensions) {
-      // retrieve MANIFEST entry and display name, build number and revision
-      // number
-      try {
-        JarFile jarFile = new JarFile(extension);
-        JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
-        if (entry == null)
-        {
-          continue;
-        }
-
-        String[] information = getBuildInformation(jarFile);
-
-        ps.append("Extension: ");
-        boolean addBlank = false;
-        for(String name : information) {
-          if ( addBlank ) {
-            ps.append(addBlank ? " " : ""); // add blank if not first append
-          } else {
-            addBlank = true;
-          }
-
-          ps.printf("%-20s", name);
-        }
-        ps.append(EOL);
-      } catch(Exception e) {
-        // ignore extra information for this extension
-      }
+      printExtensionDetails(ps, extension);
     }
 
     return baos.toString();
   }
 
+  private List<File> listFiles(File path){
+    if (path.exists() && path.isDirectory()) {
+      return Arrays.asList(path.listFiles(new FileFilter() {
+        public boolean accept(File pathname) {
+          // only files with names ending with ".jar"
+          return pathname.isFile() && pathname.getName().endsWith(".jar");
+        }
+      }));
+    }
+    return Collections.emptyList();
+  }
+
+  private void printExtensionDetails(PrintStream ps, File extension) {
+    // retrieve MANIFEST entry and display name, build number and revision number
+    try {
+      JarFile jarFile = new JarFile(extension);
+      JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
+      if (entry == null) {
+        return;
+      }
+
+      String[] information = getBuildInformation(jarFile);
+
+      ps.append("Extension: ");
+      boolean addBlank = false;
+      for(String name : information) {
+        if ( addBlank ) {
+          ps.append(" ");
+        } else {
+          addBlank = true;
+        }
+        ps.printf("%-20s", name);
+      }
+      ps.append(EOL);
+    } catch(Exception e) {
+      // ignore extra information for this extension
+    }
+  }
 
 
   /**
@@ -511,11 +408,12 @@
    * <br>index 2: the revision number of the extension.
    *
    * @param extension the jar file of the extension
-   * @return a String array containing the name, the build number and the
-   *         revision number of the extension given in argument
+   * @return a String array containing the name, the build number and the revision number
+   *         of the extension given in argument
    * @throws java.io.IOException thrown if the jar file has been closed.
    */
-  private String[] getBuildInformation(JarFile extension) throws IOException {
+  private String[] getBuildInformation(JarFile extension)
+      throws IOException {
     String[] result = new String[3];
 
     // retrieve MANIFEST entry and display name, version and revision
@@ -540,24 +438,20 @@
 
 
   /**
-   * Put extensions jars into the class loader and load all
-   * configuration definition classes in that they contain.
+   * Put extensions jars into the class loader and load all configuration definition classes in that they contain.
    * @param extensionsPath Indicates where extensions are located.
    *
    * @throws InitializationException
-   *           If the extensions folder could not be accessed or if a
-   *           extension jar file could not be accessed or if one of
-   *           the configuration definition classes could not be
-   *           initialized.
+   *           If the extensions folder could not be accessed or if a extension jar file could not be accessed or
+   *           if one of the configuration definition classes could not be initialized.
    */
   private void initializeAllExtensions(File extensionsPath)
       throws InitializationException {
 
     try {
       if (!extensionsPath.exists()) {
-        // The extensions directory does not exist. This is not a
-        // critical problem.
-        logger.error(ERR_ADMIN_NO_EXTENSIONS_DIR, extensionsPath);
+        // The extensions directory does not exist. This is not a critical problem.
+        logger.warn(WARN_ADMIN_NO_EXTENSIONS_DIR, extensionsPath);
         return;
       }
 
@@ -566,25 +460,8 @@
         throw new InitializationException(ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(extensionsPath));
       }
 
-      // Get each extension file name.
-      FileFilter filter = new FileFilter() {
-
-        /**
-         * Must be a Jar file.
-         */
-        public boolean accept(File pathname) {
-          if (!pathname.isFile()) {
-            return false;
-          }
-
-          String name = pathname.getName();
-          return name.endsWith(".jar");
-        }
-
-      };
-
       // Add and initialize the extensions.
-      addExtension(extensionsPath.listFiles(filter));
+      addExtension(listFiles(extensionsPath));
     } catch (InitializationException e) {
       logger.traceException(e);
       throw e;
@@ -603,14 +480,12 @@
    * Make sure all core configuration definitions are loaded.
    *
    * @throws InitializationException
-   *           If the core manifest file could not be read or if one
-   *           of the configuration definition classes could not be
-   *           initialized.
+   *           If the core manifest file could not be read or if one of the configuration definition
+   *           classes could not be initialized.
    */
   private void initializeCoreComponents()
       throws InitializationException {
-    InputStream is = RootCfgDefn.class.getResourceAsStream("/admin/"
-        + CORE_MANIFEST);
+    InputStream is = RootCfgDefn.class.getResourceAsStream("/admin/" + CORE_MANIFEST);
 
     if (is == null) {
       LocalizableMessage message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST);
@@ -631,20 +506,17 @@
 
 
   /**
-   * Make sure all the configuration definition classes in a extension
-   * are loaded.
+   * Make sure all the configuration definition classes in a extension are loaded.
    *
    * @param jarFile
    *          The extension's Jar file.
    * @throws InitializationException
-   *           If the extension jar file could not be accessed or if
-   *           one of the configuration definition classes could not
-   *           be initialized.
+   *           If the extension jar file could not be accessed or if one of the configuration definition classes
+   *           could not be initialized.
    */
   private void initializeExtension(JarFile jarFile)
       throws InitializationException {
-    JarEntry entry = jarFile.getJarEntry("admin/"
-        + EXTENSION_MANIFEST);
+    JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST);
     if (entry != null) {
       InputStream is;
       try {
@@ -652,8 +524,7 @@
       } catch (Exception e) {
         logger.traceException(e);
 
-        LocalizableMessage message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(
-            EXTENSION_MANIFEST, jarFile.getName(),
+        LocalizableMessage message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(EXTENSION_MANIFEST, jarFile.getName(),
             stackTraceToSingleLineString(e));
         throw new InitializationException(message);
       }
@@ -663,8 +534,8 @@
       } catch (InitializationException e) {
         logger.traceException(e);
 
-        LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile
-            .getName(), EXTENSION_MANIFEST, stackTraceToSingleLineString(e));
+        LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile.getName(), EXTENSION_MANIFEST,
+            stackTraceToSingleLineString(e));
         throw new InitializationException(message);
       }
       logExtensionsBuildInformation(jarFile);
@@ -687,14 +558,12 @@
 
 
   /**
-   * Forcefully load configuration definition classes named in a
-   * manifest file.
+   * Forcefully load configuration definition classes named in a manifest file.
    *
    * @param is
    *          The manifest file input stream.
    * @throws InitializationException
-   *           If the definition classes could not be loaded and
-   *           initialized.
+   *           If the definition classes could not be loaded and initialized.
    */
   private void loadDefinitionClasses(InputStream is)
       throws InitializationException {
@@ -732,8 +601,7 @@
       try {
         theClass = Class.forName(className, true, loader);
       } catch (Exception e) {
-        throw new InitializationException(
-            ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, e.getMessage()), e);
+        throw new InitializationException(ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, e.getMessage()), e);
       }
       if (AbstractManagedObjectDefinition.class.isAssignableFrom(theClass)) {
         // We need to instantiate it using its getInstance() static method.
@@ -763,8 +631,7 @@
         d.initialize();
       } catch (Exception e) {
         throw new InitializationException(
-            ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(
-                d.getName(), d.getClass().getName(), e.getMessage()), e);
+            ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(), d.getClass().getName(), e.getMessage()), e);
       }
     }
   }
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin.properties
index 4afaa5e..793ba08 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin.properties
@@ -62,7 +62,7 @@
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=The Directory Server jar file %s in \
  directory %s cannot be loaded because an unexpected error occurred while \
  trying to open the file for reading: %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
  exist, therefore no extensions will be loaded
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Unable to read the Directory \
  Server extensions because the extensions directory %s exists but is not a \
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties
index 14f4db3..2a56ff8 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=Fehler beim Versuch, Konfigurationseintrag %s des verwalteten Objekts zu entschl\u00fcsseln: %s
 ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=Der Directory-Server konnte Klasse %s nicht laden und verwendet sie zum Erstellen einer Komponenteninstanz wie in Konfigurationseintrag %s definiert.  Folgender Fehler ist aufgetreten:  %s.  Diese Komponente wird deaktiviert
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=Die JAR-Datei %s des Directory-Servers in Verzeichnis %s kann nicht geladen werden, da beim Versuch, die Datei zum Lesen zu \u00f6ffnen, ein unerwarteter Fehler aufgetreten ist:  %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=Das Verzeichnis f\u00fcr Erweiterungen %s ist nicht vorhanden, deshalb werden keine Erweiterungen geladen
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=Das Verzeichnis f\u00fcr Erweiterungen %s ist nicht vorhanden, deshalb werden keine Erweiterungen geladen
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Die Directory-Server-Erweiterungen konnten nicht gelesen werden, da das Verzeichnis f\u00fcr Erweiterungen %s zwar vorhanden ist, aber kein Verzeichnis darstellt
 ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=Die Directory-Server-Erweiterungen konnten nicht aus Verzeichnis %s gelesen werden, da beim Versuch, die Dateien in diesem Verzeichnis aufzulisten, ein Fehler aufgetreten ist:  %s
 ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=Die Manifest-Datei der Kernadministration %s wurde nicht gefunden
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties
index f14899a..6349b52 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=Se ha producido un error al tratar de descodificar la entrada de configuraci\u00f3n del objeto administrado %s: %s
 ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=El Servidor de directorios no pudo cargar la clase %s ni emplearla para crear una instancia de componente como se define en la entrada de configuraci\u00f3n %s.  El error producido fue el siguiente:  %s.  Este componente se inhabilitar\u00e1
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=No puede cargarse el archivo jar del Servidor de directorios %s en el directorio %s debido a que se ha producido un error inesperado al tratar de abrir el archivo para su lectura:  %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=El directorio de extensiones %s no existe, por lo que no se cargar\u00e1 ninguna extensi\u00f3n
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=El directorio de extensiones %s no existe, por lo que no se cargar\u00e1 ninguna extensi\u00f3n
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=No pueden leerse las extensiones del Servidor de directorios debido a que, pese a que existe el directorio de extensiones %s, \u00e9ste no es un directorio
 ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=No pueden leerse las extensiones del Servidor de directorios desde el directorio %s debido a que se ha producido un error inesperado al tratar de mostrar los archivos en ese directorio: %s
 ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=No puede ubicarse el archivo de manifiesto de administraci\u00f3n de base %s
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties
index 47f2cf0..c108946 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=Une erreur s'est produite lors de la tentative de d\u00e9codage de l'entr\u00e9e de configuration d'objet g\u00e9r\u00e9 %s\u00a0: %s
 ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=Directory Server n'a pas pu charger la classe %s et l'utiliser en tant qu'instance de composant comme le d\u00e9finit l'entr\u00e9e de configuration %s. Erreur d\u00e9tect\u00e9e\u00a0: %s. Ce composant va \u00eatre d\u00e9sactiv\u00e9
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=Impossible de charger le fichier jar Directory Server %s dans le r\u00e9pertoire %s car une erreur inattendue s'est produite lors de la tentative d'ouverture du fichier pour la lecture\u00a0: %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=Le r\u00e9pertoire d'extensions %s n'existe pas, aucune extension ne sera donc charg\u00e9e
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=Le r\u00e9pertoire d'extensions %s n'existe pas, aucune extension ne sera donc charg\u00e9e
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Impossible de lire les extensions Directory Server car le r\u00e9pertoire d'extensions %s existe mais il ne s'agit pas d'un r\u00e9pertoire
 ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=Impossible de lire les extensions Directory Server depuis le r\u00e9pertoire %s car une erreur inattendue s'est produite lors de la tentative d'\u00e9num\u00e9ration des fichiers de ce r\u00e9pertoire\u00a0: %s
 ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=Le fichier manifest d'administration de serveur de base %s est introuvable
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties
index 3988873..9f85b77 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=\u7ba1\u7406\u5bfe\u8c61\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u69cb\u6210\u30a8\u30f3\u30c8\u30ea %s \u306e\u30c7\u30b3\u30fc\u30c9\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: %s
 ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306f\u30af\u30e9\u30b9 %s \u3092\u8aad\u307f\u8fbc\u3081\u305a\u3001\u69cb\u6210\u30a8\u30f3\u30c8\u30ea %s \u306e\u5b9a\u7fa9\u306b\u5f93\u3063\u3066\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u6b21\u306e\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: %s\u3002\u3053\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306f\u7121\u52b9\u306b\u306a\u308a\u307e\u3059
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea %2$s \u5185\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306e jar \u30d5\u30a1\u30a4\u30eb %1$s \u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3002\u30d5\u30a1\u30a4\u30eb\u3092\u8aad\u307f\u53d6\u308a\u7528\u306b\u958b\u304f\u3068\u304d\u306b\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: %3$s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=\u62e1\u5f35\u6a5f\u80fd\u30c7\u30a3\u30ec\u30af\u30c8\u30ea %s \u304c\u5b58\u5728\u3057\u306a\u3044\u305f\u3081\u3001\u62e1\u5f35\u6a5f\u80fd\u306f\u8aad\u307f\u8fbc\u307e\u308c\u307e\u305b\u3093
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=\u62e1\u5f35\u6a5f\u80fd\u30c7\u30a3\u30ec\u30af\u30c8\u30ea %s \u304c\u5b58\u5728\u3057\u306a\u3044\u305f\u3081\u3001\u62e1\u5f35\u6a5f\u80fd\u306f\u8aad\u307f\u8fbc\u307e\u308c\u307e\u305b\u3093
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306e\u62e1\u5f35\u6a5f\u80fd\u3092\u8aad\u307f\u53d6\u308c\u307e\u305b\u3093\u3002\u62e1\u5f35\u6a5f\u80fd\u30c7\u30a3\u30ec\u30af\u30c8\u30ea %s \u306f\u5b58\u5728\u3057\u307e\u3059\u304c\u3001\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093
 ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea %s \u304b\u3089\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u30b5\u30fc\u30d0\u30fc\u306e\u62e1\u5f35\u6a5f\u80fd\u3092\u8aad\u307f\u53d6\u308c\u307e\u305b\u3093\u3002\u3053\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u5185\u306e\u30d5\u30a1\u30a4\u30eb\u3092\u4e00\u89a7\u8868\u793a\u4e2d\u306b\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: %s
 ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=\u30b3\u30a2\u7ba1\u7406\u30de\u30cb\u30d5\u30a7\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb %s \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
diff --git a/opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties b/opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties
index 8fa261f..7232527 100644
--- a/opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties
+++ b/opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties
@@ -52,7 +52,7 @@
 ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=\uad00\ub9ac \ub300\uc0c1 \uac1d\uccb4 \uad6c\uc131 \ud56d\ubaa9 %s(\uc744)\ub97c \ud574\ub3c5\ud558\ub294 \ub3d9\uc548 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4: %s
 ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=\ub514\ub809\ud1a0\ub9ac \uc11c\ubc84\uc5d0\uc11c %s \ud074\ub798\uc2a4\ub97c \ub85c\ub4dc\ud558\uc5ec \uad6c\uc131 \ud56d\ubaa9 %s\uc5d0 \uc815\uc758\ub41c \ub300\ub85c \uad6c\uc131\uc694\uc18c \uc778\uc2a4\ud134\uc2a4\ub97c \uc791\uc131\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. %s \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4. \uc774 \uad6c\uc131\uc694\uc18c\uac00 \ube44\ud65c\uc131\ud654\ub429\ub2c8\ub2e4.
 ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=\uc77d\uc744 \ud30c\uc77c\uc744 \uc5ec\ub294 \ub3d9\uc548 \uc608\uae30\uce58 \uc54a\uc740 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc5ec \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84 jar \ud30c\uc77c %s(\ub514\ub809\ud1a0\ub9ac %s\uc5d0 \uc788\uc74c)\uc744(\ub97c) \ub85c\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4: %s
-ERR_ADMIN_NO_EXTENSIONS_DIR_12=\ud655\uc7a5 \ub514\ub809\ud1a0\ub9ac %s\uc774(\uac00) \uc5c6\uc73c\ubbc0\ub85c \ud655\uc7a5\uc790\uac00 \ub85c\ub4dc\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+WARN_ADMIN_NO_EXTENSIONS_DIR_12=\ud655\uc7a5 \ub514\ub809\ud1a0\ub9ac %s\uc774(\uac00) \uc5c6\uc73c\ubbc0\ub85c \ud655\uc7a5\uc790\uac00 \ub85c\ub4dc\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
 ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=\ud655\uc7a5 \ub514\ub809\ud1a0\ub9ac %s\uc774(\uac00) \uc788\uc9c0\ub9cc \ub514\ub809\ud1a0\ub9ac\uac00 \uc544\ub2c8\ubbc0\ub85c \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84 \ud655\uc7a5\uc790\ub97c \uc77d\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
 ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=%s \ub514\ub809\ud1a0\ub9ac\uc5d0\uc11c \ud30c\uc77c\uc744 \ub098\uc5f4\ud558\ub294 \ub3d9\uc548 \uc608\uae30\uce58 \uc54a\uc740 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc5ec \uc774 \ub514\ub809\ud1a0\ub9ac\uc5d0\uc11c \ub514\ub809\ud1a0\ub9ac \uc11c\ubc84 \ud655\uc7a5\uc790\ub97c \uc77d\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4: %s
 ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=\ucf54\uc5b4 \uad00\ub9ac \uc99d\uba85 \ud30c\uc77c %s\uc744(\ub97c) \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.

--
Gitblit v1.10.0