因为学习需要,使用到了中文分词技术,网上搜索一番,最终选择了名气比较大的中科院分词器(NLPIR/ICTCLAS)。


用了几个月之后突然报错:

E:\code\URLClassifier\Data\NLPIR.user Not valid license or your license expired! Please feel free to contact pipy_zhang@msn.com!

手动更新License之后,过了一个月又过期了。才知道免费License的周期由三个月缩短为一个月了。

所以想能不能自动更新 License,免得时不时的过期,需要手动去更新。

首先想到做一个定时任务,隔断时间去下载最新的 License 不就行了吗。 最后发现这样不行,官方License的更新周期不固定,总不能隔一分钟去下载一次吧。

然后就想到另一种规避办法,每次初始化NLPIR时先检测 License 是否过期,如果过期就更新 License 。最后证明这种办法是可行的。但是要注意,不能在同一个 JVM 中初始化两次 NLPIR(会报 Other thread is under initialization )因为如果第一次初始化  NLPIR 失败,然后更新 License ,再次初始化时不会发现新下载的 License 文件!目前不清楚具体原因是什么(有知道的童鞋记得指教!),猜测应该是因为 NLPIR 用到了JNA 接口,JNA 在 load library 执行之后, filesystem cache 并没有在下载文件后及时更新。

所以只能让两次初始化处在两个独立的 JVM 中,很简单,写一个检测 License 程序打包后在另外一个程序中调用,检测到 License 过期后,更新 License 再初始化就不会出现 Other thread is under initialization 错误。

LicenseChecker.java

import com.sun.jna.Native;

/**
 * check if NLPIR license is expired
 * 
 */
public class LicenseChecker {
	public static void main(String[] args) {
		if (args.length < 1) {
			System.out.println("java -jar LicenseChecker.jar libPath [DataPath]");
			System.exit(2);
		}

		System.exit(run(args[0], args.length == 1 ? "" : args[1]));
	}

	/**
	 * try initial NLPIR
	 * 
	 * @param lib
	 * @param data
	 * @return 0 if license invalid or other exception happened else return 1
	 *         represent initial NLPIR success
	 */
	public static int run(String lib, String data) {
		int status = 0;
		NlPIRLibrary instance = (NlPIRLibrary) Native.loadLibrary(lib,
				NlPIRLibrary.class);
		if (instance.NLPIR_Init(data, 1, "")) {
			status = 1;
		}
		instance.NLPIR_Exit();
		return status;
	}
}


NlPIRIniter.java

/**
 * get NLPIR Object
 * 
 * 
 */
class NlPIRIniter {
	// license update url
	public static final String latestLicenseUrl = "https://github.com/NLPIR-team/NLPIR/raw/master" +
<span style="white-space:pre">		</span>"/License/license%20for%20a%20month/NLPIR-ICTCLAS%E5%88%86%E8%AF%8D%E7%B3%BB%E7%BB%9F%E6%8E%88%E6%9D%83/NLPIR.user";

	/**
	 * initialization NLPIR (handle license expired problem)
	 * 
	 * @param lib
	 * @param data
	 * @param licenseCheckerJarPath
	 * @return
	 * @throws Exception
	 */
	public static NlPIRLibrary getInstance(String lib, String data,String licenseCheckerJarPath)
			throws Exception {
		// call another jar to check if license is expired
		Process p = Runtime.getRuntime().exec(
				"java -jar " + licenseCheckerJarPath + " " + lib + " " + data);
		p.waitFor(10, TimeUnit.SECONDS);
		// return 0 when initial failed
		if (p.exitValue() == 0) {
			FileDownLoader.get(latestLicenseUrl,
					Paths.get(data, "Data", "NLPIR.user").toString());
		}
		NlPIRLibrary instance = (NlPIRLibrary) Native.loadLibrary(lib,
				NlPIRLibrary.class);

		if (instance.NLPIR_Init(data, 1, "0")) {
			return instance;
		}
		throw new Exception(instance.NLPIR_GetLastErrorMsg());
	}
}


这样 NLPIR 分词的 License 问题算是解决了。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐