如何在 Spark 2.3.3 中使用 orc-core-1.5.5?

How to use orc-core-1.5.5 in Spark 2.3.3?

我的代码依赖于 orc-core-1.5.5,我需要它在 Spark-2.3.3 环境中 运行。但是Spark-2.3.3只有orc-core-1.4.4.

由于某种原因,我的情况不允许使用“--jars”。所以我尝试使用 Maven Shade Plugin 将 orc-core-1.5.5 添加到我的最终 jar 中。但是当我将这个 jar 提交到 Spark-2.3.3 时,它仍然显示 java.lang.NoSuchMethodError: org.apache.orc.OrcFile$ReaderOptions.getUseUTCTimestamp()Z (仅存在于 1.5.5 版本中)。貌似我的app在我的jar中没有使用orc-core-1.5.5,而是在Spark环境下的1.4.4中搜索这个方法。

我的pom中的阴影部分:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                  <execution>
                    <phase>package</phase>
                    <goals>
                      <goal>shade</goal>
                    </goals>
                    <configuration>
                      <shadedArtifactAttached>true</shadedArtifactAttached>
                      <shadedClassifierName>cuda10</shadedClassifierName>
                      <artifactSet>
                        <includes>
                          <include>org.apache.orc:orc-core:nohive</include>
                        </includes>
                      </artifactSet>

                    </configuration>

                  </execution>
                </executions>
            </plugin>

得到 jar 后,我深入研究并反编译 OrcFile.class。我可以看到方法 "getUseUTCTimestamp()" 躺在那里。

method search 过程的顺序是什么?我该怎么做才能使用仅存在于 orc-core-1.5.5 中但存在于 Spark-2.3.3 中的方法?

根据回答更新,在configuration

中添加relocations
                  <relocations>
                    <relocation>
                      <pattern>org.apache.orc</pattern>
                      <shadedPattern>org.shaded.apache.orc</shadedPattern>
                    </relocation>
                  </relocations>

但是我收到一个新错误:

java.lang.NoClassDefFoundError: Could not initialize class org.shaded.apache.orc.impl.SnappyCodec
    at org.shaded.apache.orc.impl.WriterImpl.createCodec(WriterImpl.java:244)
    at org.shaded.apache.orc.impl.OrcCodecPool.getCodec(OrcCodecPool.java:55)
    at org.shaded.apache.orc.impl.ReaderImpl.extractFileTail(ReaderImpl.java:606)
......

我可以看到 org/shaded/apache/orc 躺在我的罐子里。

您需要使用 maven shade 插件的 <relocation> 指令。这将更改您的依赖项的 "location",以免与 spark 版本冲突。

shade 插件有效地将您的依赖项移动到不同的包位置,并重写项目其余部分的字节码以使用 已更改 完全限定的 class 名称, 这样它就不会与 spark 的依赖重叠,并允许两个版本同时存在于 JVM 中。