【问题标题】:Error when load JAR file classes at run time在运行时加载 JAR 文件类时出错
【发布时间】:2012-10-20 11:12:04
【问题描述】:

我正在尝试将 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,即使通过 getURLs 确实表明 jar 文件已添加到此加载器。

这个问题的原因是什么?谢谢

【问题讨论】:

    标签: java jar classloader classnotfoundexception urlclassloader


    【解决方案1】:
    return entryName.replaceAll(File.separator, "."); 
    

    在 Windows 上,这将失败。对于在 any 平台上制作的 Zip,ZipEntry 的分隔符应该是 /

    所以替换为:

    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
    

    【讨论】:

    • 感谢回复,你能在Windows上运行这段代码吗?我认为这不是原因,因为我使用的是 Ubuntu
    • 查看包含 SSCCE 的更新。在回答您的问题时,在 Windows 下得到了运行时“模式异常”。 ;) ..所以无论如何都要改变它。
    猜你喜欢
    • 2019-03-18
    • 2011-02-02
    • 2012-05-14
    • 1970-01-01
    • 2012-06-16
    • 2011-11-26
    • 1970-01-01
    • 2017-07-30
    • 1970-01-01
    相关资源
    最近更新 更多