将windows中HDFS-javaAPI文件打包,在linux的hadoop平台运行

目录

运行前提

一、打包

[方式 1:IDEA 标准 Artifacts 打包](#方式 1:IDEA 标准 Artifacts 打包)

[1.顶部菜单 File → Project Structure(快捷键 Ctrl+Alt+Shift+S)](#1.顶部菜单 File → Project Structure(快捷键 Ctrl+Alt+Shift+S))

[2.左侧 Artifacts → 右上角 + → JAR → From modules with dependencies](#2.左侧 Artifacts → 右上角 + → JAR → From modules with dependencies)

配置弹窗

[3.顶部菜单 Build → Build Artifacts → 选中你的 jar → Build​编辑](#3.顶部菜单 Build → Build Artifacts → 选中你的 jar → Build编辑)

4.注意

[方式 2:Maven 打包(最通用,企业首选)](#方式 2:Maven 打包(最通用,企业首选))

[1)pom.xml 添加打包配置 & 主类](#1)pom.xml 添加打包配置 & 主类)

2)执行打包

3)注意

二、在linux系统中的hadoop平台执行

1、hadoop已经启动,hadoop命令可执行

2、安全模式已经退出

[3、将打包的jar包上传到linux平台中,并使用命令chmod 755添加执行权限](#3、将打包的jar包上传到linux平台中,并使用命令chmod 755添加执行权限)

4、执行jar包

附1:MkdirDemo代码

[附2:hadoop jar命令使用说明](#附2:hadoop jar命令使用说明)

附3:打包时,是否将依赖打包进入说明

[1、Hadoop 相关依赖](#1、Hadoop 相关依赖)

关键改动说明

[1. 依赖 scope 调整](#1. 依赖 scope 调整)

[2. 彻底移除 maven-assembly-plugin](#2. 彻底移除 maven-assembly-plugin)

[3. shade 插件核心能力](#3. shade 插件核心能力)

[4. 集群运行命令(适配 hadoop jar)](#4. 集群运行命令(适配 hadoop jar))

[方式 1:使用 shaded 大包(内置 log4j 依赖,无需额外传参)](#方式 1:使用 shaded 大包(内置 log4j 依赖,无需额外传参))

[方式 2:纯净小包 + -libjars 动态加载第三方依赖(包体积更小)](#方式 2:纯净小包 + -libjars 动态加载第三方依赖(包体积更小))

配套避坑操作

[附4:打包时指定主类,hadoop jar xxx.jar 直接运行(不用写主类名)](#附4:打包时指定主类,hadoop jar xxx.jar 直接运行(不用写主类名))

原理

[方案 1:maven-shade 插件(你现在使用的 pom,推荐)](#方案 1:maven-shade 插件(你现在使用的 pom,推荐))

[方案 2:原生 maven-jar-plugin(无第三方依赖,轻量包),不适合此项目](#方案 2:原生 maven-jar-plugin(无第三方依赖,轻量包),不适合此项目)

关键注意事项


运行前提

1、linux中hadoop配置完成,jps显示进程正确

2、linux中hadoop命令可以运行

3、linux中已经退出hadoop安全模式

一、打包

方式 1:IDEA 标准 Artifacts 打包

1.顶部菜单 File → Project Structure(快捷键 Ctrl+Alt+Shift+S
2.左侧 Artifacts → 右上角 +JAR → From modules with dependencies
配置弹窗
  • Module:选择你的当前项目
  • Main class:选中你的 MkdirDemo(包含 main 方法的主类)
  • Extract to the target JAR(把依赖打进 jar,避免 Linux 缺包报错)
  • Directory for META-INF需要改为resource路径
  • Apply → OK
3.顶部菜单 Build → Build Artifacts → 选中你的 jar → Build

生成 jar 路径:项目根目录 out/artifacts/xxx_jar/xxx.jar

4.注意

Directory for META-INF需要改为resource路径,否则

打包 Jar 时,IDEA 自动在 src/main/java 下生成了 META-INF/MANIFEST.MF;再次打包时工具尝试重新生成,触发冲突。如下图所示

方式 2:Maven 打包(最通用,企业首选)

1)pom.xml 添加打包配置 & 主类
复制代码
<build>
    <plugins>
        <!-- maven打包插件,指定主类,打包所有依赖 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <archive>
                    <manifest>
                        <!-- 填写你的主类全限定名 -->
                        <mainClass>MkdirDemo</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <!-- 将所有依赖打入一个jar包 -->
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

完整pom.xml文件为:

java 复制代码
<?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>HDFS-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.19.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- maven打包插件,指定主类,打包所有依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <archive>
                        <manifest>
                            <!-- 填写你的主类全限定名 -->
                            <mainClass>MkdirDemo</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <!-- 将所有依赖打入一个jar包 -->
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>
2)执行打包

右侧 Maven 面板 → Lifecycle → package,双击执行

完成后显示finished

打包完成后,jar 包在 项目/target/xxx-jar-with-dependencies.jar

3)注意

如果打包后,再次打包报错 Process terminated

原因分析:Process terminated 不是具体异常,代表 Maven 打包进程被系统 / IDE 强制终止,最常见诱因是内存溢出、JDK/Maven 版本不兼容、pom 插件配置错误、IDEA 运行器配置异常 ,尤其你使用jar-with-dependencies(依赖全打进包)时依赖多,极易内存爆掉。

解决方案:File → Invalidate Caches... 勾选:Clear file system cache and local history → Invalidate and Restart即可

方式3:直接使用mvn命令

1:IDEA 内置 Terminal 终端(推荐,不用切文件夹)
  1. IDEA 底部打开 Terminal
  2. 直接执行清理 + 打包一条命令:

运行

复制代码
mvn clean package
  • clean:删除旧 target 文件夹、旧 jar,彻底清空
  • package:编译代码、执行 assembly 插件打包
2:Windows CMD/PowerShell 手动执行
  1. CMD cd 切换到你的项目根目录(pom.xml 所在文件夹) 示例:

    cd D:\javaweb\HDFS-helloworld

  2. 执行打包:

    mvn clean package

三、打包成功标志

终端输出 BUILD SUCCESS jar 包生成路径: 项目目录/target/HDFS-helloworld-1.0-jar-with-dependencies.jar

二、在linux系统中的hadoop平台执行

1、hadoop已经启动,hadoop命令可执行

2、安全模式已经退出

3、将打包的jar包上传到linux平台中,并使用命令chmod 755添加执行权限

4、执行jar包

附1:MkdirDemo代码

主要功能是在/目录下创建bigdata文件夹

java 复制代码
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

public class MkdirDemo {
    public static FileSystem getFileSystem() throws IOException, URISyntaxException, InterruptedException {
        Configuration conf=new Configuration();
        URI url=new URI("hdfs://192.168.17.128:9000");
        final FileSystem fileSystem=FileSystem.get(url,conf,"root");
        return fileSystem;
    }

    public static  void list(String dir) throws Exception{
        FileSystem fileSystem=getFileSystem();
        FileStatus[] listStatus=fileSystem.listStatus(new Path(dir));
        for(FileStatus fileStatus : listStatus){
            boolean isDir=fileStatus.isDirectory();
            String name=fileStatus.getPath().toString();
            System.out.println(isDir+" "+name);
        }
    }

    public static void mkdir(String path) throws Exception{
        final FileSystem fileSystem=getFileSystem();
        fileSystem.mkdirs(new Path(path));
        //遍历文件夹下的内容
        list("/");
    }

    public static void create(String path) throws Exception{
        final FileSystem fileSystem=getFileSystem();
        fileSystem.create(new Path(path));
        //遍历文件夹下的内容
        list("/");
    }

    public static void delete(String path) throws Exception{
        final FileSystem fileSystem=getFileSystem();
        fileSystem.delete(new Path(path),true);
        //遍历文件夹下的内容
        list("/");
    }

    public static void main(String[] args) throws Exception{
        mkdir("/bigdata");

//        delete("bigdata");

//        create("demo.txt");

    }
}

附2:hadoop jar命令使用说明

hadoop jar jar包路径 主类全名

hadoop jar HDFS-helloworld.jar MkdirDemo

命令说明:

  • hadoop 调用 Hadoop 客户端脚本,加载 Hadoop 运行环境、自带 HDFS/MapReduce 所有依赖包。
  • jar 是 hadoop 子命令,专门用来执行打包好的 Java Jar 程序,底层会启动一个内置 JVM。
  • HDFS-helloworld.jar 你的本地 Jar 包文件路径(当前目录下的 MkdirDemo.jar),里面存放编写 HDFS 操作代码(创建目录)。
  • MkdirDemo是Jar 包内程序入口主类全名(不带包名则代表主类在默认包),等价于 java -cp xxx.jar MkdirDemo。

附3:打包时,是否将依赖打包进入说明

此处只针对场景为:HDFS操作+MR操作。

1、Hadoop 相关依赖

不需要打进 Jar 包,编译时保留、打包剔除集群执行用 hadoop jar 命令时,程序运行依赖的 Hadoop 核心包(hadoop-common、hadoop-hdfs、mapreduce、yarn 等)全部由集群服务自带,运行时自动加载,不用打入自己的业务 Jar。

Maven 中统一设置依赖作用域 provided:

XML 复制代码
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.3.4</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>3.3.4</version>
    <scope>provided</scope>
</dependency>
  • provided 含义:IDE 编译、写代码时提供依赖;打包时不会把这些 jar 打进你的包,完美规避大包冲突、内存溢出。
  • 优势:解决之前 jar-with-dependencies 打包过大、进程中断、类版本冲突的问题。
  • 同时删除原来添加的 maven-assembly-plugin 完整配置
  • 无第三方依赖:只用原生 maven-jar-plugin
  • 有第三方依赖:改用 maven-shade-plugin,并过滤所有 hadoop 类,不使用 assembly 打包后用命令执行

hadoop jar 你的包.jar 主类全路径

补充:shade 和 provided 搭配是安全的shade 可以手动配置过滤规则,主动排除org/apache/hadoop/**,配合 provided 双重保险,不会冲突:

XML 复制代码
<filter>
    <artifact>*:*</artifact>
    <excludes>
        <exclude>org/apache/hadoop/**</exclude>
        <exclude>org/apache/mapreduce/**</exclude>
        <exclude>org/apache/hdfs/**</exclude>
    </excludes>
</filter>

此时原pom.xml文件

XML 复制代码
<?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>HDFS-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.19.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- maven打包插件,指定主类,打包所有依赖 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <archive>
                        <manifest>
                            <!-- 填写你的主类全限定名 -->
                            <mainClass>MkdirDemo</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <!-- 将所有依赖打入一个jar包 -->
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

变为:

XML 复制代码
<?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>HDFS-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hadoop.version>3.1.3</hadoop.version>
    </properties>

    <dependencies>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- Hadoop全部核心依赖 scope=provided 编译用,打包剔除 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- 第三方日志依赖(非Hadoop自带,会被shade打进包) -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.19.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 基础编译打包插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
            </plugin>

            <!-- Shade插件:只打包第三方依赖,过滤所有Hadoop类,替代assembly -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.5.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <!-- 过滤所有Hadoop集群自带类,不打进Jar,彻底避免冲突 -->
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>org/apache/hadoop/**</exclude>
                                        <exclude>org/apache/yarn/**</exclude>
                                        <exclude>org/apache/mapreduce/**</exclude>
                                        <exclude>org/apache/hdfs/**</exclude>
                                        <exclude>org/apache/hadoop/hdfs/**</exclude>
                                    </excludes>
                                </filter>
                            </filters>

                            <!-- 自动生成MANIFEST,指定程序入口主类,无需手动创建META-INF -->
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <!-- 替换为你的完整主类名,如果有包名必须写全包名,例:com.bigdata.MkdirDemo -->
                                    <mainClass>MkdirDemo</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
关键改动说明
1. 依赖 scope 调整
  • 所有hadoop-*依赖增加 <scope>provided</scope>:Maven 打包时不会把这些依赖打入 jar
  • junit 设置 <scope>test</scope>:仅测试阶段生效,打包不会带入测试类
  • log4j-core 保留默认 compile:属于第三方日志包,shade 会将其打进 jar
2. 彻底移除 maven-assembly-plugin

原 assembly 的jar-with-dependencies会无视 provided 强制打包全部 Hadoop 依赖,和集群自带 Hadoop 类产生冲突,直接删除。

3. shade 插件核心能力
  1. 自动过滤所有org/apache/hadoop/**相关 class,双重保险配合 provided
  2. 仅打包你的业务代码 + log4j 等第三方自定义依赖
  3. 自动生成合法 MANIFEST.MF,不会出现 IDE already exists in VFS 报错
  4. 打包后生成两个 jar:
    • HDFS-helloworld-1.0-SNAPSHOT.jar:纯净业务包
    • HDFS-helloworld-1.0-SNAPSHOT-shaded.jar:内置第三方依赖的可运行包
4. 集群运行命令(适配 hadoop jar)
方式 1:使用 shaded 大包(内置 log4j 依赖,无需额外传参)

bash

运行

复制代码
hadoop jar HDFS-helloworld-1.0-SNAPSHOT-shaded.jar
方式 2:纯净小包 + -libjars 动态加载第三方依赖(包体积更小)

bash

运行

复制代码
hadoop jar HDFS-helloworld-1.0-SNAPSHOT.jar MkdirDemo -libjars log4j-core-2.19.0.jar

配套避坑操作
  1. 删除项目内手动创建的 src/main/java/META-INF 文件夹,避免 VFS 文件冲突
  2. 自定义配置文件、自定义 MANIFEST 资源统一放到 src/main/resources/META-INF
  3. IDE 本地调试时如果报类找不到,临时把 Hadoop 依赖 scope 改为compile,打包上线切回provided
  4. 打包前执行 mvn clean package,先清空旧 target 目录

附4:打包时指定主类,hadoop jar xxx.jar 直接运行(不用写主类名)

原理

hadoop jar 读取 Jar 内部 META-INF/MANIFEST.MF 里的 Main-Class 属性,如果配置了,命令行可以省略主类全名,直接传业务参数。

下面分两种场景:普通 maven-jar(无第三方依赖)、shade 打包(带第三方依赖,你当前 pom 方案)

方案 1:maven-shade 插件(你现在使用的 pom,推荐)

shade 通过 ManifestResourceTransformer 自动写入 Main-Class,无需手动创建 META-INF 文件,完美规避 IDE VFS 文件重复报错。

关键配置片段(已整合到你之前优化后的 pom)

XML 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.5.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <!-- 过滤hadoop依赖,防止冲突 -->
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>org/apache/hadoop/**</exclude>
                            <exclude>org/apache/yarn/**</exclude>
                            <exclude>org/apache/mapreduce/**</exclude>
                        </excludes>
                    </filter>
                </filters>
                <!-- 自动生成MANIFEST,配置默认主类 -->
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <!-- 这里替换成你的完整主类名,有包必须写全包名,例如 com.test.MkdirDemo -->
                        <mainClass>MkdirDemo</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

使用效果打包后生成 xxx-shaded.jar,执行命令直接省略主类:

无需写 MkdirDemo,直接运行

hadoop jar HDFS-helloworld-1.0-SNAPSHOT-shaded.jar

方案 2:原生 maven-jar-plugin(无第三方依赖,轻量包),不适合此项目

如果你的项目没有 log4j 等第三方包,只用基础打包插件,通过 manifestEntries 配置主类:

XML 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifest>
                <!-- 自动生成Main-Class -->
                <mainClass>MkdirDemo</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

运行命令:

hadoop jar HDFS-helloworld-1.0-SNAPSHOT.jar

此时完整pom.xml文件为:

XML 复制代码
<?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>HDFS-helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hadoop.version>3.1.3</hadoop.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- Hadoop依赖全部provided,打包不打入 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- 第三方日志依赖,shade会打入包内 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.19.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 基础打包插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
            </plugin>

            <!-- Shade插件:过滤hadoop依赖 + 配置默认主类 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.5.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>org/apache/hadoop/**</exclude>
                                        <exclude>org/apache/yarn/**</exclude>
                                        <exclude>org/apache/mapreduce/**</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <!-- 核心:设置Jar默认主类 -->
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <!-- 重点:替换为你项目的完整类名!! -->
                                    <mainClass>MkdirDemo</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
关键注意事项
  1. 主类必须写全限定名 如果你的类在包下,比如 com.bigdata.MkdirDemo,不能只写 MkdirDemo,否则运行报错找不到类。

  2. 禁止手动创建 src/main/java/META-INF/MANIFEST.MF Maven/shade 会自动生成清单文件,手动创建会触发 already exists in VFS IDE 报错。

  3. 打包执行命令,运行

    复制代码
    mvn clean package

    target 目录会生成两个包:

    • HDFS-helloworld-1.0-SNAPSHOT.jar:纯净源码包,无第三方依赖,不带自动主类(需要手动传主类名)
    • HDFS-helloworld-1.0-SNAPSHOT-shaded.jar:内置第三方依赖,配置好默认主类,直接用 hadoop jar 运行