欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java使用maven-shade-plugin打包,环境说明:jdk17

来源: javaer 分享于  点击 4863 次 点评:190

java使用maven-shade-plugin打包,环境说明:jdk17


最近正在练习Flink JAVA编程,但是发现打包后老大的问题。

环境说明:

  • jdk17
  • springboot 3.4.6
  • flink 1.20.0

 

一、问题发现和解决

在pom.xml的依赖部分,和flink有关的内容如下:

        <!-- Original Flink Dependencies -->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-core</artifactId>
			<version>${flink.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-streaming-java</artifactId>
			<version>${flink.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-api-java</artifactId>
			<version>${flink.version}</version>
			<!--<scope>provided</scope> -->
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- tableapi 桥接器,主要和DataStream进行对接 -->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-api-java-bridge</artifactId>
			<version>${flink.version}</version>
			<!--<scope>provided</scope> -->
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- ide调试 -->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-planner-loader</artifactId>
			<version>${flink.version}</version>
			<!--<scope>provided</scope> -->
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-table-runtime</artifactId>
			<version>${flink.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- 连接器 -->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-connector-files</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-csv</artifactId>
			<version>${flink.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-connector-jdbc</artifactId>
			<version>${flink-connector.jdbc.version}</version>
		</dependency>

		<!-- 执行工厂定义 -->
		<dependency>
			<groupId>org.apache.flink</groupId>
			<artifactId>flink-clients</artifactId>
			<version>${flink.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

 

一开始用的是spring-boot-maven-plugin进行打包,但是总会提示某些类找不到。

事实是有关的jar都打入了,但就是无法找到。主要的原因是SPI无法找到(在META-INF/services/下无法找到对应的spi定义)

折腾了一会,发现无法搞定。

后来发现可以使用maven-shade-plugin解决这个问题。

注:SPI即Service Provider Interface,中文称为服务供应商接口

参考地址:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/ServiceLoader.html

 

打包配置如下:

<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.13.0</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
					<encoding>${project.build.sourceEncoding}</encoding>
					<parameters>true</parameters>
				</configuration>
			</plugin>
			<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.6.0</version>
                <executions>
                    <!-- Run shade goal on package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <artifactSet>
                                <!-- 如果想排除一些包 -->
                                <excludes>
                                    <!--<exclude>org.apache.flink:force-shading</exclude>-->
                                    <exclude>com.google.code.findbugs:jsr305</exclude>
                                </excludes>
                            </artifactSet>
                            <filters>
                                <filter>
                                    <!-- Do not copy the signatures in the META-INF folder.
                                    Otherwise, this might cause SecurityExceptions when using the JAR. -->
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>org.lzfto.flink.demo.DemoApplication</mainClass>
                                </transformer>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
		</plugins>
		<resources>
			<resource>
				<directory>src/main/resources/</directory>
				<includes>
					<include>**/*.js</include>
					<include>**/*.css</include>
					<include>**/*.yml</include>
					<include>**/*.xml</include>
					<include>**/*.txt</include>
					<include>**/*.png</include>
					<include>**/*.jpeg</include>
					<include>**/*.jpg</include>
					<include>**/*.svg</include>
					<include>**/*.properties</include>
					<include>**/*.Factory</include>
					<include>**/*.json</include>
					<include>META-INF/services/*.Factory</include>
				</includes>
			</resource>
			<resource>
				<!-- directory 表示取该目录下的文件 -->
				<directory>libs</directory>
				<!--targetPath 指定打包到哪个目录下 默认是放到class目录下 -->
				<targetPath>/BOOT-INF/lib/</targetPath>
				<!-- 取符合格式的所有文件 *代表全部 -->
				<includes>
					<include>**/*.jar</include>
				</includes>
			</resource>
		</resources>
		<finalName>lzfto-${lzfto.flinktest.version}</finalName>
	</build>

 

Shade插件使用ServicesResourceTransformer解决SPI加载问题。

 

二、比较Shade和Springboot

 

为了便于行文,以Shade表示maven-shade-plugin,以Springboot表示spring-boot-maven-plugin

也就是说一般情况下,使用maven-shade-plugin比使用spring-boot-maven-plugin更好一些,好处有两点:

1.很容易解决SPI问题。也许spring-boot-maven-plugin可以通过自定义LayOut解决SPI问题

2.Shade打好的包加载速度更快,看下图(用rar打开后的看到的文件结构),并没有Springboot那样把库都放在BOOT-INF/libs,而是完全展开的class

 

当然,springboot也并非没有优势,使用较高版本的springboot,有一些额外的配置(看个人需要),例如(部分特新示例)

参考:https://docs.spring.io/spring-boot/maven-plugin/build-info.html

<project>
	<modelVersion>4.0.0</modelVersion>
	<artifactId>build-info</artifactId>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<executions>
					<execution>
						<goals>
							<goal>build-info</goal>
						</goals>
						<configuration>
							<additionalProperties>
								<encoding.source>UTF-8</encoding.source>
								<encoding.reporting>UTF-8</encoding.reporting>
								<java.version>${java.version}</java.version>
							</additionalProperties>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

 

大部分情况下,二者都需要maven-compiler-plugin解决某些问题,例如:

  1. 指定编译参数,如-parameters保留方法参数名、-Xlint启用警告检查等
  2. 指定编译版本和代码编码
  3. 处理模块系统

有关编译器插件的内容参见:https://maven.apache.org/plugins/maven-compiler-plugin/

 

本文来自博客园,作者:正在战斗中,转载请注明原文链接:https://www.cnblogs.com/lzfhope/p/18908589

相关栏目:

用户点评