【java学习】Jni在hadoop上的使用(上)
遇到的需求很简单,我们有一个性能很好的分词器,用c++实现的,现在想在java写的hadoop的程序中使用它,咋办?
如果只是使用hadoop,用c++ pipes实现hadoop程序,再调用c++实现的分词器(源代码调用或者动态库调用)就很简单,不存在上面的问题。不过,由于Legacy原因(其实就是种种原因),不能放弃java版本的hadoop程序,才会有以上问题。
上网上搜了一下,Java调用c++用的是JNI(java native interface)技术,只是JNI怎么放到hadoop中?而且分词器要读取资源文件(词表),这个文件在hadoop中的路径设定有什么规矩?我就不知道了。
尝试分三阶段进行:
阶段一:在linux跑通一个单机版的JNI程序,即用java调用c++。
阶段二:将上面的程序放到hadoop上跑通。
阶段三:让c++编出来的动态库(so文件)load资源,并在hadoop上跑通。
现在进行阶段一的工作。
1. 写一个Java类,用来包装c++代码的接口。这里面我只是写了示意性代码,毕竟是要尝试么,如下:
package FakeSegmentForJni;import java.io.IOException;import java.net.URI;import java.net.URL;/** * This class is for verifying the jni technology. * It call the function defined in FakeSegmentForJni.java * */public class TestFakeSegmentForJni {public static void main(String[] args) throws Exception {System.out.println ("In this project, we test jni!\n");// test jni on linux localString s = FakeSegmentForJni.SegmentALine("now we test FakeSegmentForJni");System.out.print(s);} // main} // TestFakeSegmentForJni
测试代码也很简单,就是输入给FakeSegmentForJni.SegmentALine一个字符串,并且打印它的返回结果。
在linux上面打了一个jar包,输入如下命令运行上述代码:
java -Djava.library.path='/xxx/TestJni/' -jar /xxx/TestFakeSegmentForJni.jar FakeSegmentForJni.TestFakeSegmentForJni
(用-Djava.library.path指明FakeSegmentForJni_FakeSegmentForJni.so文件所在的路径,否则jvm找不到;后面FakeSegmentForJni.TestFakeSegmentForJni是main函数所在的路径)
程序运行结果是在屏幕上输出
now we test FakeSegmentForJni--copy that
这样的字样,表示成功调用FakeSegmentForJni_FakeSegmentForJni.so中的函数。