Java 如何在windows上从JAR反映类

Java 如何在windows上从JAR反映类,java,linux,windows,jar,classloader,Java,Linux,Windows,Jar,Classloader,假设以下loader定义(示例是用scala编写的,但与Java几乎相同,因此您应该很容易理解问题): JARmyjar.JAR包含org/pack/Simple.class。Simple具有标准包org.pack,并通过编译打包到JAR中。JAR是正确的(可执行文件等) 在linux上,loader.loadClass(“org.pack.Simple”)返回正确的Class对象 在windows上,它抛出一个ClassNotFoundException。当然,我使用\而不是/作为文件分隔符

假设以下
loader
定义(示例是用scala编写的,但与Java几乎相同,因此您应该很容易理解问题):

JAR
myjar.JAR
包含
org/pack/Simple.class
Simple
具有标准包
org.pack
,并通过编译打包到JAR中。JAR是正确的(可执行文件等)

在linux上,
loader.loadClass(“org.pack.Simple”)
返回正确的
Class
对象

在windows上,它抛出一个
ClassNotFoundException
。当然,我使用
\
而不是
/
作为文件分隔符

我做错了什么?还是说窗户真的很烂?我安装了OracleJDK8,并将其
bin/
文件夹添加到
路径

EDIT1:


如果我将JAR解压到某个目录中,并让类加载器从指向该目录的URL读取,那么一切都会正常工作。这怎么可能呢?

昨天我一直在努力解决这个问题,但在长时间的谷歌搜索之后,我偶然发现了解决方案

必须按如下方式创建指定的URL对象:

URLClassLoader.addURL(new File(pathParam).toURI().toURL());
new URLClassLoader(new URL[]{new File(pathParam).toURI().toURL()},this.getClass().getClassLoader());
或在构造函数中,如下所示:

URLClassLoader.addURL(new File(pathParam).toURI().toURL());
new URLClassLoader(new URL[]{new File(pathParam).toURI().toURL()},this.getClass().getClassLoader());
请注意,构造函数将父类装入器作为参数。

对于loadClass()方法。您需要确保类的路径是二进制格式的(正如您已经做的那样)

出于某种原因,即使我使用URL(字符串)构造函数创建URL对象,它也不会工作

如果查看
java.lang.ClassLoader
super类,您会注意到默认情况下它会抛出一个异常。这就是类加载器很重要的原因

protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
受保护的类findClass(字符串名称)抛出ClassNotFoundException{
抛出新的ClassNotFoundException(名称);
}

您是否检查了windows中存在的路径所指示的文件?它看起来像什么?我在Windows上使用的URLclassLoader没有任何问题,因此这不是“Windows糟糕透顶”的情况。@JPMoresmau我仔细检查了URL-它是以
文件:/C://…/myjar.jar
的形式出现的(即前斜杠),因此我认为是这样correct@JPMoresmau我加了一条评论,你能看一下吗?我真的很绝望。永远不要使用反斜杠,它只会使你的代码不可移植。此外,请尝试相对路径并确保
File.exists()
。我觉得这个URL不太合适,C前面不应该有一个双斜杠吗:看我的答案。我最初认为这是因为内部类和Windows无法处理文件名中的$字符。但后来发现情况并非如此。