hive添加IP解析的udf函数_java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.node.ObjectNode.<init>...

这个问题着实是个大坑啊,使用mr解析用户ip没有问题,然后,想直接使用相同代码在hive中添加udf函数,不断地掉坑啊,踩坑踩了两天,总算是解决了。

1、编写代码

public class IP extends UDF{
    
    private static Logger logger = Logger.getLogger(IP.class);
    public static boolean enableFileWatch = false;
    private static int offset;
    private static int[] index = new int[256];
    private static ByteBuffer dataBuffer;
    private static ByteBuffer indexBuffer;
    private static Path ipFile = new Path("/file/IpParse.dat");
    private static Path maxMindFile = new Path("/hive_udf/GeoIP2-City.mmdb");
    private static DatabaseReader reader;
    private static InputStream in = null;
    private static ReentrantLock lock = new ReentrantLock();
    
//    public static void main(String[] args){
//        try {
//            IP ip = new IP();
//            System.out.println(ip.evaluate("121.12.12.12"));
//        } catch (Exception e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//    }
    
    
    public String evaluate(String ip)  {
        try{
            Configuration conf = new Configuration();
            InputStream in = FileSystem.getLocal(conf).open(maxMindFile);
            reader = new DatabaseReader.Builder(in).build();
            FSDataInputStream fin = null;
            fin = ipFile.getFileSystem(conf).open(ipFile);
            dataBuffer = ByteBuffer.allocate(Long.valueOf(fin.available()).intValue());
           
            int readBytesLength;
            byte[] chunk = new byte[4096];
            while (fin.available() > 0) {
                readBytesLength = fin.read(chunk);
                dataBuffer.put(chunk, 0, readBytesLength);
            }
            dataBuffer.position(0);
            int indexLength = dataBuffer.getInt();
            byte[] indexBytes = new byte[indexLength];
            dataBuffer.get(indexBytes, 0, indexLength - 4);
            indexBuffer = ByteBuffer.wrap(indexBytes);
            indexBuffer.order(ByteOrder.LITTLE_ENDIAN);
            offset = indexLength;

            int loop = 0;
            while (loop++ < 256) {
                index[loop - 1] = indexBuffer.getInt();
            }
            indexBuffer.order(ByteOrder.BIG_ENDIAN);
          
            //解析IP
            if (ip == null) {
                ip = "0.0.0.0";
            } else {
                String[] ips = ip.split("\\.", -1);
                if (ips.length != 4) {
                    ip = "0.0.0.0";
                }
            }
            int ip_prefix_value = new Integer(ip.substring(0, ip.indexOf(".")));
            long ip2long_value = ip2long(ip);
            int start = index[ip_prefix_value];
            int max_comp_len = offset - 1028;
            long index_offset = -1;
            int index_length = -1;
            byte b = 0;
            for (start = start * 8 + 1024; start < max_comp_len; start += 8) {
                if (int2long(indexBuffer.getInt(start)) >= ip2long_value) {
                    index_offset = bytesToLong(b, indexBuffer.get(start + 6), indexBuffer.get(start + 5), indexBuffer.get(start + 4));
                    index_length = 0xFF & indexBuffer.get(start + 7);
                    break;
                }
            }

            byte[] areaBytes;            
            dataBuffer.position(offset + (int) index_offset - 1024);
            areaBytes = new byte[index_length];
            dataBuffer.get(areaBytes, 0, index_length);
            

            String local = new String(areaBytes);
            String[] locals = local.split("\t", -1);
            if (locals.length < 5) {
                local += "\t";
            }
            if (!locals[0].equals("中国")) {
                try {
                    StringBuffer sb = new StringBuffer();
                    InetAddress addr = InetAddress.getByName(ip);
                    CityResponse city = reader.city(addr);
//                    logger.info(Thread.currentThread().getId());
                    sb.append(city.getCountry().getNames().get("zh-CN")).append("\t");
                    sb.append(city.getMostSpecificSubdivision().getName()).append("\t");
                    sb.append(city.getCity().getName()).append("\t");
                    sb.append("\t");
                    local = sb.toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return local;
        }catch(Exception ex){
            ex.printStackTrace();
            return ex.getMessage();
        }        
    }


    private static long bytesToLong(byte a, byte b, byte c, byte d) {
        return int2long((((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)));
    }

    private static int str2Ip(String ip) {
        String[] ss = ip.split("\\.");
        int a, b, c, d;
        a = Integer.parseInt(ss[0]);
        b = Integer.parseInt(ss[1]);
        c = Integer.parseInt(ss[2]);
        d = Integer.parseInt(ss[3]);
        return (a << 24) | (b << 16) | (c << 8) | d;
    }

    private static long ip2long(String ip) {
        return int2long(str2Ip(ip));
    }

    private static long int2long(int i) {
        long l = i & 0x7fffffffL;
        if (i < 0) {
            l |= 0x080000000L;
        }
        return l;
    }
}

2、代码写完之后,使用本地运行和在linux下运行,都没有问题,但是放到hive中,就会报错。

Caused by: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.node.ObjectNode.<init>(Lcom/fasterxml/jackson/databind/node/JsonNodeFactory;Ljava/util/Map;)V
        at com.maxmind.db.Decoder.decodeMap(Decoder.java:285)
        at com.maxmind.db.Decoder.decodeByType(Decoder.java:154)
        at com.maxmind.db.Decoder.decode(Decoder.java:147)
        at com.maxmind.db.Decoder.decodeMap(Decoder.java:281)
        at com.maxmind.db.Decoder.decodeByType(Decoder.java:154)
        at com.maxmind.db.Decoder.decode(Decoder.java:147)
        at com.maxmind.db.Decoder.decode(Decoder.java:87)
        at com.maxmind.db.Reader.<init>(Reader.java:132)
        at com.maxmind.db.Reader.<init>(Reader.java:116)
        at com.maxmind.geoip2.DatabaseReader.<init>(DatabaseReader.java:35)
        at com.maxmind.geoip2.DatabaseReader.<init>(DatabaseReader.java:23)
        at com.maxmind.geoip2.DatabaseReader$Builder.build(DatabaseReader.java:129)
        at com.bankofamerica.gisds.ExtractEnterpriseData.ExtractEnterpriseDB(ExtractEnterpriseData.java:27)
        at com.package.name.App.evaluate(App.java:73)

3、解决问题

看到这个错误,考虑是jar冲突,因为在解析过程中需要使用hadoop的jar包引用,因此在所有引用中删除掉jackson_databind,无济于事,还是顽强报相同的错误。

 

<exclusions>
     <exclusion>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     </exclusion>
     <exclusion>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-annotations</artifactId>
     </exclusion>
</exclusions>

 4、我引用的GeoIP2为2.9.0版本,这是问题的所在

<dependency>
      <groupId>com.maxmind.geoip2</groupId>
      <artifactId>geoip2</artifactId>
      <version>2.9.0</version>
      <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-databind</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.core</groupId>
                    <artifactId>jackson-annotations</artifactId>
                </exclusion>
            </exclusions>
    </dependency>

5、将版本改为2.5.0,问题解决。

6、导入hive

delete jar /hive_udf/tt.jar;

add jar /hive_udf/tt.jar;

add file /hive_udf/GeoIP2-City.mmdb;

add file /hive_udf/IpParse.dat;

CREATE TEMPORARY FUNCTION pars_IP AS 'com.dewmobile.ParsIP.IP';

SELECT pars_IP('121.12.12.12');

7、运行:

120329_fQI9_2489618.png

8、pom.xml

<dependencies>		
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-mapreduce-client-core</artifactId>
			<version>2.3.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.hadoop</groupId>
			<artifactId>hadoop-common</artifactId>
			<version>2.3.0</version>
		</dependency>
		<dependency>
			<groupId>com.maxmind.geoip2</groupId>
			<artifactId>geoip2</artifactId>
			<version>2.5.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.hive</groupId>
			<artifactId>hive-exec</artifactId>
			<version>1.1.1</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>			
			<plugin>
				<artifactId> maven-assembly-plugin </artifactId>
				<configuration>
					<descriptorRefs>
						<descriptorRef>jar-with-dependencies</descriptorRef>
					</descriptorRefs>
					<archive>
					</archive>
				</configuration>
				<executions>
					<execution>
						<id>make-assembly</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

 

转载于:https://my.oschina.net/u/2489618/blog/1624980

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.MangoMap; //import android.app.Activity; import com.google.android.maps.MapActivity; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.SimpleAdapter; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; //MapView Com import com.google.android.maps.MapView; import com.google.android.maps.MapController; import com.google.android.maps.GeoPoint; //import com.google.android.maps. public class MangoMap extends MapActivity { /** Called when the activity is first created. */ private MapView mpv; private MapController mpc; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //地图 mpv = (MapView) findViewById(R.id.map); mpv.setTraffic(true); mpv.setClickable(true); mpv.setScrollContainer(true); mpc = mpv.getController(); GeoPoint gp = new GeoPoint((int) (23.05320 * 1000000), (int) (113.155550 * 1000000)); //地理坐标 mpc.animateTo(gp); mpc.setZoom(15); //mpc. // } @Override protected boolean isRouteDisplayed() { return false; } } //----------------- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> --> <com.google.android.maps.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="YOUR API key" /> <Button android:text="@+id/Button01" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> </LinearLayout> //--------------------- <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.MangoMap" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="com.google.android.maps" /> <activity android:name=".MangoMap" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值