mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
20.34.2015 34b7cef2c96152433da6f380656baf9d27c9579a
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
9 files modified
643 ■■■■■ changed files
opendj-config/src/main/java/org/forgerock/opendj/config/ConfigurationFramework.java 274 ●●●●● patch | view | raw | blame | history
opendj-config/src/main/resources/com/forgerock/opendj/ldap/config/admin.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/admin/ClassLoaderProvider.java 355 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin_de.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin_es.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin_fr.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin_ja.properties 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/admin_ko.properties 2 ●●● patch | view | raw | blame | history
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;
        }
@@ -393,44 +331,44 @@
                "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.
     *
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 \
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,14 +355,31 @@
              EOL);
    for(File extension : extensions) {
      // retrieve MANIFEST entry and display name, build number and revision
      // number
      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)
        {
          continue;
      if (entry == null) {
        return;
        }
        String[] information = getBuildInformation(jarFile);
@@ -486,11 +388,10 @@
        boolean addBlank = false;
        for(String name : information) {
          if ( addBlank ) {
            ps.append(addBlank ? " " : ""); // add blank if not first append
          ps.append(" ");
          } else {
            addBlank = true;
          }
          ps.printf("%-20s", name);
        }
        ps.append(EOL);
@@ -499,10 +400,6 @@
      }
    }
    return baos.toString();
  }
  /**
   * Returns a String array with the following information :
@@ -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);
      }
    }
  }
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 \
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
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
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
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
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.