Hbase在 Windows下运行报错 IllegalArgumentException: Pathname /D:/download/repository/org/apache/.....

写在文前,本人菜鸟一个,如果文章中有说的不对的地方,还望各路大神指出,本人愿意虚心接受!

首先描述下环境。

我正在使用Hbase中java mapreduce的API(就想做个数据迁移,其实就是把A表中的数据,移动到B表中),写完了之后并没有打成jar包,在服务器上运行,只是在本地(也就是Windows环境里)做了个测试。遇到问题如下:

1、首先记录下我的开发过程。

开启服务:

这里就不写什么Hbase怎么配置了,自行脑补百度,配置好了之后,

先要开启zookeeper和hadoop的服务(这里我也不写了,实在不会的在文章下面评论,我回答你~)

然后再通过如下命令开启hbase相关服务:

bin/hbase regionserver start 

bin/hbase master start 

bin/hbase shell(这里你也可以打开你的shell交互行,看看你里面的表的状态数据之类的)

差不多就是这些服务要开启:

[beifeng@bigdata-03 ~]$ jps
3406 DataNode
4196 Main
4656 HRegionServer
4446 HMaster
7422 Jps
3786 NodeManager
4142 QuorumPeerMain
3305 NameNode
3684 ResourceManager

然后开始在Windows下写代码测试,写好代码之后(这里提醒下,要把下图这几个文件已经配置好的文件,放到自己新建的src/main/resource文件夹里面,代码我会在文章后面提供),一切准备就绪,我们就开始来解决BUG。。。。


 2、BUG

Exception in thread "main" java.lang.IllegalArgumentException: Pathname /D:/download/repository/org/apache/hbase/hbase-server/0.98.6-hadoop2/hbase-server-0.98.6-hadoop2.jar from hdfs://bigdata-03:8020/D:/download/repository/org/apache/hbase/hbase-server/0.98.6-hadoop2/hbase-server-0.98.6-hadoop2.jar is not a valid DFS filename.
	at org.apache.hadoop.hdfs.DistributedFileSystem.getPathName(DistributedFileSystem.java:187)
	at org.apache.hadoop.hdfs.DistributedFileSystem.access$000(DistributedFileSystem.java:101)
	at org.apache.hadoop.hdfs.DistributedFileSystem$17.doCall(DistributedFileSystem.java:1068)
	at org.apache.hadoop.hdfs.DistributedFileSystem$17.doCall(DistributedFileSystem.java:1064)
	at org.apache.hadoop.fs.FileSystemLinkResolver.resolve(FileSystemLinkResolver.java:81)
	at org.apache.hadoop.hdfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:1064)
	at org.apache.hadoop.mapreduce.filecache.ClientDistributedCacheManager.getFileStatus(ClientDistributedCacheManager.java:288)
	at org.apache.hadoop.mapreduce.filecache.ClientDistributedCacheManager.getFileStatus(ClientDistributedCacheManager.java:224)
	at org.apache.hadoop.mapreduce.filecache.ClientDistributedCacheManager.determineTimestamps(ClientDistributedCacheManager.java:93)
	at org.apache.hadoop.mapreduce.filecache.ClientDistributedCacheManager.determineTimestampsAndCacheVisibilities(ClientDistributedCacheManager.java:57)
	at org.apache.hadoop.mapreduce.JobSubmitter.copyAndConfigureFiles(JobSubmitter.java:265)
	at org.apache.hadoop.mapreduce.JobSubmitter.copyAndConfigureFiles(JobSubmitter.java:301)
	at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:389)
	at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1285)
	at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1282)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:415)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
	at org.apache.hadoop.mapreduce.Job.submit(Job.java:1282)
	at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1303)
	at com.beifeng.senior.hadoop.hbase.User2BasicMapReduce.run(User2BasicMapReduce.java:124)
	at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
	at com.beifeng.senior.hadoop.hbase.User2BasicMapReduce.main(User2BasicMapReduce.java:136)
看这个路径我都醉了,这是个啥。。。。

不过根据以前的经验,大概是因为在Windows下运行,程序识别文件系统时候出了差错。

现在我附上我的代码:

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class User2BasicMapReduce extends Configured implements Tool {
	
	// Tapper Class
	public static class ReadUserMapper extends TableMapper<Text, Put> {

		private Text mapOutputKey = new Text();
	
		@Override
		public void map(ImmutableBytesWritable key, Result value,
				Mapper<ImmutableBytesWritable, Result, Text, Put>.Context context)
						throws IOException, InterruptedException {
			// get rowkey
			String rowkey = Bytes.toString(key.get());

			// set
			mapOutputKey.set(rowkey);

			// --------------------------------------------------------
			Put put = new Put(key.get());

			// iterator
			for (Cell cell : value.rawCells()) {
				// add family : info
			/*	if ("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))) {
					// add column: name
					if ("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
						put.add(cell);
					}
					// add column : age
					if ("age".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
						put.add(cell);
					}
				}*/
				System.out.println(cell.toString());
				put.add(cell);
			}
			System.out.println("===================");
			// context write
			context.write(mapOutputKey, put);
		}

	}

	// Reducer Class
	public static class WriteBasicReducer extends TableReducer<Text, Put, //
	ImmutableBytesWritable> {
		
		@Override
		public void reduce(Text key, Iterable<Put> values,
				Reducer<Text, Put, ImmutableBytesWritable, Mutation>.Context context)
						throws IOException, InterruptedException {
			int count = 0;
			for(Put put: values){
				count+=1;
			System.out.println("count:"+count);
				context.write(null, put);
			}
			System.out.println("======reduce=======");
		}

	}

	// Driver
	public int run(String[] args) throws Exception {
		
		// create job
		Job job = Job.getInstance(this.getConf(), this.getClass().getSimpleName());
		
		// set run job class
		job.setJarByClass(this.getClass());
		
		// set job
		Scan scan = new Scan();
		scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
		scan.setCacheBlocks(false);  // don't set to true for MR jobs
		// set other scan attrs

		// set input and set mapper
		TableMapReduceUtil.initTableMapperJob(
		  "stu_info",        // input table
		  scan,               // Scan instance to control CF and attribute selection
		  ReadUserMapper.class,     // mapper class
		  Text.class,         // mapper output key
		  Put.class,  // mapper output value
		  job
		  //,false
		 );
		// set reducer and output
		TableMapReduceUtil.initTableReducerJob(
		  "basic",        // output table
		  WriteBasicReducer.class,    // reducer class
		  job
		  //,null,null, null, null,false
		 );
		
		job.setNumReduceTasks(1);   // at least one, adjust as required
		
		// submit job
		boolean isSuccess = job.waitForCompletion(true) ;
		
		
		return isSuccess ? 0 : 1;
	}
	
	
	public static void main(String[] args) throws Exception {
		// get configuration
		Configuration configuration = HBaseConfiguration.create();
		
		// submit job
		int status = ToolRunner.run(configuration,new User2BasicMapReduce(),args) ;
		
		// exit program
		System.exit(status);
	}

}

大家注意看我run方法中的TableMapReduceUtil.initTableMapperJob()和TableMapReduceUtil.initTableReducerJob()这两个方法,其实这两个方法重载了多个,你要是有兴趣可以点到TableMapReduceUtil里面,看到init方法有多个传参,其中有一个:

@param addDependencyJars upload HBase jars and jars for any of the configured
    *           job classes via the distributed cache (tmpjars).

然后你可以很开心的把这个检查的东西关闭(这个会打印一连串的jar包路径,在linux上是没有问题,在Windows上,它就把路径拼接得乱七八糟的),其实只要传入false值(默认是true)进去就能解决问题,修改下我上面给出的代码就可以了,代码如下:

	TableMapReduceUtil.initTableMapperJob(
		  "stu_info",        // input table
		  scan,               // Scan instance to control CF and attribute selection
		  ReadUserMapper.class,     // mapper class
		  Text.class,         // mapper output key
		  Put.class,  // mapper output value
		  job
		  ,false
		 );
		// set reducer and output
		TableMapReduceUtil.initTableReducerJob(
		  "basic",        // output table
		  WriteBasicReducer.class,    // reducer class
		  job
		  ,null,null, null, null,false
		 );

认真看下啊,其实我是用了传入参数不一样的initTableMapperJob和initTableReduceJob,然后这里的reduce方法其实什么都没做,相当于只是初始化了,不信你把initTableMapperJob方法中的WriteBasicReducer.class注释掉,传个null进去,也能够实现我们想要的结果

接着在运行一次。

就会报另外一个错,起码往前走了一步。

报错如下:

Exception in thread "main" java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
	at org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Native Method)
	at org.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:570)
	at org.apache.hadoop.fs.FileUtil.canRead(FileUtil.java:977)
	at org.apache.hadoop.util.DiskChecker.checkAccessByFileMethods(DiskChecker.java:173)
	at org.apache.hadoop.util.DiskChecker.checkDirAccess(DiskChecker.java:160)
	at org.apache.hadoop.util.DiskChecker.checkDir(DiskChecker.java:94)
	at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.confChanged(LocalDirAllocator.java:285)
	at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:344)
	at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:150)
	at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:131)
	at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:115)
	at org.apache.hadoop.mapred.LocalDistributedCacheManager.setup(LocalDistributedCacheManager.java:131)
	at org.apache.hadoop.mapred.LocalJobRunner$Job.<init>(LocalJobRunner.java:163)
	at org.apache.hadoop.mapred.LocalJobRunner.submitJob(LocalJobRunner.java:731)
	at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:432)
	at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1285)
	at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1282)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:415)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
	at org.apache.hadoop.mapreduce.Job.submit(Job.java:1282)
	at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1303)
	at com.beifeng.senior.hadoop.hbase.User2BasicMapReduce.run(User2BasicMapReduce.java:124)
	at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
	at com.beifeng.senior.hadoop.hbase.User2BasicMapReduce.main(User2BasicMapReduce.java:136)

这个错相信之前有用windows写过mapreduce的开发者,应该是会遇到过(我理解的是,文件系统的检查,导致这个问题,不知道理解的对不对)。

其实修改下源码就可以搞定了,其实没有必要把源码包里的.class文件反编译出来,修改,再重新打成jar包,你只要直接点开NativeIO这个类,然后Ctrl+A全文复制,再左键单击你的项目的文件夹(如下如点选src/main/java),最后Ctrl+V这样就会直接生成对应的包名和类。

接着修改下570行的return,注释掉原来的return,直接让代码return true就可以了。如下图:


提醒大家一下,文中给出的这两个报错,其实都是在Windows下才会出的问题,其实可以把类打成jar包,上传服务器运行,是不会报错的!!

最后再运行下程序,反正我是成功了,你要是还报错,来打爆我的狗头。。。。。没有俩,开玩笑,在下面留言,有空帮你看看。。。。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值