Spring Maven Plugin 的不同封装:Spring + Spark 应用

Posted

技术标签:

【中文标题】Spring Maven Plugin 的不同封装:Spring + Spark 应用【英文标题】:Different packaging with Spring Maven Plugin: Spring + Spark application 【发布时间】:2017-12-14 00:42:49 【问题描述】:

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

Spring Boot 应用程序 Spark 应用程序 上述两者都使用“库”(将此库作为单独的 JAR 或类似文件会导致一些开销并减慢开发速度)

所以我想要的是一个可用于运行 Spring Boot 应用程序 (java -jar myapp.jar) 以及 Spark 应用程序 (java -cp myapp.jar path.to.main.class) 的 JAR。 拥有两个 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】:

我对应用程序使用了相同的技术堆栈(Spring- 用​​于 Web 部件,Apache Spark 用于大数据处理)。我没有看到有人想为双方构建一个胖罐,Spring + Spark(除了在 Spark 工作中你会使用 Spring 中的东西的情况)。因此,我们使用的方法是必须将 Maven 模块分开,一个用于 Spring Web 部件,一个用于 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 应用程序构建一个仅包含 Spark 代码中使用的依赖项的胖 jar 是可取的,因为您只加载真正需要的内容。我们可以为此使用 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>

【讨论】:

以上是关于Spring Maven Plugin 的不同封装:Spring + Spark 应用的主要内容,如果未能解决你的问题,请参考以下文章

`spring-boot-maven-plugin` 和 `maven-compiler-plugin` 有啥区别?

maven install 怎么忽略spring-boot-maven-plugin

SpringBoot项目使用maven-assembly-plugin根据不同环境打包成tar.gz

Maven插件系列之spring-boot-maven-plugin

使用spring-boot-maven-plugin打包

SpringBootPlugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found