在本文中,我们将详细介绍如何添加第三方Javajar以便在pyspark中使用的各个方面,并为您提供关于java添加第三方类库的相关解答,同时,我们也将为您带来关于3.2、spark集群运行应用之第三
在本文中,我们将详细介绍如何添加第三方Java jar以便在pyspark中使用的各个方面,并为您提供关于java添加第三方类库的相关解答,同时,我们也将为您带来关于3.2、spark集群运行应用之第三方jar的处理方式、android 添加第三方jar库、Android.mk文件中添加第三方jar文件的方法、C++项目通过JNI使用Java第三方jar包的有用知识。
本文目录一览:- 如何添加第三方Java jar以便在pyspark中使用(java添加第三方类库)
- 3.2、spark集群运行应用之第三方jar的处理方式
- android 添加第三方jar库
- Android.mk文件中添加第三方jar文件的方法
- C++项目通过JNI使用Java第三方jar包
如何添加第三方Java jar以便在pyspark中使用(java添加第三方类库)
我有一些使用Java的第三方数据库客户端库。我想通过访问它们
java_gateway.py
例如:通过Java网关使客户端类(不是jdbc驱动程序!)可用于python客户端:
java_import(gateway.jvm,"org.mydatabase.MyDBClient")
目前尚不清楚将第三方库添加到jvm类路径的位置。我试图添加到compute-classpath.sh,但这似乎并没有奏效:我明白了
Py4jError: Trying to call a package
另外,与Hive进行比较时:Hive jar文件不会通过compute-
classpath.sh加载,这使我感到怀疑。似乎在建立jvm端类路径的其他机制正在发生。
3.2、spark集群运行应用之第三方jar的处理方式
在编写程序时,不可避免会用到第三方jar,有三种使用方式:
1、将运行程序需要的所有第三方 jar,分发到所有spark的/soft/spark/jars下
2、将第三方jar打散,和自己的源码打成一个jar包,如3.1中
3、在spark-submit命令中,通过--jars指定使用的第三方jar包
在s102上提交,fastjson-1.2.47.jar 本地,myspark.jar本地,temptags.txt HDFS上
spark-submit --class a --jars fastjson-1.2.47.jar --master spark://s101:7077 myspark.jar temptags.txt
spark-shell脚本也用到spark-submit,因此也可以通过spark-shell指定第三方 jar
spark-shell --master spark://s101:7077 --jars fastjson-1.2.47.jar //该jar在本地
import java.util._
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
import com.alibaba.fastjson._
def pp(line: String)={ //解析方法
val list = new ArrayList[String]
val jsonObject = JSON.parseObject(line)
val extInfoList = jsonObject.getJSONArray("extInfoList")
if (extInfoList != null && extInfoList.size != 0) {
for (o <- extInfoList) {
val jo = o.asInstanceOf[JSONObject]
if (jo.get("title") == "contentTags") {
val values = jo.getJSONArray("values")
for (value <- values) {
list.add(value.toString)
}
}
}
}
list
}
val rdd1 = sc.textFile("myspark/temptags.txt")
val rdd2 = rdd1.map(s => {val sp = s.split("\t");val lst = pp(sp(1));(sp(0), lst)}).filter(_._2.size() > 0)
val rdd3 = rdd2.flatMapValues(_.asScala).map(t=>((t._1,t._2),1)).reduceByKey((a,b)=>a+b).groupBy(_._1._1).mapValues(_.map(t=>(t._1._2,t._2)))
val rdd4 = rdd3.mapValues(_.toList.sortBy(-_._2)).sortBy(-_._2(0)._2)
val rdd5 = rdd4.collect()
rdd5.foreach(println)
android 添加第三方jar库
右键工程,Build path,
java build path,选择libraries
在右边的按钮中点击“Add Library”
选择“User library”,点击“下一步”
点击“User librarys”按钮
在出现的界面中点击“New..”按钮
在弹出的界面中随便起一个名字,点击“确定”
点击“Add jars”按钮选择第三方jar包,点击“确定”完成。
后面的步骤很重要,如果不进行后面的操作。在Eclipse里显示编译通过,不会有错误,但在模拟器或真机上运行的时候可能就会出现java.lang.noclassdeffounderror之类的错误:
1、在Android项目根目录下新建一个libs文件夹;
2、把你需要的导入的第三方Jar包复制进这个目录;
3、在libs目录上点右键,选Bulid path –> Use as source folder。
Android.mk文件中添加第三方jar文件的方法
下面给大家介绍Android.mk文件中添加第三方jar文件的方法,具体内容详情如下所示:
先添加:
LOCAL_STATIC_JAVA_LIBRARIES += clib
clib为jar文件名,没有后缀
然后下面语句中间添加
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES :=clib:libs/clib.jar include $(CLEAR_VARS) include $(BUILD_MULTI_PREBUILT)
即:
include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := clib:libs/clib.jar include $(BUILD_MULTI_PREBUILT)
libs/clib.jar代表:文件夹/文件名
如果有多个jar文件,可以这样
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := clib:libs/clib.jar \ mygson:libs/mygson.jar
ps:android.mk中引用第3方 jar包的方法
在某一应用程序中有时候需要引用第三方jar包,那么怎么才能在编译app的时候把该jar包引入进入呢? 在该app下的Android.mk文件中添加如下语句: ------------------------------start----------------------------------------------- LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := user eng ######################################## LOCAL_STATIC_JAVA_LIBRARIES := lib3party //定义引用名 ######################################## .... include $(BUILD_PACKAGE) ############################################################### include $(CLEAR_VARS) LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := lib3part:libs/3part.jar // 引用名:jar包名 include $(BUILD_MULTI_PREBUILT) ################################################################ --------------------------------end---------------------------------------------------------------- 以上红色字体部分为添加jar包的语句,其中关键在于LOCAL_STATIC_JAVA_LIBRARIES := libarity和LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libarity:lily.jar 这两句。 libarity为jar包的别名,可以随便取,只要与下面相对应就行。但是后面冒号后面的那个jar包名字就必须写你需要引入的jar包名字。jar包应该方在工程的根目录下,也就是与你要编译的app的src,res,Android.mk文件同级的目录。
总结
以上所述是小编给大家介绍的Android.mk文件中添加第三方jar文件的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
您可能感兴趣的文章:
- Android开发之Android.mk模板的实例详解
- 浅析Android.mk
- 详解安卓系统中的Android.mk文件
C++项目通过JNI使用Java第三方jar包
最近在C++项目中碰到了需要使用第三方公司开发的Java jar包的问题,最后使用了JNI来解决。
参考了网络上不少的方法介绍, 大多数介绍JNI的文章讲的的都是Java通过JNI来调C的本地代码,其实这个也可以反过来用就是C的本地代码通过创建Java虚拟机调用java方法。下面贴一下解决实例C2JavaJym.c,注释不是很多。
#include <jni.h>
#include <stdlib.h>
#include <string.h>
/*C字符串转JNI字符串*/
jstring stoJstring(JNIEnv* env, const char* pat) {
jclass strClass = (*env)->FindClass(env, "Ljava/lang/String;");
jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>",
"([BLjava/lang/String;)V");
jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat));
(*env)->SetByteArrayRegion(env, bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = (*env)->NewStringUTF(env, "utf-8");
return (jstring)(*env)->NewObject(env, strClass, ctorID, bytes,
encoding);
}
/*JNI字符串转C字符串*/
char* jstringTostring(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "utf-8");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
"(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
strencode);
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen> 0) {
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
return rtn;
}
/*C和Java的字符串类型不同需要在这里进行装换*/
int main(int argc, char **argv) {
if(argc<7)
{
fprintf(stderr, "参数个数不足\n");
return -1;
}
int res;
JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
/*设置初始化参数*/
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path=.:../lib/jym.jar:../lib/codeutil.jar"; //这里指定了要使用的第三方Jar包
options[2].optionString = "-verbose:NONE"; //用于跟踪运行时的信息
/*版本号设置不能漏*/
vm_args.version=JNI_VERSION_1_4;//jdk版本目前有1.1,1.2,1.4 只要比你的jdk的版本低就可以 我用的是jdk1.5.0的版本
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (res < 0 || jvm == NULL || env == NULL) {
fprintf(stderr, "Can''t create Java VM\n");
return -1;
}
fprintf(stdout, "ok 调用JNI_CreateJavaVM创建虚拟机\n");
/*获取实例的类定义*/
jclass cls = (*env)->FindClass(env, "ptest/JymProduce"); //这里是jar包内JymProduce类的具体路径
if (cls == 0) {
fprintf(stderr, "FindClass failed\n");
(*jvm)->DestroyJavaVM(jvm);
fprintf(stdout, "Java VM destory.\n");
return -1;
}
fprintf(stdout, "ok 返回JAVA类的CLASS对象\n");
/*创建对象实例*/
jobject obj = (*env)->AllocObject(env, cls);
if (obj == NULL) {
fprintf(stderr, "AllocObject failed\n");
(*jvm)->DestroyJavaVM(jvm);
fprintf(stdout, "Java VM destory.\n");
return -1;
}
fprintf(stdout, "ok 获取该类的实例\n");
/*获取构造函数,用于创建对象*/
/***1.1可用""作为构造函数, 1.2用"<init>"参数中不能有空格
"(Ljava/lang/String;)V"*/
jmethodID mid = (*env)->GetMethodID(env, cls, "getGertWord",
"(Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
if (mid == 0) {
fprintf(stderr, "GetMethodID failed\n");
(*jvm)->DestroyJavaVM(jvm);
fprintf(stdout, "Java VM destory.\n");
return -1;
}
fprintf(stdout, "ok 获取类中的方法\n");
//构造参数并调用对象的方法
//发票代码
jstring fpdm = stoJstring(env, argv[2]);
//发票号码
jstring fphm = stoJstring(env, argv[3]);
//开票金额
jlong kpje = (jlong)atoi(argv[4]);
//开票时间,格式为YYYYMMDD
jstring kpsj = stoJstring(env, argv[5]);
//行业分类代码
jstring hydm = stoJstring(env, argv[6]);
char szJym[8];
memset(szJym, 0, sizeof(szJym));
jstring msg = (jstring) (*env)->CallObjectMethod(env, obj, mid, fpdm, fphm, kpje, kpsj, hydm);
strcpy(szJym,jstringTostring( env, msg));
fprintf(stdout, szJym);
fprintf(stdout, "\n");
fprintf(stdout, "ok Java返回参数\n");
PrintToFile(argv[1],szJym);
/*捕捉异常*/
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
return -1;
}
/*销毁JAVA虚拟机*/
(*jvm)->DestroyJavaVM(jvm);
fprintf(stdout, "Java VM destory.\n");
}
int PrintToFile(const char* filename,const char* content)
{
FILE *fp;
if((fp=fopen(filename,"w"))==NULL)
return(-1);
fputs(content, fp);
fclose (fp);
fflush(stdin) ;
fflush(stdout) ;
return 0;
}
这里是将C调用Jar包获取jym的过程生成了一个C2JavaJym的可执行程序,通过命令行来调用生成包含jym的临时文件供C++项目来读取。
编译命令 gcc -o C2JavaJym C2JavaJym.c -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -L${JAVA_HOME}/jre/lib/amd64/server -ljvm
char sCmd[101];
memset(sCmd, 0, sizeof(sCmd));
strcpy(sCmd, "C2JavaJym ");
char sFile[21];
memset(sFile, 0, sizeof(sFile));
sprintf(sFile, "Jym%d.j", getpid() );
strcat(sCmd, sFile);
strcat(sCmd, " ");
strcat(sCmd, sFPDM);
strcat(sCmd, " ");
strcat(sCmd, sFPHM);
strcat(sCmd, " ");
strcat(sCmd, sFPJE);
strcat(sCmd, " ");
strcat(sCmd, sDate);
strcat(sCmd, " ");
strcat(sCmd, sHYDM);
strcat(sCmd, " 1>/dev/null");
system(sCmd);
/*以上是调用生成校验码*/
char buf[101];
memset(buf, 0, sizeof(buf));
FILE* pf = fopen(sFile, "r");
if (pf!=NULL)
{
if (!feof(pf))
{
fgets(buf, sizeof(buf)-1, pf);
}
else
{
tuxData.setRsp("4401","获取校验码失败!");
return false;
}
}
else
{
tuxData.setRsp("4401","获取校验码失败!");
return false;
}
StrNCpy(sJYM,buf,7);
/*通过读取文件获取校验码*/
memset(sCmd, 0, sizeof(sCmd));
strcpy(sCmd, "rm ");
strcat(sCmd, sFile);
strcat(sCmd, " 1>/dev/null");
system(sCmd);
/*删除临时文件*/
也可以在命令行之间执行 C2JavaJym Jym2.j 235051102210 00002520 3456 20110330 04 来调用
这个方案比较土,不过还是有效的。我也试过将这个过程编译到CPP源代码中和tuxexdo服务端的pc文件中,但是都在创建虚拟机后,找不到指定的类,虚拟机的销毁也有问题,感觉是虚拟机创建的有问题。
另外还有2个方案只有构想还没有尝试过。一个是利用linux的消息机制,将Java虚拟机作为守护进程一样起在后台,C++项目往A消息队列上扔需要校验的数据,启动Java虚拟机的进程从这个A队列上获取数据,并计算出校验码,再扔到B队列上,C++项目再从这个B队列上获取算出来的校验码。这个过程可以减少Java虚拟机被频繁的创建和销毁,减少开销,但是如果并发量上来的话,等在B队列上获取校验码的C++进程比较多,怎么保证从B队列上取到的就是自己发送的内容的校验码是个问题。另一个也类似了就是利用socket来代替消息队列进行通讯。
不过实际项目中测试虚拟机的从创建到销毁的整个过程还是很快的,不像在我本机windows上那么慢,开销应该还是可以接受的。
关于如何添加第三方Java jar以便在pyspark中使用和java添加第三方类库的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于3.2、spark集群运行应用之第三方jar的处理方式、android 添加第三方jar库、Android.mk文件中添加第三方jar文件的方法、C++项目通过JNI使用Java第三方jar包的相关信息,请在本站寻找。
本文标签: