如何修复在hive下运行的geoip2 java的“java.lang.nosuchmethoderror”

axzmvihb  于 2021-06-24  发布在  Hive
关注(0)|答案(1)|浏览(442)

我在hive2.3.4(java8)下执行一个以geoip2(maxmind)作为依赖项的udf时遇到了问题,同样的代码在使用java7的旧版本hive和使用java8的presto下都可以正常工作。
我尝试过使用精确依赖(maven)和手动编译,多个版本的配置单元,将代码和依赖减少到最低限度

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;

import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.exception.GeoIp2Exception;

public final class CityName extends UDF {
        public String evaluate(String dbFile) throws IOException,GeoIp2Exception {
            File database = new File(dbFile);
            InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
            DatabaseReader reader = new DatabaseReader.Builder(database).build();
            return "Database: "+dbFile.toString();
        }
}

错误消息

2019-05-21T16:31:56,631 ERROR [ce3bca33-87aa-4468-b1ed-7080e95efb2d main([])]: ql.Driver (SessionState.java:printError(1126)) - FAILED: SemanticException [Error 10014]: Line 1:7 Wrong arguments ''/root/GeoIP2-City.mmdb'': org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public java.lang.String com.example.hive.udf.CityName.evaluate(java.lang.String) throws java.io.IOException,com.maxmind.geoip2.exception.GeoIp2Exception,java.net.UnknownHostException with arguments {/root/GeoIP2-City.mmdb}:com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
org.apache.hadoop.hive.ql.parse.SemanticException: Line 1:7 Wrong arguments ''/root/GeoIP2-City.mmdb'': org.apache.hadoop.hive.ql.metadata.HiveException: Unable to execute method public java.lang.String com.example.hive.udf.CityName.evaluate(java.lang.String) throws java.io.IOException,com.maxmind.geoip2.exception.GeoIp2Exception,java.net.UnknownHostException with arguments {/root/GeoIP2-City.mmdb}:com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
at org.apache.hadoop.hive.ql.parse.TypeCheckProcFactory$DefaultExprProcessor.process(TypeCheckProcFactory.java:1367)
at org.apache.hadoop.hive.ql.lib.DefaultRuleDispatcher.dispatch(DefaultRuleDispatcher.java:90)
at org.apache.hadoop.hive.ql.lib.DefaultGraphWalker.dispatchAndReturn(DefaultGraphWalker.java:105)
.......
Caused by: java.lang.NoSuchMethodError: com.maxmind.geoip2.DatabaseReader.(Lcom/maxmind/geoip2/DatabaseReader$Builder;Lcom/maxmind/geoip2/DatabaseReader$1;)V
at com.maxmind.geoip2.DatabaseReader$Builder.build(DatabaseReader.java:160)
at com.example.hive.udf.CityName.evaluate(CityName.java:20)
... 47 more
gg58donl

gg58donl1#

我们遇到了一个非常类似的问题。在我们的例子中,发现在配置单元部署的类路径中有一个过时的maxminddb版本。在新版本的hive上,这甚至可能是默认的,但我还没有确认。
若要修复,只需对com.maxmind的任何引用进行阴影处理。另外,为了安全起见,对任何对fasterxml.jackson的引用也进行阴影处理——这是geoip2的核心依赖关系之一,类路径中的冲突往往会导致像这样奇怪的运行时问题。您可以在一个配置单元udf geoip lib中的pr中看到这样一个例子。

相关问题