spark读取jar中文件的路径问题

  上周和这周的前两天一直在解决工作中遇到的一个问题,问题的背景是这样的:我们搭建的平台中使用了lucene的IKAnalyzer分词工具,该工具在进行分词时会先读取resource文件夹下的config文件,每次在本地跑ut测试的时候都能顺利通过,但是放到集群上执行的时候会报找不到config文件路径的错误。问题很清楚,但是就是不知道为什么无法找到文件,最后把路径信息打出来发现其中有个“!”,才知道问题的根结在于读取文件的方式。

  先说说java中获取文件路径的几种方式,工程的目录结构如下



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

public void testPath() {
// 第一种:获取类加载的根路径
URL url1 = this.getClass().getResource("/");
System.out.println(url1.getPath());
//输出:/Users/name/test/target/classes/

// 第二种:获取当前类的所在工程路径(不加“/”)
URL url2 = this.getClass().getResource("");
System.out.println(url2.getPath());
//输出:/Users/name/test/target/classes/test/

// 第三种:在资源加载的过程中,使用的逐级向上委托的形式加载,不能以“/”开头
URL url3 =this.getClass().getClassLoader().getResource("");
System.out.println(url3.getPath());
//输出:file:/Users/name/test/target/classes/
URL url4 =this.getClass().getClassLoader().getResource("/");
System.out.println(url3.getPath());
//输出:null

}

  在正常情况下我们可以按照以上方法进行文件的读取,但是当我们把项目打成jar包,使用java -jar运行时,上述方法会在第一个打印方法出报空指针,这说明单独运行jar的时候上述读取文件的方法已经失效,但是我们采用下面的方法仍然可以进行文件的读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
public void testStream() throws IOException {
InputStream in = this.getClass().getResourceAsStream("/folder/3.txt");
int temp = 0;
byte[] bytes = new byte[1024];
int len = 0;
while ((temp = in.read()) != -1) {
bytes[len] = (byte) temp;
len++;
}
in.close();
String content = new String(bytes,0,len);
System.out.println(content);
}

采用getResourceAsStream再运行打出来的jar包就没有问题了。

  起初一直以为是spark运行jar的问题,后来才发现是java读取资源方式有错误。其实这个问题之前在进行web开发时遇到过,当时使用weblogic服务器,总是读取不到resource文件夹下的配置文件,后来也是采用getResourceAsStream的方法才读出来。然而在tomcat服务器下采用getResource的方式可以正常读取,因为tomcat服务器会解析放入的jar包,而weblogic却不会,运行机制不一样导致读取文件的方式也不一样。

  解决完问题后想想这次的bug和之前遇到的本质是一个问题,之前遇到问题解决后也没有仔细思考,还以为是weblogic的特例,也就没有把经验积累下来。虽然这次后知后觉耽误了不少时间,但是印象更加深刻了,工作中遇到的坑还是应该记下来多看看,多总结。

-------------本文结束感谢您的阅读-------------

本文标题:spark读取jar中文件的路径问题

文章作者:小建儿

发布时间:2017年10月28日 - 20:10

最后更新:2018年06月25日 - 20:06

原始链接:http://yajian.github.io/spark读取jar中文件的路径问题/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。