Apache Flink利用Maven对Scala与Java进行混编

2020-04-14 14:41:53 浏览数 (1)

Flink是由Scala进行编写的一种大数据计算引擎,而Scala由是执行与JVM之上的一种语言,所以Scala语言也会编译为字节码文件进行执行。那么使用maven同时管理Scala与Java的代码是否可行?

主要是因为作者在使用IDEA,maven做Flink开发的时候出现的问题。Flink作业在提交到生产环境集群的时候不要把Flink相关源码等打入jar包中,因为这样可能会出现当生产版本与开发版本不同的时候就会出现冲突。

所以我们在代码打包的时候需要把Flink相关的jar包排除掉。而只打入我们引用的其他三方包,例如fastjson等。所以,对于maven中可能出现冲突的包需要过滤掉,而其他的三方包或二方包才打入jar包中。

Scala与Java混合编写肯定是支持的,在开发的时候首先我引入的是Scala相关的依赖,后来由于需要Java的同学帮忙来做工程中的某些实现,需要在工程中编写Java相关代码。在本地开发Java代码,Scala引用Java相关内容均没有任何的问题,开发完成后需要把代码打为jar包提交到Flink集群中。 NoClassDefFoundError

本地没有任何问题啊,IDEA查看代码确实存在

Java与Scala代码均位于src/main/scala 包中,开始Google... 翻了好几个博客都说需要引入Scala与Java的编译。

代码语言:javascript复制
<!--Scala编译-->
<plugin>
	<groupId>net.alchim31.maven</groupId>
	<artifactId>scala-maven-plugin</artifactId>
	<executions>
		<execution>
			<id>scala-compile</id>
			<phase>compile</phase>
			<goals>
				<goal>add-source</goal>
				<goal>compile</goal>
			</goals>
		</execution>
		<execution>
			<id>scala-test-compile</id>
			<phase>test-compile</phase>
			<goals>
				<goal>testCompile</goal>
			</goals>
		</execution>
	</executions>
</plugin>
<!--Java编译-->
<plugin>
	<artifactId>maven-compiler-plugin</artifactId>
	<executions>
		<execution>
			<id>default-compile</id>
			<phase>none</phase>
		</execution>
		<execution>
			<id>default-testCompile</id>
			<phase>none</phase>
		</execution>
	</executions>
</plugin>

但是我明明已经引用了啊.

继续翻发现一个基于shade可以打包成功,重复套路,修改pom,打包,提交到集群上...依然是熟悉的 NoClassDefFoundError..

没问题,打包成功...

本地执行没问题...

反编译jar包,还是没有Java相关的代码...

那还是maven插件的问题..继续google... 找到这个..

看不懂...

一脸懵逼...

搞一搞...

打包,提交到集群...

成功了!!!

现在扔出完整的build留个纪念~

代码语言:javascript复制
<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-shade-plugin</artifactId>
			<version>2.3</version>
			<executions>
				<execution>
					<phase>package</phase>
					<goals>
						<goal>shade</goal>
					</goals>
					<configuration>
						<artifactSet>
							<excludes>
								<exclude>org.apache.flink:*</exclude>
								<exclude>org.slf4j:*</exclude>
								<exclude>log4j:*</exclude>
							</excludes>
						</artifactSet>
						<transformers>
							<transformer
									implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
								<mainClass>XXX.XXX.XXX.XXX.DataParsingWorker</mainClass>  <!--这里运行类! -->
							</transformer>
						</transformers>
					</configuration>
				</execution>
			</executions>
		</plugin>
		<plugin>
			<groupId>net.alchim31.maven</groupId>
			<artifactId>scala-maven-plugin</artifactId>
			<executions>
				<execution>
					<id>scala-compile</id>
					<phase>compile</phase>
					<goals>
						<goal>add-source</goal>
						<goal>compile</goal>
					</goals>
				</execution>
				<execution>
					<id>scala-test-compile</id>
					<phase>test-compile</phase>
					<goals>
						<goal>testCompile</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
		<plugin>
			<artifactId>maven-compiler-plugin</artifactId>
			<executions>
				<execution>
					<id>default-compile</id>
					<phase>none</phase>
				</execution>
				<execution>
					<id>default-testCompile</id>
					<phase>none</phase>
				</execution>
			</executions>
		</plugin>

		<!-- Eclipse Scala Integration -->
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-eclipse-plugin</artifactId>
			<version>2.8</version>
			<configuration>
				<downloadSources>true</downloadSources>
				<projectnatures>
					<projectnature>org.scala-ide.sdt.core.scalanature</projectnature>
					<projectnature>org.eclipse.jdt.core.javanature</projectnature>
				</projectnatures>
				<buildcommands>
					<buildcommand>org.scala-ide.sdt.core.scalabuilder</buildcommand>
				</buildcommands>
				<classpathContainers>
					<classpathContainer>org.scala-ide.sdt.launching.SCALA_CONTAINER</classpathContainer>
					<classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
				</classpathContainers>
				<excludes>
					<exclude>org.scala-lang:scala-library</exclude>
					<exclude>org.scala-lang:scala-compiler</exclude>
				</excludes>
				<sourceIncludes>
					<sourceInclude>**/*.scala</sourceInclude>
					<sourceInclude>**/*.java</sourceInclude>
				</sourceIncludes>
			</configuration>
		</plugin>
		<plugin>
			<groupId>org.codehaus.mojo</groupId>
			<artifactId>build-helper-maven-plugin</artifactId>
			<version>1.7</version>
			<executions>
				<!-- Add src/main/scala to eclipse build path -->
				<execution>
					<id>add-source</id>
					<phase>generate-sources</phase>
					<goals>
						<goal>add-source</goal>
					</goals>
					<configuration>
						<sources>
							<source>src/main/scala</source>
						</sources>
					</configuration>
				</execution>
				<!-- Add src/test/scala to eclipse build path -->
				<execution>
					<id>add-test-source</id>
					<phase>generate-test-sources</phase>
					<goals>
						<goal>add-test-source</goal>
					</goals>
					<configuration>
						<sources>
							<source>src/test/scala</source>
						</sources>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

最终实现在 src/main/scala 包下使用Scala,Java 语言均可开发,打包,部署。

这样某些模块就可以交由Java语言的同学进行开发了...所以,最终最需要做好框架就可以了,这个才是最核心的目的!

0 人点赞