【工作笔记】- maven-shade-plugin打包合并META-INF/services

2023-11-08

今天在项目终于到一个问题,我写了一个简单的Flink-SQL的Demo工程,只有一个主类:

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;

public class SqlMockTask {
    public static void main(String[] args) throws Exception{
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
        
        tableEnv.executeSql("CREATE TABLE Orders_Table (\n" +
                "    order_number BIGINT,\n" +
                "    price        DECIMAL(32,2),\n" +
                "    buyer        ROW<first_name STRING, last_name STRING>,\n" +
                "    order_time   TIMESTAMP(3)\n" +
                ") WITH (\n" +
                "  'connector' = 'datagen',\n" +
                "  'rows-per-second' = '1'" +
                ")");

        tableEnv.executeSql("CREATE TABLE Print_Table (\n" +
                "    order_number BIGINT,\n" +
                "    price        DECIMAL(32,2),\n" +
                "    buyer        ROW<first_name STRING, last_name STRING>,\n" +
                "    order_time   TIMESTAMP(3)\n" +
                ") WITH (\n" +
                "  'connector' = 'print'\n" +
                ")");

        tableEnv.executeSql("INSERT INTO Print_Table SELECT * FROM Orders_Table");

        env.execute();
    }
}

POM文件是这样的

<?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>com.chinaums.dss</groupId>
    <artifactId>flink-mock</artifactId>
    <version>1.0-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
		<maven.compiler.source>${java.version}</maven.compiler.source>
		<maven.compiler.target>${java.version}</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<flink.version>1.16.0</flink.version>
		<slf4j.version>1.7.15</slf4j.version>
		<log4j.version>2.12.1</log4j.version>
		<fastjson.version>1.2.83</fastjson.version>
	</properties>

	<dependencies>
		<!-- flink start-->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-planner_2.12</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-api-java-bridge</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-api-java</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-clients</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<!-- flink end-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>RELEASE</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<!-- 指定maven编译方式为jdk1.8版本 -->
	<profiles>
		<profile>
			<id>prod</id>
			<activation>
				<activeByDefault>true</activeByDefault>
				<jdk>1.8</jdk>
			</activation>
			<properties>
				<maven.compiler.source>1.8</maven.compiler.source>
				<maven.compiler.target>1.8</maven.compiler.target>
				<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
			</properties>
		</profile>
	</profiles>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<transformers>
								<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<manifestEntries>
										<Main-Class>SqlMockTask</Main-Class>
									</manifestEntries>
								</transformer>
							</transformers>
							<filters>
								<filter>
									<artifact>*:*</artifact>
									<excludes>
										<exclude>META-INF/*.SF</exclude>
										<exclude>META-INF/*.DSA</exclude>
										<exclude>META-INF/*.RSA</exclude>
									</excludes>
								</filter>
							</filters>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.xml</include>
				</includes>
				<filtering>true</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.*</include>
				</includes>
			</resource>
		</resources>
	</build>
</project>

打包后生成一个可执行文件flink-mock-1.0-SNAPSHOT.jar, 直接拖到终端执行:

java -jar flink-mock-1.0-SNAPSHOT.jar 

发现以下报错:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" org.apache.flink.table.api.TableException: Could not instantiate the executor. Make sure a planner module is on the classpath
	at org.apache.flink.table.api.bridge.internal.AbstractStreamTableEnvironmentImpl.lookupExecutor(AbstractStreamTableEnvironmentImpl.java:109)
	at org.apache.flink.table.api.bridge.java.internal.StreamTableEnvironmentImpl.create(StreamTableEnvironmentImpl.java:101)
	at org.apache.flink.table.api.bridge.java.StreamTableEnvironment.create(StreamTableEnvironment.java:122)
	at org.apache.flink.table.api.bridge.java.StreamTableEnvironment.create(StreamTableEnvironment.java:94)
	at SqlMockTask.main(SqlMockTask.java:11)
Caused by: org.apache.flink.table.api.ValidationException: Could not find any factories that implement 'org.apache.flink.table.delegation.ExecutorFactory' in the classpath.
	at org.apache.flink.table.factories.FactoryUtil.discoverFactory(FactoryUtil.java:533)
	at org.apache.flink.table.api.bridge.internal.AbstractStreamTableEnvironmentImpl.lookupExecutor(AbstractStreamTableEnvironmentImpl.java:106)
	... 4 more

就是没有找到某些SPI的实现类的意思,这些实现类本来应该是在依赖的Jar中的,而我选择的打包方式是maven-shade,应该所有的依赖Jar都被打进了shade包了,使用反编译软件打开jar包,发现了猫腻:

这个META-INF/services中的org.apache.flink.table.factories.Factory,只有三条词条,而我们项目中不止一个依赖jar有这个SPI定义:

Maven按照POM依赖声明的先后顺序, 只加载了第一个services文件中的内容,后面的两条都被忽略掉了,导致运行报错。

参考Apache Maven Shade Plugin – Resource Transformers

给maven-shade-plugin添加一条配置:

<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>

重新编译,再查看META-INF/service中的内容:

之前被忽略掉的services实现类已经都被加上去了 ,再运行jar包, 恢复正常了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【工作笔记】- maven-shade-plugin打包合并META-INF/services 的相关文章

随机推荐

  • @RequestMapping使用须知

    RequestMapping 使用须知 使用 RequestMapping 注解映射请求路径 即 你可以使用 RequestMapping注解来将请求URL映射到整个类上 或某个特定的方法上 即 RequestMapping 既可以定义在类
  • 关于OPenGL贴图莫名其妙扭曲

    原图 效果 这个问题查出来了 OpenGL要求所有的纹理都是4字节对齐的 即纹理的大小永远是4字节的倍数 通常这并不会出现什么问题 因为大部分纹理的宽度都为4的倍数并 或每像素使用4个字节 但是这个图片是jpg并且宽高不是4的倍数 所以出现
  • js获取当前年月日,格式(YYYY年mm月dd日)

    1 显示当前系统年月日 2023 01 21 格式
  • Glide的封装

    package com example et Ustlis import android content Context import android graphics Bitmap import android graphics draw
  • Mac环境下小米手机Root教程

    参考文章 小米手机解锁注意事项 小米手机BL解锁操作指南 小米手机获取 Root 权限教程 详细图文 准备环境 需要Win环境 解锁需要Win环境 解锁工具是exe版本 刷机也需要Win环境 fastboot是exe文件 1 手机解锁 需要
  • Maven基础篇

    一 为什么要使用Maven 随着我们使用越来越多的框架 或者框架封装程度越来越高 项目中使用的 jar 包也越来越多 项目中 一个模块里面用到上百个jar包是非常正常的 框架中使用的 jar 包 不仅数量庞大 而且彼此之间存在错综复杂的依赖
  • Numpy一维array转置

    参考 https www cnblogs com cymwill p 8358866 html 分析 Numpy相关的转置函数有T transpose等 使一维数组转置可以使用reshape实现 实现例子 import numpy as n
  • 单元测试,模拟用户Get登陆,并携带登录后的token访问接口

    HttpClient httpClient HttpClient businessHttpClient private async Task
  • 慢sql和sql注入

    慢SQL是指在数据库中执行的SQL查询或操作的执行时间超过了预期或可接受的时间 这可能是由多种原因引起的 包括查询优化不当 索引缺失 不合理的数据模型设计 高并发负载等 下面是关于慢SQL的详细描述 排查和解决方法 现象 响应时间延迟 查询
  • VS2005自带SQL2005的管理工具

    有很多人对于VS2005自带SQL2005 Express版使用感觉很迷茫 因为它没有自带的管理工具 不过好在官网有SQL2005 Express版配套的管理工具可供下载 有了它 就可以管理SQL2005 Express版了 没有特殊要求的
  • SetThreadAffinityMask中掩码的问题

    在我们进行多线程开发的过程时 常常需要自己分配线程到不同的处理器上运算 以保证我们程序的运行效率 SetThreadAffinityMask是我们常见的选择 1 MSDN中函数的定义 DWORD PTR WINAPI SetThreadAf
  • ubuntu 18.04 radius 服务安装配置

    环境信息 cat etc os release NAME Ubuntu VERSION 18 04 6 LTS Bionic Beaver ID ubuntu ID LIKE debian PRETTY NAME Ubuntu 18 04
  • 火星java_AcWing 420. 火星人(Java 图示 实现next_permutation)

    图示 代码 import java util import java lang public class Main static Scanner scanner new Scanner System in static int n m st
  • Matlab——表达式 阵列与矩阵的创建

    表达式 指令过长 如果一个指令过长可以在结尾加上 下一行继续写指令即可 若不想每次都显示运算结果 只需在运算式最後加上分号 即可 注释 基本的算术运算有 加 减 乘 除 幂次方 范例为 5 3 5 3 5 3 5 3 5 3 设置精度值 t
  • Python默认设置为python3

    1 方法 执行 shell里执行 sudo update alternatives install usr bin python python usr bin python2 100 sudo update alternatives ins
  • 论文中参考文献中大写字母的含义

    方括号内英文字母为文献类型标识 专著 M 论文集 C 学位论文 D 报纸文章 N 期刊文章 J 报告 R 标准 S 专利 P 析出文献 A 其他 Z
  • Android APP之间的跳转

    APP之间的跳转实际上也是Activity之间的跳转 只是需要多配置一些东西 首先在目标APP的清单文件上加多一个intent filter在Activity中
  • QT5+VS2010+openCV2.4.9联调视频小工程

    项目场景 最近在vs上联调qt opencv 光配置环境就配置了一个星期555 配置好环境后仿照教程 https blog csdn net skeeee article details 10187561 编写了第一个联调的demo 后来参
  • qt控件拖动-动态布局-动态控件

    1 lua直接调用qt类库 包括实时ui控制 qt lua 交互 tolua 2 静态连接qt类库 动态控制ui 3 代码生成静态布局 4 代码生成ui
  • 【工作笔记】- maven-shade-plugin打包合并META-INF/services

    今天在项目终于到一个问题 我写了一个简单的Flink SQL的Demo工程 只有一个主类 import org apache flink streaming api environment StreamExecutionEnvironmen