我可能会错过一些愚蠢但仍然存在的东西
我创建了一个具有以下内部结构的jar文件:
其中folder1和folder2保存.class文件和资源有txt和png文件 在我的代码中,我有以下行
BufferedReader reader = new BufferedReader(new InputStreamReader(
ClassLoader.getSystemResourceAsStream(txtFile)));
其中txtFile
是一个字符串,其中包含位于资源文件夹中的文件名。 (直接在文件夹中)。
问题是当我尝试从命令行运行程序时
这是我跑的命令。
java -cp externalJar.jar;myJar.jar;resources com.my.package.MyMainClass
程序运行和精细单元我到达上面的代码行,我得到一个空指针异常:
java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at com.my.package.MyMainClass.generateSomething(Unknown Source)
at com.my.package.MyMainClass.main
我猜这意味着我的类路径有问题 - 但我无法想象...
修改
我正在使用ant编译程序并将程序打包到一个可执行的jar中
这是我build.xml
:
<target name="jar" depends="compile">
<jar destfile="${executable.jar}" basedir="${bin}">
<zipfileset dir="${src}\resources" prefix="resources" />
<manifest>
<attribute name="Main-Class" value="MyMainClass" />
<attribute name="Class-Path" value="externalJar.jar" />
</manifest>
</jar>
</target>
编辑 - 2
因为它应该是一个可执行jar,所以txtFile
变量的值是硬编码的(除非作为参数给出)作为资源目录中的文件名。所以最终,我想运行这个命令:
java -jar myJar.jar
不幸的是 - 这也导致了相同的方式(同一行上的NullPointerException)
编辑 - 3(发现非优雅解决方案)
我发现如果我连接到类加载器读取的文件的所有路径前缀"resources/"
然后它工作正常 - 但我发现这是不优雅的。有没有办法将资源文件夹添加到类路径?
答案 0 :(得分:2)
首先,如果您只打算访问与MyMainclass
位于同一个jar中的文件,则可以在其类加载器而不是{{1}上调用getResource()
或getResourceAsStream()
} / getSystemResource()
。
getSystemResourceAsStream()
其次,您应该将路径传递给文件,而不是在类路径上传递resources文件夹:
public class MyMainClass {
public static void main(String[] args) throws Exception {
InputStream inputStream = MyMainClass.class.getResourceAsStream(args[0]);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
}
}
请注意,在创建InputStreamReader时指定编码(几乎)总是一个好主意,否则您依赖于JVM默认编码。
答案 1 :(得分:-1)
有一件事是清楚的,txtFile
变量将是null
或不存在的路径,因为NPE源自那里。
OR
问题的另一个可能性是调用ClassLoader.getSystemResourceAsStream(txtFile)
为了让正确的加载程序访问您的资源,请将其更改为
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getSystemResourceAsStream(txtFile);
并使用该流。