# hive-exec.jarを利用する際のTips > Blogged: https://uokada.hatenablog.jp/entry/2021/03/12/140930 ###### tags: `java`, `scala` 仕事で作っていたアプリケーションで`hive-exec`を利用する機会があり、その過程で色々とハマったので解決方法を残しておきます。 ## java.lang.NoSuchMethodErrorへの対応 アプリケーションを開発し無事にアプリを立ち上げたが実行中に`java.lang.NoSuchMethodError`を吐いて処理が失敗しました。 ```java= java.lang.NoSuchMethodError: 'void com.google.common.base.Preconditions.checkArgument(boolean, java.lang.String, java.lang.Object)' ``` このとき利用していたのが`hive-exec-2.3.2-jar`で何故このエラーが出るのかを調べていきます。 - https://search.maven.org/artifact/org.apache.hive/hive-exec/2.3.2/jar - https://search.maven.org/remotecontent?filepath=org/apache/hive/hive-exec/2.3.2/hive-exec-2.3.2.jar まず、jarファイルをダウンロードして中を調べてみるとjarファイルにGoogle guava関連のクラスが含まれていることが分かります。 ```shell= $ jar tvf hive-exec-2.3.2.jar|grep Preconditions 2059 Thu Nov 09 14:29:18 JST 2017 org/apache/parquet/Preconditions.class 5310 Thu Nov 09 14:29:18 JST 2017 com/google/common/base/Preconditions.class 2704 Thu Nov 09 14:29:20 JST 2017 com/google/common/math/MathPreconditions.class ``` 十中八九これが悪さをしています。なので、guava関連のファイルを取り除いたhive-exec.jarを利用すれば問題が解決するように思いますね。 幸いなことに、`hive-exec`ライブラリは通常のjarファイル以外にcore.jarっていうのが提供されています。 このjarファイルをダウンロードして中身を確認してみるとguava関連のクラスが入ってないことが分かります。 ```bash= $ jar tvf hive-exec-2.3.2-core.jar |grep Preconditions <no output> ``` - https://search.maven.org/remotecontent?filepath=org/apache/hive/hive-exec/2.3.2/hive-exec-2.3.2-core.jar ### 余談: core.jarはいつから提供されているのか? & Why is the core.jar provided? https://search.maven.org/artifact/org.apache.hive/hive-exec 調べていくとv0.14.0からcore.jarが提供されていました。 https://search.maven.org/artifact/org.apache.hive/hive-exec/0.14.0/jar 次は、この時期のissueを読んで提供された理由を調べていきます。 ググったらすぐ該当するissueが見つかりました。 - https://issues.apache.org/jira/browse/HIVE-7423 > currently ql module produces hive-exec-$version.jar which is an uber jar. It's also useful to have a thin jar, let's call it hive-exec-$version-core.jar, that only has classes from ql. ## How to use the core.jar in sbt さて、core.jarが提供されていることが分かりましたがどうすればこのjarを利用することが出来るのか紹介します。 maven, gradle, sbtの3つでどういう方法でcore.jarを利用するか紹介します。 どれも`classifier`タグかキーワードを入れるだけで簡単に利用することが出来ます。 ### Maven ```xml <dependencies> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>2.3.2</version> <classifier>core</classifier> </dependency> </dependencies> ``` - http://maven.apache.org/pom.html ### Gradle ```groovy= compile("org.apache.hive:hive-exec:2.3.2:core") or compile(group:'org.apache.hive', name: 'hive-exec', version: '2.3.2', classifier: 'core') ``` ### sbt ```scala= libraryDependencies += "org.apache.hive" % "hive-exec" % "2.3.2" classifier "core" or "org.apache.hive" % "hive-exec" % "2.3.2" classifier "core" ``` - https://www.scala-sbt.org/1.x/docs/Library-Management.html#Classifiers ## まとめ 自分のケースでは`core.jar`を利用してアプリケーションを再コンパイル・パッケージングして動かして確認したところ例外が発生しなくなり期待通り動作するようになりました。 hive-execを利用する際に起きたトラブルとその解決方法について紹介しました。 自分はこれまで`classifier`されたjarを利用することがなかったので`core.jar`が提供されている可能性やそのjarファイルの利用方法を調べるのに時間を取られましたが今後同じようなケースがあった場合にサクッとdefault以外のjarファイルがある可能性を調べてデバッグを高速に完了出来るのではないかと思います。 ---------------------- ---------------------- - https://github.com/linkedin/transport/issues/29 > org.apache.hive:hive-exec bundles in some transitive dependencies (e.g. guava) without shading them. This causes classpath issues in the test framework as user is not able to depend on newer guava version. Instead we should use org.apache.hive:hive-exec:core jar which does not bundle transitive dependencies. This way, guava dependencies can be manipulated through Gradle dependency resolution if required. ```scala= "org.apache.hive" % "hive-exec" % "2.3.2" classifier "core" ``` ### How to use a core jar in gradle https://github.com/apache/iceberg/blob/99df4cc902df8197ed4b45cca98330c178005b34/build.gradle#L348 ```groovy= testCompile("org.apache.hive:hive-exec::core") { ``` https://github.com/apache/iceberg/blob/99df4cc902df8197ed4b45cca98330c178005b34/build.gradle#L685-L691 ```groovy= compile("org.apache.orc:orc-core::nohive") { exclude group: 'org.apache.hadoop' exclude group: 'commons-lang' // These artifacts are shaded and included in the orc-core fat jar exclude group: 'com.google.protobuf', module: 'protobuf-java' exclude group: 'org.apache.hive', module: 'hive-storage-api' } ``` ### How to use a classfied jar in maven - https://search.maven.org/artifact/org.testng/testng/5.7/jar - https://medium.com/@therealgaryj/simplifying-our-git-repositories-using-maven-classifiers-42b24509e945 e.g: https://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html ```xml <dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>5.11</version> <scope>test</scope> <classifier>jdk15</classifier> </dependency> </dependencies> ``` > classifier: The classifier distinguishes artifacts that were built from the same POM but differ in content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number. As a motivation for this element, consider for example a project that offers an artifact targeting Java 11 but at the same time also an artifact that still supports Java 1.8. The first artifact could be equipped with the classifier jdk11 and the second one with jdk8 such that clients can choose which one to use. > > Another common use case for classifiers is to attach secondary artifacts to the project's main artifact. If you browse the Maven central repository, you will notice that the classifiers sources and javadoc are used to deploy the project source code and API docs along with the packaged class files. > > type: Corresponds to the chosen dependency type. This defaults to jar. While it usually represents the extension on the filename of the dependency, that is not always the case: a type can be mapped to a different extension and a classifier. The type often corresponds to the packaging used, though this is also not always the case. Some examples are jar, ejb-client and test-jar: see default artifact handlers for a list. New types can be defined by plugins that set extensions to true, so this is not a complete list. http://maven.apache.org/pom.html ## Links - https://issues.apache.org/jira/browse/HIVE-22126 - https://issues.apache.org/jira/browse/ORC-174 - https://issues.apache.org/jira/browse/HIVE-5733 - https://blog.csdn.net/u012121587/article/details/103903162 - https://bryantsai.com/how-to-resolve-dependency-conflict-out-of-your-control-e75ace79e54f