问题及解决方法:
1、System.loadLibrary("License");时出错
解决:libLicense.so文件要放到正确的目录下,可以利用System.getProperty("java.library.path"));打印出path,我放的是 /lib/ 下面
2、verifylicense 本地方法找不到
解决:头文件和C的JNIEXPORT 定义的方法名要正确,包含License.java的包名,如果Java中定义的method有划线的话,头文件中下划线后面要紧跟一个1
3、加载文件和方法都没有问题,运行的时候没有执行
解决:这个问题困扰了我一段时间,最后发现安装环境时加了一个文件:/etc/profile,而这个文件里面没有声明CATALINA_HOME、CATALINA_BASE,并且CLASSPATH里面没有带上servlet-api.jar包,所以native方法无法在servlet容器中执行
部分代码:
1、web.xml
<servlet> <servlet-name>license</servlet-name> <servlet-class>com.blingtel.common.util.License</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
2、License.java
package com.xxx.common.util; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /* * 文件名称: CheckLicense.java * 文件描述: <描述> * @version 1.0 * @author */ /** * <校验License> * <功能详细描述> * @author zengyouyuan * @version [版本号, 2013-7-5] * @see [相关类/方法] * @since [产品/模块版本] */ public class License extends HttpServlet { /** * 注释内容 */ private static final long serialVersionUID = 1L; /** * 日志对象 */ private static Log logger = LogFactory.getLog(License.class); private native boolean verifylicense(); static { int i = 0; try { logger.error("loadLibary start..."); System.loadLibrary("License"); i = 1; logger.error("load Libary OK..."); } catch (Exception e) { i = 2; // TODO Auto-generated catch block logger.error("load error"); e.printStackTrace(); Runtime runtime = Runtime.getRuntime(); try { i = 3; logger.error("load libLicense.so error, killall java"); runtime.exec("killall java"); } catch (Exception e1) { i = 4; // TODO Auto-generated catch block e1.printStackTrace(); } } finally { logger.error("i = " + i); if (i == 0) { Runtime runtime = Runtime.getRuntime(); try { logger.error("load libLicense.so error, killall java"); runtime.exec("killall java"); System.exit(0); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } public void init(ServletConfig servletConfig) throws ServletException { logger.error("income License.init()"); License l = new License(); if (l.verifylicense()) { logger.error("verify_license ERROR"); Runtime runtime = Runtime.getRuntime(); try { logger.error("verify license failed, killall java"); runtime.exec("killall java"); System.exit(0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { logger.error("verify license success! create ok.txt file"); logger.error("verify_license OK"); } } }
3、License.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class License */ #ifndef _Included_License #define _Included_License #ifdef __cplusplus extern "C" { #endif /* * Class: License * Method: verify_license * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_com_blingtel_common_util_License_verifylicense (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
4、license_decrypt.c部分代码
#include <stdio.h> #include <string.h> #include <sys/ioctl.h> #include <net/if.h> #include <errno.h> #include "base64.h" #include "rsa.h" #include <jni.h> #include "License.h" #define KEY_LEN 128 #define RSA_N "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"\ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" #define RSA_E "010001" #pragma GCC push_options #pragma GCC optimize ("O0") int verify_license(); /* Header for class IntArray */ #ifdef __cplusplus extern "C" { #endif JNIEXPORT jboolean JNICALL Java_com_blingtel_common_util_License_verifylicense (JNIEnv * env, jobject job) { return verify_license(); } #ifdef __cplusplus } #endif