I needed to load the classes from thedt.jar archive on the fly. The path to the archive was generated automatically based on the "java.home" system property. The original idea was to use the URLClassLoader, but it could not find classes. I had to write a custom class loader which read an archive and loaded classes on demand. At that instant I realized why theURLClassLoader did not work: I had incorrectly generated the path to the archive and theURLClassLoader for a wonder provided no warning that the archive was not found.

Below is the code of the custom class loader for work with jar- and zip-archives:

public final class ZipClassLoader extends ClassLoader {
    private final ZipFile file;

    public ZipClassLoader(String filename) throws IOException {
        this.file = new ZipFile(filename);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        ZipEntry entry = this.file.getEntry(name.replace('.', '/') + ".class");
        if (entry == null) {
            throw new ClassNotFoundException(name);
        }
        try {
            byte[] array = new byte[1024];
            InputStream in = this.file.getInputStream(entry);
            ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
            int length = in.read(array);
            while (length > 0) {
                out.write(array, 0, length);
                length = in.read(array);
            }
            return defineClass(name, out.toByteArray(), 0, out.size());
        }
        catch (IOException exception) {
            throw new ClassNotFoundException(name, exception);
        }
    }
}

Note that it is not necessary to cache classes here, because the ClassLoader caches loaded classes automatically. Also you can override the following methods to search resources in the archive:

    @Override
    protected URL findResource(String name) {
        ZipEntry entry = this.file.getEntry(name);
        if (entry == null) {
            return null;
        }
        try {
            return new URL("jar:file:" + this.file.getName() + "!/" + entry.getName());
        }
        catch (MalformedURLException exception) {
            return null;
        }
    }

    @Override
    protected Enumeration<URL> findResources(final String name) {
        return new Enumeration<URL>() {
            private URL element = findResource(name);

            public boolean hasMoreElements() {
                return this.element != null;
            }

            public URL nextElement() {
                if (this.element != null) {
                    URL element = this.element;
                    this.element = null;
                    return element;
                }
                throw new NoSuchElementException();
            }
        };
    }

Perhaps someone may need it because it slightly faster. But I recommend to use theURLClassLoader which is able to work with remote archives and supports security:

URL[] urls = { new URL("jar:file:" + path + "!/") };
return URLClassLoader.newInstance(urls);

If the classes cannot be loaded, double check the correctness of the path.