将SeqReader打包成可执行的jar包

时间:2022-05-18 12:34:12

SeqReader是我定义的一个读取SequenceFile文件,并将部分(key,value)打印到控制台窗口的类,其完整代码如下:

 1 /**
 2  * Created with IntelliJ IDEA.
 3  * User: hadoop
 4  * Date: 16-3-14
 5  * Time: 上午9:57
 6  * To change this template use File | Settings | File Templates.
 7  */
 8 import org.apache.hadoop.conf.Configuration;
 9 import org.apache.hadoop.fs.FileSystem;
10 import org.apache.hadoop.fs.Path;
11 import org.apache.hadoop.io.SequenceFile;
12 import org.apache.hadoop.io.Writable;
13 import org.apache.hadoop.io.IntWritable;
14 import org.apache.hadoop.io.DoubleWritable;
15 import org.apache.hadoop.io.ArrayWritable;
16 import org.apache.hadoop.util.ReflectionUtils;
17 
18 import java.io.IOException;
19 import java.net.URI;
20 
21 public class SeqReader  {
22     public static void main(String[] args) throws IOException {
23         String uri=args[0];
24         //String uri="/home/hadoop/2016Test/SeqTest/10IntArray";
25         Configuration conf=new Configuration();
26         FileSystem fs =FileSystem.get(URI.create(uri),conf);
27         Path path=new Path(uri);
28         SequenceFile.Reader reader=null;
29         //DoubleWritable[] doubleWritableArray=new DoubleWritable[Integer.parseInt(args[1])];
30 
31        /* for (int i=0;i<doubleWritableArray.length;++i){
32             doubleWritableArray[i]=new DoubleWritable(0.0);
33         }
34         */
35         try {
36             reader=new SequenceFile.Reader(fs,path,conf);
37             IntWritable key =(IntWritable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);
38             DoubleArrayWritable value=(DoubleArrayWritable)ReflectionUtils.newInstance(reader.getValueClass(),conf);
39             long position=reader.getPosition();
40             String[] sValue=null;
41             int index;
42             int counter=0;
43             StringBuilder sb=new StringBuilder();
44             while(reader.next(key,value)){
45                 if(key.get()%Integer.parseInt(args[1])==0){
46                     System.out.println("key:"+key.get());
47                     index=-1;
48                     for (Writable val:value.get()){
49                     //doubleWritableArray[++index].set(((DoubleWritable)val).get());
50                         if (counter>10){
51                             break;
52                         }
53                         counter++;
54                         sb.append(((DoubleWritable)val).get()).append(",");
55                     }
56                     System.out.println("value:"+sb.toString());
57 
58                 }
59 
60             }
61         }
62         finally {
63             //IOUtils.closeStream(reader);
64         }
65     }
66 
67 }
68 class DoubleArrayWritable extends ArrayWritable {
69     public DoubleArrayWritable(){
70         super(DoubleWritable.class);
71     }
72     /*
73     public String toString(){
74         StringBuilder sb=new StringBuilder();
75         for (Writable val:get()){
76             DoubleWritable doubleWritable=(DoubleWritable)val;
77             sb.append(doubleWritable.get());
78             sb.append(",");
79         }
80         sb.deleteCharAt(sb.length()-1);
81         return sb.toString();
82     }
83     */
84 }

 关于生成可执行jar包,这里只说几点需要注意的地方,详细信息可以参考:http://www.cnblogs.com/lz3018/p/5228639.html

1)首先就是MANIFEST.MF文件的配置,应该保证配置完成之后,文件有一个空白行,使用gedit编辑此文件,打开“显示行号”功能。

将SeqReader打包成可执行的jar包

 

前4行是我们配置的有效内容,第5行就是我们文件需要的空白行,第6行是目前准备写入字符的行,此时我们就保存文件,那我们文件内容就是包含有字符的前四行,外加一个空白行,也就是我们文件总共有5行。

2)对于Main-Class,当我们的类中没有定义包名的话,那么只需要写主类名称就可以了。(只有eclipse中采用默认包名就是类名这一说法吧)

3)当我们使用jar cfm SeqWriter.jar MANIFEST.MF *.class重新打jar包之后,使用命令java -jar SeqWriter.jar part-r-00000 1000运行jar包时,提示"NoClassDefFoundError":

将SeqReader打包成可执行的jar包

也就是找不到类 /org/apache/commons/logging/LogFactorty,这个类是在commons-logging-1.1.1中,我们只需要添加这个jar包就可以了,怎么添加了,就是在MANIFEST.MF文件在添加Class-Path属性,给属性配置这个jar包的路径就可以了(多个jar包用空格分隔),完成上述操作之后,使用jar命令重新生成jar包,再使用java -jar执行jar包,然后又出现如下提示:

将SeqReader打包成可执行的jar包

还是找不到类,仍然是按照上述方法将commons-configuration-1.6.jar的路径添加到Class-Path中,再重新打包、运行·,如下:

将SeqReader打包成可执行的jar包

同样的,将comons.lang-2.4.jar的路径添加到Class-Path中,然后重新打包、运行,结果如下所示:
将SeqReader打包成可执行的jar包

成功运行。