经过几个小时的斗争,我开始变得非常沮丧。
我有一个JKS服务器文件,我想从jar中加载。只要文件在Jar之外,使用FileInputStream就可以处理,但是一旦我尝试将其更改为getResourceAsStream,它就不会接受它,说(没有这样的文件或目录)。
这是项目的分发方式
ProjectFolder
-src
--package.name
---JKS File
---Class calling the resource retrieval and loading into the keystore
我想我几乎尝试过this.getClass()。getClassLoader()。getResourceAsStream(“jksFile.jks”)的每一个组合我都能想到。
我提前道歉,因为没有更具体的代码,但我完全忘记了我尝试过的东西和我没有的东西。
HELP!
提前致谢
答案 0 :(得分:2)
如果是战争文件:
在构建和运行项目时,.class将不再位于此位置(/ src),它将转到WEB-INF / classes / ...,所以,也许你可以试着把你的JKS文件在那里,或者在getResourceAsStream()中从类到src的引用。
war文件夹的文件夹层次结构的有用链接:http://www.yolinux.com/TUTORIALS/Java-WAR-files.html
答案 1 :(得分:1)
通过获取Class
,有两种主要方式可以通过Classloader
对象和getResourceAsStream
访问类路径中的资源。
最终,实现资源查找的精确规则依赖于类加载器。但大部分内容都明确规定。资源按名称查找。
资源的名称是'/' - 标识资源的分隔路径名。
而且,在探索类路径时,搜索顺序也很清晰
此方法将首先在父类加载器中搜索资源;如果父项为null,则搜索内置到虚拟机的类加载器的路径。如果失败,此方法将调用{@link #findResource(String)}来查找资源。
findResource
是依赖于实现的部分。但是,大多数Java类加载器都是某种类型的URLClassLoader
,并且它们的实现知道如何探索类路径条目(在文件系统上或JAR文件内部 - 甚至是远程的)以将名称解析为内部的相对或绝对路径-entries。
因此,简而言之:您使用getResourceByName
来探索类路径,通过类路径中的相对或绝对路径查找文件。
Class#getResourceAsStream
和ClassLoader#getResourceAsStream
之间的区别在于Class
版本会将相对路径解释为相对于Class
的包,而ClassLoader
version将从类路径的根目录开始。
所以......考虑到以下项目结构:
src
name
gpi
file.txt
Test.java
这个Test.java有效:
public static void main(String[] args) throws IOException {
// relative path from this class
InputStream is = Test.class.getResourceAsStream("file.txt");
byte[] content = new byte[4096];
int length = is.read(content);
System.out.println(new String(content, 0, length));
// relative path from the root of the classpath
is = Test.class.getClassLoader().getResourceAsStream("name/gpi/file.txt");
content = new byte[4096];
length = is.read(content);
System.out.println(new String(content, 0, length));
}
在文档思想中要小心,
// This works : on the class object, absolute path are treated as "root of the classpath"
InputStream is = Test.class.getResourceAsStream("/name/gpi/file.txt");
//This does not work, because this looks actually at the root of the file system
InputStream is = Test.class.getClassLoader().getResourceAsStream("/name/gpi/file.txt");
如果你尝试这里列出的组合工作,而他们实际上没有,那么要么你有一个“时髦”的类加载器(绝对不应该在一个简单的项目上发生),你的编译器/打包器设置(maven或eclipse或其他)的设置方式是从编译/打包结果(JAR)中丢弃JKS文件。
在maven项目中,Java类属于src / main / java目录,而属性,配置和JKS文件通常属于src / main / resources目录。根据您确切的maven设置,将JKS文件放在java目录中可能会导致它从实际的可运行类路径中被丢弃。所以你也应该检查一下。
答案 2 :(得分:0)
假设jar包含 src
下的文件夹结构,它包含已编译的.class
文件以及甚至包含源.java
的文件。 file(s)(使目录名src
误导):
this.getClass().getResourceAsStream(String)
或其他方式获取类MyClass.class
然后.getResourceAsStream(String)
将resource-name视为相对于包含类
this.getClass().getClassLoader().getResourceAsStream(String)
或其他方式查找类似athread.getContextClassLoader()
然后.getResourceAsStream(String)
的类加载器
将资源名称视为相对于jar文件的根目录,因此您需要"package/names/jksfile.jks"
。
请记住jar 中的包路径使用斜杠,而在Java源代码中,它们使用点。
(将源文件放在src/package/names/MyClass.java
和编译文件下时,目录'src'和'bin'通常使用且有用
在镜像层次结构bin/package/names/MyClass.class
中。)