Hive的--auxpath使用相对路径遇到的一个奇怪的异常

来源:互联网 发布:217淘宝站外平台哪个好 编辑:程序博客网 时间:2024/06/05 19:39
在使用Hive的--auxpath过程中,如果我使用的是相对路径(例如,--auxpath=abc.jar),会产生下面的一个异常:
java.lang.IllegalArgumentException: Can not create a Path from an empty string
     at org.apache.hadoop.fs.Path.checkPathArg(Path.java:91)
     at org.apache.hadoop.fs.Path.<init>(Path.java:99)
     at org.apache.hadoop.fs.Path.<init>(Path.java:58)
     at org.apache.hadoop.mapred.JobClient.copyRemoteFiles(JobClient.java:619)
     at org.apache.hadoop.mapred.JobClient.copyAndConfigureFiles(JobClient.java:724)
     at org.apache.hadoop.mapred.JobClient.copyAndConfigureFiles(JobClient.java:648)
 
从异常的内容来看,是由于使用了一个空字符串来创建一个Path对象。
 
经过分析发现,使用"--auxpath=abc.jar"来启动Hive时,Hive会自动在abc.jar前面补上"file://"。也就是说Hive最后使用的路径是"file://abc.jar"。
当我们使用"file://abc.jar"来生成一个Path时,调用这个Path的getName将会返回""(空字符串)。而Hive在提交MapReduce的Job时,会使用getName来获取文件名,并创建一个新的Path对象。下面的示例代码演示了一下这个过程,会抛出上文提到的异常(Hadoop的代码本身比较复杂,有兴趣看源码的可以点这里)。
1Path path = new Path("file://abc.jar");
2System.out.println("path name:" + path.getName());
3System.out.println("authority:" + path.toUri().getAuthority());
4Path newPath = new Path(path.getName());
上文的代码输出
path name:
authority:abc.jar
并抛出了异常"Can not create a Path from an empty string"
 
那么为什么"file://abc.jar"生成的Path的getName返回的是""而不是"abc.jar"呢,而且"abc.jar"却成了authority?在Path中的处理代码如下:
01if (pathString.startsWith("//", start) &&
02    (pathString.length()-start > 2)) {       // has authority
03  int nextSlash = pathString.indexOf('/', start+2);
04  int authEnd = nextSlash > 0 ? nextSlash : pathString.length();
05  authority = pathString.substring(start+2, authEnd);
06  start = authEnd;
07}
08

09// uri path is the rest of the string -- query & fragment not supported
10String path = pathString.substring(start, pathString.length());
pathString就是传进去的"file://abc.jar",由于我们只有两个"/"因此,从第二个"/"到结尾的字符串("abc.jar")都被当成了authority,path(内部的成员)则设置成了""而getName返回的就是path,因此也就为""了。
 
因此,如果使用Hive的--auxpath来设置jar,必须使用绝对路径,或者使用"file:///.abc.jar"这样的表示法。这个才是Hadoop的Path支持的方式。事实上,hadoop许多相关的Path的设置,都存在这个问题,所以在无法确定的情况下,就不要使用相对路径了。
0 0