hadoop权威指南第四章讲到了压缩的问题,其中有一示例程序StreamCompressor,该程序压缩从标准输入读取的数据,然后将其写到标准输出。
程序如下:StreamCompressor.java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.util.ReflectionUtils;
// vv StreamCompressor
public class StreamCompressor {
public static void main(String[] args) throws Exception {
String codecClassname = args[0];
Class<?> codecClass = Class.forName(codecClassname);
Configuration conf = new Configuration();
CompressionCodec codec = (CompressionCodec)
ReflectionUtils.newInstance(codecClass, conf);
CompressionOutputStream out = codec.createOutputStream(System.out);
IOUtils.copyBytes(System.in, out, 4096, false);
out.finish();
}
}
// ^^ StreamCompressor
我们可以在Eclipse下运行生成StreamCompressor.class文件,或者使用命令:
javac -classpath /home/hadoop-2.2.0/share/hadoop/common/hadoop-common-2.2.0.jar StreamCompressor.java
生成StreamCompressor.class文件。(在hadoop2.2.0下,hadoop1.2.1下同理)
然后通过命令:
echo "Text" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec | gunzip
运行程序,正常情况下应该输出字符:Text,但程序在运行时出现出错:
“找不到或无法加载主类StreamCompressor”
在苦思无果之后,求助于赛赛同学,终于明白了错误在哪里,并且学到了分析问题的方法,因此特地记录下来,作为纪念。
首先从程序错误可以看出,在使用hadoop命令运行程序时,在hadoop指定的classpath中无法找到StreamCompressor,因此我们的解决方
法就是找到hadoop指定的classpath,并把StreamCompressor加入进去就可以了。
所以我们打开/hadoop1.2.1/bin/目录下的hadoop文件,里面是一长段的脚本文件,我们可以在每一段脚本之间加入“ echo 'line1'”来标识程
序运行到了什么位置,最终定位到程序运行到哪里时出错的。
最终我们发现程序执行到如下位置时出错:
果然是CLASSPATH出了问题!所以解决方法1:
将“CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar”更改为:“CLASSPATH=‘.:’${CLASSPATH}:$JAVA_HOME/lib/tools.jar”
即将当前目录也添加到classpath中,这样hadoop就可以找到类了,实验验证成功!(这种做法更改了hadoop文件,慎用)
第二种方法:
在hadoop文件最后添加语句“echo $CLASSPATH > /home/1.txt”,将classpath输出到一个文件,再在文件中查找目录(classpath中绝大部
分都是jar文件),该目录即有可能是hadoop默认的classpath查找目录,把StreamCompressor.class文件放到目录中再运行,实验验证成
功。hadoop1.2.1的classpath中只包含一个目录:/hadoop1.2.1/conf,因此将文件放入该目录即可。在hadoop2.2.0中,包含的目录
为:/hadoop-2.2.0/etc/hadoop/,放入该目录即可。
第三种方法:
我们在运行URLCat程序时曾经有一种做法,即将class文件打成jar包,然后将jar包放入目录/hadoop-2.2.0/share/hadoop/common目录,之
后使用hadoop jar命令执行。这种做法同样有用,并且这样做以后,在其他目录下执行
echo "Text" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec | gunzip
命令时,StreamCompressor都可以被找到。