如何在 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 中。
我的代码依赖于 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 中。