Spark Maven依赖关系在delta-core和spark-avro之间不兼容

问题描述

我试图将delta-core添加到运行2.4.4的scala Spark项目中。

我看到的一个奇怪的行为是它似乎与Spark Avro冲突。 Maven构建成功,但是在运行时出现错误

如果首先声明增量表依赖关系,则会收到一个运行时错误提示未安装spark avro:

用户类抛出异常:org.apache.spark.sql.AnalysisException: 无法找到数据源:avro。 Avro是内置的,但外部数据 自Spark 2.4起的源模块。请按照以下说明部署应用程序 “ Apache Avro数据源指南”的部署部分。

<dependencies>
    <dependency>
        <groupId>io.delta</groupId>
        <artifactId>delta-core_2.11</artifactId>
        <version>0.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-avro_2.11</artifactId>
        <version>2.4.4</version>
    </dependency>

如果先定义了spark avro,则Avro可以工作,但是delta会出现异常:

用户类引发异常:java.lang.classNotFoundException:失败 查找数据源:增量。请在以下位置找到软件包 http://spark.apache.org/third-party-projects.html

    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-avro_2.11</artifactId>
            <version>2.4.4</version>
        </dependency>

        <dependency>
            <groupId>io.delta</groupId>
            <artifactId>delta-core_2.11</artifactId>
            <version>0.6.1</version>
        </dependency>

我认为这可能是某种依赖冲突,所以我尝试了:

 <exclusions>
        <exclusion>
            <groupId>*</groupId>
            <artifactId>*</artifactId>
        </exclusion>
    </exclusions>

在两者上,但这都没有帮助。

解决方法

得到一个answer for this in the delta-core issues page。谢谢zsxwing!

完整的解决方案基于此previous stack overflow answer来合并META-INF下的服务,因此不同的火花源不会相互覆盖。

完整的解决方案-我将maven程序集插件更改为此:

<plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptors>
                        <descriptor>${project.basedir}\src\assembly\tvm_assembly.xml</descriptor>
                    </descriptors>
                </configuration>
            </plugin>

在新的tvm_assembly.xml文件中(基于原始的jar-with-depndencies,添加了合并属性):

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <!-- TODO: a jarjar format would be better -->
    <id>jar-with-dependencies</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
    <containerDescriptorHandlers>
        <containerDescriptorHandler>
            <handlerName>metaInf-services</handlerName>
        </containerDescriptorHandler>
        <containerDescriptorHandler>
            <handlerName>metaInf-spring</handlerName>
        </containerDescriptorHandler>
        <containerDescriptorHandler>
            <handlerName>plexus</handlerName>
        </containerDescriptorHandler>
    </containerDescriptorHandlers>
</assembly>