jodd-core/src/main/java/jodd/util/cl/DefaultClassLoaderStrategy.java
@Override
	public Class loadClass(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
		String arrayClassName = prepareArrayClassnameForLoading(className);

		if ((className.indexOf('.') == -1) && (arrayClassName == null)) {
			// maybe a primitive
			int primitiveNdx = getPrimitiveClassNameIndex(className);
			if (primitiveNdx >= 0) {
				return PRIMITIVE_TYPES[primitiveNdx];
			}
		}

		// try #1 - using provided class loader
		if (classLoader != null) {
			Class klass = loadClass(className, arrayClassName, classLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #2 - using thread class loader
		ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();

		if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) {
			Class klass = loadClass(className, arrayClassName, currentThreadClassLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #3 - using caller classloader, similar as Class.forName()
		//Class callerClass = ReflectUtil.getCallerClass(2);
		Class callerClass = ClassUtil.getCallerClass();
		ClassLoader callerClassLoader = callerClass.getClassLoader();

		if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) {
			Class klass = loadClass(className, arrayClassName, callerClassLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #4 - everything failed, try alternative array loader
		if (arrayClassName != null) {
			try {
				return loadArrayClassByComponentType(className, classLoader);
			} catch (ClassNotFoundException ignore) {
			}
		}

		throw new ClassNotFoundException("Class not found: " + className);
	}
@Override
	public Class loadClass(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
		String arrayClassName = prepareArrayClassnameForLoading(className);

		if ((className.indexOf('.') == -1) && (arrayClassName == null)) {
			// maybe a primitive
			int primitiveNdx = getPrimitiveClassNameIndex(className);
			if (primitiveNdx >= 0) {
				return PRIMITIVE_TYPES[primitiveNdx];
			}
		}

		// try #1 - using provided class loader
		if (classLoader != null) {
			Class klass = loadClass(className, arrayClassName, classLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #2 - using thread class loader
		ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();

		if ((currentThreadClassLoader != null) && (currentThreadClassLoader != classLoader)) {
			Class klass = loadClass(className, arrayClassName, currentThreadClassLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #3 - using caller classloader, similar as Class.forName()
		//Class callerClass = ReflectUtil.getCallerClass(2);
		Class callerClass = ClassUtil.getCallerClass();
		ClassLoader callerClassLoader = callerClass.getClassLoader();

		if ((callerClassLoader != classLoader) && (callerClassLoader != currentThreadClassLoader)) {
			Class klass = loadClass(className, arrayClassName, callerClassLoader);

			if (klass != null) {
				return klass;
			}
		}

		// try #4 - everything failed, try alternative array loader
		if (arrayClassName != null) {
			try {
				return loadArrayClassByComponentType(className, classLoader);
			} catch (ClassNotFoundException ignore) {
			}
		}

		throw new ClassNotFoundException("Class not found: " + className);
	}
Loads class by name.