Ошибка при загрузке классов файла JAR во время выполнения

Я пытаюсь добавить файл JAR в путь к классу и загрузить все классы из файла JAR во время выполнения. вот код, который я написал для этой задачи (этот класс расширяет URLClassLoader)

public void loadJar(final String fName) throws IOException, IllegalAccessException, ClassNotFoundException {
    final File file = new File(fName);
    if (file.exists() && getFileExtension(file.getName()).equalsIgnoreCase("jar")) {
        addURL(file.toURI().toURL());
        for(final URL url : getURLs()){
            System.out.println(url.toString());
        }
        final ZipFile jarFile = new ZipFile(file, ZipFile.OPEN_READ);
        final Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) jarFile.entries();
        while (entries.hasMoreElements()) {
            final String className = getClassCanonicalName(entries.nextElement());
            if (className != null) {
                loadClass(getClassCanonicalName(entries.nextElement()));
            }
        }
    }
}

private String getFileExtension(final String fileName) {
    return fileName.substring(fileName.lastIndexOf(".") + 1);
}

private String getClassCanonicalName(final ZipEntry entry) {
    final String entryName = entry.getName();
    if (getFileExtension(entryName).toLowerCase().endsWith("class")) {
        return entryName.replaceAll(File.separator, ".");
    } else {
        return null;
    }
}

Но я продолжаю получать ClassNotFoundException для сущностей класса, даже если getURL указывает, что файлы jar были добавлены в этот загрузчик.

В чем причина этой проблемы? Спасибо


person Korben    schedule 31.10.2012    source источник


Ответы (1)


return entryName.replaceAll(File.separator, "."); 

В Windows это не удастся. Это должно быть / для разделителя ZipEntry для Zip, созданного на любой платформе.

Поэтому замените это на:

return entryName.replaceAll("/", "."); 

Также удалите имя класса. SSCCE, например:

import java.io.*;
import java.net.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class URLClassLoaderTest extends URLClassLoader {

    public URLClassLoaderTest(URL[] arg0) {
        super(arg0);
    }

    public void loadJar(URL urlOfJar) throws IOException, IllegalAccessException, ClassNotFoundException {
        if (getFileExtension(urlOfJar.getFile()).equalsIgnoreCase("jar")) {
            addURL(urlOfJar);
            for(final URL url : getURLs()){
                System.out.println(url.toString());
            }
            final ZipInputStream zis = new ZipInputStream(urlOfJar.openStream());
            ZipEntry ze = zis.getNextEntry();
            while (ze!=null) {
                final String className = getClassCanonicalName(ze);
                if (className != null) {
                    loadClass(getClassCanonicalName(ze));
                }
                ze = zis.getNextEntry();
            }
        }
    }

    private String getFileExtension(final String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    private String getClassCanonicalName(final ZipEntry entry) {
        final String entryName = entry.getName();
        if (getFileExtension(entryName).toLowerCase().endsWith("class")) {
            String s = entryName.substring(0,entryName.length()-6);
            s = s.replaceAll("/", ".");
            System.out.println(s);
            return s;
        } else {
            return null;
        }
    }

    public static void main(String[] args) throws Exception {
        URL[] url = {new URL("http://pscode.org/lib/mime.jar")};
        URLClassLoaderTest uclt = new URLClassLoaderTest(url);
        uclt.loadJar(url[0]);
    }
}

Выход

http://pscode.org/lib/mime.jar
org.pscode.mime.MimeType$1
org.pscode.mime.MimeType$1
org.pscode.mime.MimeType$2
org.pscode.mime.MimeType$2
org.pscode.mime.MimeType
org.pscode.mime.MimeType
person Andrew Thompson    schedule 31.10.2012
comment
Спасибо за ответ, можете ли вы запустить этот фрагмент кода в Windows? Я думаю, что это не причина, так как я использую Ubuntu - person Korben; 31.10.2012
comment
См. обновление, включающее SSCCE. В ответ на ваш вопрос получил «исключение шаблона» во время выполнения под Windows. ;) ..Так что все равно меняй. - person Andrew Thompson; 31.10.2012