相对于类的Java文件位置
我很困惑java如何从类加载器的角度看待文件系统。相对于类的Java文件位置
假设我在EAR的APP-INF/lib文件夹中有一个jar文件。这个jar文件包含一个类,它实例化了new File("foo.txt")
。另外,foo.txt位于jar旁边的APP-INF/lib文件夹中。
然后,我在WAR模块中使用这个库。现在,代码是否仍会找到该文件,或者除了在EAR的根目录或WAR根目录中找到该文件?
我敢肯定,该文件需要在WAR的根,因为在你的jar文件WAR负载从EAR的APP-INF/lib下因此将相对搜索到WAR的文件路径
这是一个例子它是如何处理在classpath
package main;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class Test {
private Test() {
Class<?> c = this.getClass();
ClassLoader cl = c.getClassLoader();
InputStream[] iss = new InputStream[8];
URL[] urls = new URL[8];
iss[0] = c.getResourceAsStream("/resources/txtFile.txt");
iss[1] = c.getResourceAsStream("resources/txtFile.txt");
iss[2] = c.getResourceAsStream("/txtFile.txt");
iss[3] = c.getResourceAsStream("txtFile.txt");
iss[4] = cl.getResourceAsStream("/resources/txtFile.txt");
iss[5] = cl.getResourceAsStream("resources/txtFile.txt");
iss[6] = cl.getResourceAsStream("/txtFile.txt");
iss[7] = cl.getResourceAsStream("txtFile.txt");
urls[0] = c.getResource("/resources/txtFile.txt");
urls[1] = c.getResource("resources/txtFile.txt");
urls[2] = c.getResource("/txtFile.txt");
urls[3] = c.getResource("txtFile.txt");
urls[4] = cl.getResource("/resources/txtFile.txt");
urls[5] = cl.getResource("resources/txtFile.txt");
urls[6] = cl.getResource("/txtFile.txt");
urls[7] = cl.getResource("txtFile.txt");
for (int i = 0; i < 8; i++)
System.out.println("iss[" + i + "] is "
+ String.valueOf(iss[i] == null));
for (int i = 0; i < 8; i++)
System.out.println("url[" + i + "] is "
+ String.valueOf(urls[i] == null));
}
public static final void main(String[] args) {
new Test();
}
}
打印
iss[0] is false
iss[1] is true
iss[2] is true
iss[3] is true
iss[4] is true
iss[5] is false
iss[6] is true
iss[7] is true
url[0] is false
url[1] is true
url[2] is true
url[3] is true
url[4] is true
url[5] is false
url[6] is true
url[7] is true
装载_resources_时可能会出现这种情况,但操作系统会特别询问“File”对象,而不是资源。 –
您是否看过我的文章的顶部?底部只是一些额外的 – Dinh
是的,我读过它。就OP的问题而言,我相信你的回答是不正确的。只有在资源加载时,类加载器行为对符合JEE的应用服务器中的_File_加载没有影响。可以说,OP应该将他的数据文件指定为资源,而不是“文件”,但他不是。如果我误解了你写的内容,我很抱歉。 –
你不能依靠的是能够在EAR文件部署到访问任何一个java.io.File
对象。
Java EE服务器不需要“爆炸”文件系统中的部署,许多服务器不需要。一些供应商可能会提供这样做的选择,但总的来说,依靠这种能力并不明智。
此外,使用类加载器完全无法访问构建到EAR文件中的纯文件。
在EAR文件中,如果对象位于EAR/lib jar文件,EJB模块,RAR模块或WEB模块(WAR)中,则只能从类加载器访问对象。即使那么有关于哪些模块可以在其他模块中看到的规则,如My ear is not able to find ejb module classes
的答案中所述那就是说,您的问题指的是非标准APP-INF/lib
目录。您需要参考您的供应商文档来发现启用的内容。我隐约记得它是WebLogic或WebSphere中EAR/lib机制标准化的前身(2009年的Java EE 5中)。
为了使你的'新文件(“foo.txt”)'工作,该文件需要在当前工作目录中。要从类路径中加载数据,请使用'Classloader#getResourceAsInputStream'。不过,不确定EAR是如何工作的。不同部分的类路径可能是分开的,不能直接彼此访问。 – Thilo
确实。在我所知道的所有appservers中,简单的文件操作独立于类加载器行为。类加载器根本不会输入图片。所以,正如@Thilo所说的那样,文件名是相对于appserver进程当前工作目录解析的,无论如何。一些appservers设置了特定的CWS,有些则不。因此,在可行的情况下,用户资源加载通常更好,而不是直接加载文件。然后,你必须考虑类加载器行为,并且关于各类加载器看起来的规则在JEE规范中列出。 –