使用Spring Maven插件进行不同的打包:Spring + Spark应用程序

时间:2017-07-10 10:12:49

标签: maven apache-spark spring-boot maven-plugin

我有一个由三部分组成的项目:

  • Spring Boot应用程序
  • Spark应用程序
  • "图书馆"以上两者使用(将此库作为单独的JAR或类似的原因导致安静一点开销并减慢开发速度)

所以我想要的是一个JAR,它可用于运行Spring Boot应用程序(java -jar myapp.jar)以及Spark应用程序(java -cp myapp.jar path.to.main.class)。 拥有两个JAR也是可以的 - 但两者都需要是胖JAR(意思是:包括依赖项)。

我在pom.xml中尝试的是:

  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
  </plugin>

这会创建一个可用于运行Spring Boot应用程序的胖JAR(如预期的那样)。但它不能用于Spark应用程序(因为类和依赖关系按照我的理解以某种方式重新打包)。

我的第二次尝试是:

  <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
      <execution>
        <goals>
          <goal>repackage</goal>
        </goals>
        <configuration>
          <classifier>exec</classifier>
        </configuration>
      </execution>
    </executions>
  </plugin>

这也创建了胖JAR以及另一个JAR,它只保存了我项目中实现的类 - 但没有依赖项。因此,Spark作业无法启动(如预期的那样)。

知道如何解决这种情况吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我为应用程序使用了相同的技术堆栈(Spring-用于Web部件,Apache Spark用于大数据处理)。我没有看到有人想要为侧面,Spring + Spark构建一个胖罐的情况(除了你可以使用Spring的内部火花作业的情况)。因此,我们使用的方法是必须为Spring Web部分分离Maven模块,为Apache Spark分离一个。对于Spring Boot,我们没有使用spring-boot-maven-plugin,而是使用了以下maven插件,如下所示:

<plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.5.0</version>
            <configuration>
                <mainClass>com.Application</mainClass>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.5.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <excludeArtifactIds>integration</excludeArtifactIds>
                        <outputDirectory>${project.build.directory}/lib/</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.Application</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

像这样我们有一个更好的控制器使用所有依赖项(例如:然后放在lib文件夹中并将它们包含在MANIFEST中)

对于Spark应用程序,您有两个选项:

  • 使用spark-submit运行(我个人不喜欢)
  • 使用spark_launcher * .jar依赖项中的SparkLauncher类(从Web调用Spark作业)。

为Spark应用程序构建一个胖jar,只有Spark代码中使用的依赖项是可取的,因为你只加载你真正需要的东西。我们可以使用maven-shade-plugin:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                            <includes>
                             // put here what you need to include
                            </includes>
                        </artifactSet>
                    </configuration>
                </execution>
            </executions>
        </plugin>