Exception in thread “main“ java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$PO

Exception in thread “main” java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO P O S I X . s t a t ( L j a v a / l a n g / S t r i n g ; ) L o r g / a p a c h e / h a d o o p / i o / n a t i v e i o / N a t i v e I O POSIX.stat(Ljava/lang/String;)Lorg/apache/hadoop/io/nativeio/NativeIO POSIX.stat(Ljava/lang/String;)Lorg/apache/hadoop/io/nativeio/NativeIOPOSIX$Stat;

报错如下图所示
在这里插入图片描述
报错原因:就是你导入的依赖的hadoop版本和你本地window的hadoop版本不匹配的而导致的,解法方法就是把导入的依赖的版本换成和window版本一样的就可以了。
解决方法如下:
之前导入的依赖是:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Mapreduce</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!--设置项目的编码为UTF-8-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--使用java8进行编码-->

        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!--设置hadoop的版本-->
        <hadoop.version>3.1.2</hadoop.version>

    </properties>
    <!--jar包的依赖-->
    <dependencies>
        <!--测试的依赖坐标-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <!--日志打印的依赖坐标-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.2</version>
        </dependency>
        <!--hadoop的通用模块的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <!--hadoop的对HDFS分布式文件系统访问的技术支持的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <!--hadoop的客户端访问的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
    </dependencies>


</project>

也就是说我之前导入的依赖版本是3.1.2,和我虚拟机上面是一样的,而我自己本地的是:
在这里插入图片描述

所有就把导入的依赖换成了本地有的3.0.0

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>java</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <hadoop.version>3.0.0</hadoop.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.0.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
        </dependency>
        <!--hadoop的通用模块的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <!--hadoop的对HDFS分布式文件系统访问的技术支持的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <!--hadoop的客户端访问的依赖坐标-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
    </dependencies>


</project>

然后重写运行mapreduce经典案例倒排索引
代码如下:

package com.atguigu.mapreduce.mapreducedemo;
import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class InvertedIndex {

    public static class Map extends Mapper<Object, Text, Text, Text> {
        private Text keyInfo = new Text(); // 存储单词和URL组合
        private Text valueInfo = new Text(); // 存储词频
        private FileSplit split; // 存储Split对象
        // 实现map函数
        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            // 获得<key,value>对所属的FileSplit对象
            split = (FileSplit) context.getInputSplit();
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                // key值由单词和URL组成,如"MapReduce:file1.txt"
                // 获取文件的完整路径
                // keyInfo.set(itr.nextToken()+":"+split.getPath().toString());
                // 这里为了好看,只获取文件的名称。
                int splitIndex = split.getPath().toString().indexOf("file");
                keyInfo.set(itr.nextToken() + ":" + split.getPath().toString().substring(splitIndex));
                // 词频初始化为1
                valueInfo.set("1");
                context.write(keyInfo, valueInfo);
            }
        }
    }

    public static class Combine extends Reducer<Text, Text, Text, Text> {
        private Text info = new Text();
        // 实现reduce函数
        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            // 统计词频
            int sum = 0;
            for (Text value : values) {
                sum += Integer.parseInt(value.toString());
            }
            int splitIndex = key.toString().indexOf(":");
            // 重新设置value值由URL和词频组成
            info.set(key.toString().substring(splitIndex + 1) + ":" + sum);
            // 重新设置key值为单词
            key.set(key.toString().substring(0, splitIndex));
            context.write(key, info);
        }
    }

    public static class Reduce extends Reducer<Text, Text, Text, Text> {
        private Text result = new Text();
        // 实现reduce函数
        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            // 生成文档列表
            String fileList = new String();
            for (Text value : values) {
                fileList += value.toString() + ";";
            }
            result.set(fileList);
            context.write(key, result);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();


        Job job = Job.getInstance(conf);
        job.setJarByClass(InvertedIndex.class);

        // 设置Map、Combine和Reduce处理类
        job.setMapperClass(Map.class);
        job.setCombinerClass(Combine.class);
        job.setReducerClass(Reduce.class);

        // 设置Map输出类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        // 设置Reduce输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        // 设置输入和输出目录
        FileInputFormat.addInputPath(job, new Path("D:\\input"));
        FileOutputFormat.setOutputPath(job, new Path("D:\\output"));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

运行结果:

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Process finished with exit code 0

### 回答1: 这是一个Java程序中的异常错误,错误信息为“exception in thread "main" java.lang.unsatisfiedlinkerror: org.apache.hadoop.io.nativeio.nativeio$windows.createdirectorywithmode(ljava/lang/string;i)v”。该错误通常是由于缺少本地库文件或库文件版本不匹配导致的。可能需要检查Java程序中使用的库文件是否正确安装和配置。 ### 回答2: 该错误信息表明在Java程序执行过程中,出现了无法满足链接的错误。具体来说,是指程序试图调用 org.apache.hadoop.io.nativeio 包下的 nativeio 类中的 windows.createdirectorywithmode0 方法时,发现没有找到或无法链接到对应的本地库文件,导致方法调用失败。 出现该错误的原因可能有多种,常见的包括: 1. 本地库文件缺失或损坏: nativeio 类中的 windows.createdirectorywithmode0 方法需要依赖对应的本地库文件进行实现,如果该文件不存在、路径错误、损坏等,则会导致无法链接的错误出现。 2. 操作系统不兼容: nativeio 类中的 windows.createdirectorywithmode0 方法可能会因为操作系统不符合要求而无法链接,例如该方法只能在 Windows 操作系统上运行,如果在其他操作系统上执行,就会出现无法满足链接的错误。 3. JDK 版本不兼容: 某些 nativeio 库文件可能需要依赖特定版本的 JDK 才能正确链接,如果使用了不兼容的 JDK 版本,则会出现无法满足链接的错误。 解决该错误的方法也有多种,可以尝试以下几种: 1. 检查本地库文件: 检查是否存在该本地库文件,路径是否正确,是否有权限访问等。同时也要确保本地库文件版本与操作系统、JDK 版本兼容。 2. 使用合适的 JDK 版本: 尝试使用与该 nativeio 库文件兼容的 JDK 版本。可以尝试升级或降级 JDK 版本,重新编译和运行程序。 3. 修改操作系统: 如果该方法只能在特定的操作系统上运行,可以尝试在对应的操作系统上执行程序,或寻找适合的替代方法。 4. 编写异常处理代码: 如果无法找到合适的解决方法,可以在程序中增加异常处理代码,捕捉该异常并输出错误信息,以便于在运行时及时排查错误。 ### 回答3: 这个错误信息表示在Java程序中调用了一个本地方法,但是这个本地方法的实现在当前系统环境下无法找到或者无法使用。具体来说,这个错误信息中的org.apache.hadoop.io.nativeio.nativeio$windows.createdirectorywithmode0(ljava/lang/string;i)v就是一个Java程序中调用的本地方法,它的作用是在Windows系统中创建一个带有指定权限的目录。但是,当Java程序在当前的系统环境下运行时,发现没有找到这个本地方法的实现,所以就抛出了这个异常。 造成这个错误的原因可能有多种,比如本地方法库文件的路径配置错误、Java虚拟机版本和本地方法库版本不兼容等等。解决这个错误的方法也有多种,具体要根据具体情况来定。一般来说,下面几个方法可能会有所帮助: 1. 检查程序所依赖的本地方法库文件是否存在,并且路径是否设置正确。 2. 检查Java虚拟机和本地方法库之间的版本兼容性。 3. 尝试更新Java虚拟机和本地方法库的版本。 4. 尝试使用不同的本地方法库实现。 5. 尝试使用不同的操作系统环境或者其他设备来运行程序,看看是否能够正常工作。 总之,这个错误信息看起来比较复杂,但其实就是一个简单的错误提示,意思是Java程序中调用的本地方法没有找到实现。要解决此问题需要具体情况具体分析,排除一些常规问题,然后才能有效解决。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值