@Override
    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
        synchronized (this.getClassLoadingLock(name)) {
            // If the class with the specified binary name has already been loaded exactly by this PluginClassLoader instance,
            // find the loaded class, and return it.
            //
            // Note that ClassLoader#findLoadedClass(String) does not find the class from its parent class loader.
            final Class<?> loadedClass = this.findLoadedClass(name);

            if (loadedClass != null) {
                return resolveClass(loadedClass, resolve);
            }

            final boolean parentFirst = isParentFirstPackage(name);

            // If the class is "not parent-first" (not to be loaded by the parent at first),
            // try {@code #findClass} of the child's ({@code PluginClassLoader}'s).
            if (!parentFirst) {
                try {
                    // If a class that is removed by JEP 320 is found here, it should be fine.
                    // It means that the class is found on the plugin side -- the plugin contains its own one.
                    // Classes removed by JEP 320 are not in the "parent-first" list.
                    return resolveClass(findClass(name), resolve);
                } catch (ClassNotFoundException ignored) {
                    // Passing through intentionally.
                }
            }

            // If the class is "parent-first" (to be loaded by the parent at first), try this part at first.
            // If the class is "not parent-first" (not to be loaded by the parent at first), the above part runs first.
            try {
                final Class<?> resolvedClass = resolveClass(getParent().loadClass(name), resolve);
                logInfoIfJep320Class(name);
                return resolvedClass;
            } catch (final ClassNotFoundException ex) {
                if (!parentFirst) {
                    rethrowIfJep320Class(name, ex);
                }
                // Passing through intentionally if the class is not not removed by JEP 320.
            }

            // If the class is "parent-first" (to be loaded by the parent at first), this part runs after the above.
            if (parentFirst) {
                return resolveClass(findClass(name), resolve);
            }

            throw new ClassNotFoundException(name);
        }
    }
Loads the class with the specified binary name prioritized by the "parent-first" condition.

It copy-cats {@code ClassLoader#loadClass} while the "parent-first" priorities are considered.

If the specified class is "parent-first", it behaves the same as {@code ClassLoader#loadClass} ordered as below.

<ol>

<li><p>Invoke the {@code #findLoadedClass} method to check if the class has already been loaded.</p></li>

<li><p>Invoke the parent's {@code #loadClass} method.

<li><p>Invoke the {@code #findClass} method of this class loader to find the class.</p></li>

</ol>

If the specified class is "NOT parent-first", the 2nd and 3rd actions are swapped.

@see <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#loadClass(java.lang.String,%20boolean)">Oracle Java7's ClassLoader#loadClass</a>
@see <a href="http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/jdk7u141-b02/src/share/classes/java/lang/ClassLoader.java">OpenJDK7's ClassLoader</a>
embulk-core/src/main/java/org/embulk/plugin/PluginClassLoader.java