swig+crf++0.58+java环境配置详解(win+linux)

时间:2021-06-06 21:24:05

前言


      因为刚在公司接手了一个使用crf++做对象识别的项目,该项目之前一直不能在windows上运行(crf++需要配置相应的环境,并且如

果想和JAVA整合需要用swig来封装动态链接库形成JNI接口),而且也缺乏日志,所以就想直接配置出windows的开发调试环境,在网

上搜索了很多前辈的方法,很受启发,但是也有一些语焉不详的地方让我入了不少坑,所以在此准备将Linux的Crf+java整合方法和

windows的Crf+java环境配置方法都整理出来,也为自己之后的留用,也为给有同样需求的同学提供一些小小的帮助。

配置步骤


    1.windows


         软件环境  win10 + crf++0.58win32  + jdk1.7.0._45(win32) + swigwin3.0.10 + swig-3.0.12 + visual studio2017(crf和swig之类的

东西会在末尾打包留种的)

     Tip:关于为什么使用32位的jdk是因为crf++0.58只有linux版本和win32版本的,如果用64位的jdk的话在加载libcrfpp.dll的时候容易 出现Can't load IA

32-bit .dll on a AMD 64-bit platform的问题,当然不是说不能搞,只不过为了方便起见,博主还是直接安装了一个 32位的jdk,关于win上安装多个jdk有

时候会出现改环境变量不好使的情况,这个时候可以检查下 控制面板-》java-》java-》查看 在 里面设置运行时环境设置,如果还不好使的话你

C:\Windows\System32\目录下绝对有java.exe,javaw.exe,javaws.exe这些文件,直 接删掉就好,这个操作的详细描述请戳



     由于CRF++是用c++编写的条件随机场工具,为了在JAVA为主体的程序中使用的话就应该使用JNI技术对java进行扩展,并将CRF++编译为可供java

调用的动态链接库。SWIG可以帮我们将C++编写的CRF++和JAVA系统进行联合。

    首先将 XXX\CRF++-0.58\sdk(windows版) 目录下的crfpp.h,libcrfpp.lib两个文件拷贝出来放在一个单独的文件夹里,在将XXX\CRF++-0.58\swig

下的CRFPP.i和version.h拷贝出来放在同样的目录下,这个时候这个目录的截图是这样的。swig+crf++0.58+java环境配置详解(win+linux)

        打开CRFPP.i,在倒数第二行的地方将%include ../crfpp.h   改为    %include crfpp.h  因为他们现在都在同一个文件夹下了嘛。



      之后我们需要使用win版的swig了,直接解压就可以用,你也可以将swig的swig.exe添加进环境变量,这样不需要每次使用都再输一大串的地址。

      如果配置了swig环境变量  swig –c++ -java -package org.anon.crfpp CRFPP.i   (-package 后面的包名自己随便起的啦)

      没配的话就给一个全路径咯  /d/crf++Env/swig3.0.10win/swigwin-3.0.10/swig.exe -c++ -java -package com.anon.crfpp /d/crf++Env/sdkCol/CRFPP.i

(我 是在git bash里执行的,cmd的自己转下路径格式)

swig+crf++0.58+java环境配置详解(win+linux)

    然后在我们的文件夹中可以看到以下文件。swig+crf++0.58+java环境配置详解(win+linux)


      *.java就是swig生成的调用文件,测试类可以去linux版的crf++0.58下的java目录下拷贝出test.java类,将这些类拷进一个项目中。


  swig+crf++0.58+java环境配置详解(win+linux)


    接下来就是最容易出错也是最麻烦的环节了,我们要编译一个dll动态链接库,在这里我使用的是Visual studio 2017,当然任何版本的都是可以的,

swig+crf++0.58+java环境配置详解(win+linux)

swig+crf++0.58+java环境配置详解(win+linux)

     在项目配置向导这里记得要选择dll,附件选项选上空项目即可,要不然会有一堆然并卵的东西生成。

     接下来我们将生成的CRFPP_wrap.cxx(和*.java一起生成的)文件拷贝入CRFPP项目中,放在源文件下

swig+crf++0.58+java环境配置详解(win+linux)

这个时候你可以试着右键项目,生成一下,会报错误如下

swig+crf++0.58+java环境配置详解(win+linux)

这是因为我们编译dll还需要JDK中jni.h的帮助,这个时候我们可以对项目进行少许配置。

右键工程点击属性  配置属性-》VC++目录中进行如下配置


swig+crf++0.58+java环境配置详解(win+linux)

     将包含目录中添加你使用的jdk的include目录( xxx\java\jdk_1.7.0_45win32\include) ,和include下的32win目录(xxx\java\jdk_1.7.0_45win32

\include\win32)。

    在库目录下添加win版的crf++的sdk文件夹,也就是libcrfpp.lib的目录(xxx\crf++Env\CRF++-0.58\sdk)。

    网上有的博客说这样就可以生成成功了,大家可以试一下,反正我配置到这一步没有生成成功,报之下的错误



swig+crf++0.58+java环境配置详解(win+linux)

   如果你到这一步能生成成功那很Nice,不能的话那就接着按之下的步骤进行配置。

   依旧是右键项目,属性,链路器下的常规再配置下附加库目录,

    swig+crf++0.58+java环境配置详解(win+linux)

  接着还没完,在链路器下的输入里加上libcrfpp.lib,编辑里直接输就可以

swig+crf++0.58+java环境配置详解(win+linux)


   OK,全部配置流程走完了。build一下试试。

swig+crf++0.58+java环境配置详解(win+linux)

    果不其然的生成成功了,但是请注意这个时候是Debug模式生成的dll,这个时候我们要再调到Release模式生成一遍dll,使用release的dll去进行

JAVA整合调用。对的,是不是又报错了?那是因为Release和debug的属性是两套,再练一遍熟下手吧,我也是为你好swig+crf++0.58+java环境配置详解(win+linux)


    接下来就是和JAVA项目整合了,在项目里建一个文件夹,我比较习惯取名lib,将刚生成的dll文件和win版的CRF++0.58目录下的 libcrfpp.dll都拷入文

件夹下。

swig+crf++0.58+java环境配置详解(win+linux)


   然而工作并没有结束,我们要在JRE System Library里添加入lib的配置路径,右键点击JRE System Library 然后build Path ->configure build path

   swig+crf++0.58+java环境配置详解(win+linux)

     将之前的lib文件夹目录配置入Native library location中,如下所示

   swig+crf++0.58+java环境配置详解(win+linux)

  然后运行test.java 的main方法,不过记得之前将他读取的模型路径改变一下swig+crf++0.58+java环境配置详解(win+linux)

  如果没有模型的话在附件里找就行,友情提供一个。


   然后当你满怀激动的心情运行的时候,他偏偏有可能报这个错swig+crf++0.58+java环境配置详解(win+linux)

 

       这是因为我们的dll库并不叫CRFPP,而是叫CRFPP_demo,我们load的library应该是和这个dll库同名的,然后我们很无奈的改了loadLibrary的参数

以后,他很有可能还会报一个错。


   swig+crf++0.58+java环境配置详解(win+linux)

  
      这句话的意思是找不到依赖的dll包,感觉这个有很多种解决方案,有人说可以直接在C:\Windows\System32文件夹下加入libcrfpp.dll就好,但是我尝

试的并没有什么效果,同样尝试了感觉没什么效果的可以再加一行load库的代码如下。然后运行成功

swig+crf++0.58+java环境配置详解(win+linux)



     这是在eclipse下的crfpp配置,IDEA下的其实也差不多,有人想配的话照着这个流程来就行,实在出不来了给我留言我更新下,windows占的篇幅太

多了,有一些坑没有全部列出来,如果有哪些坑以上没有涉及到可以留言,我再更新(毕竟win下坑还是蛮多的)。



    2.Linux

       软件环境  CentOS release 6.9 (Final),CRF++0.58,pcre-8.32.tar.gz,swig3.0.12, java version "1.8.0_111".

 

      首先确认一点,你的jdk如果是openjdk的话你需要删除它,安装正常的jdk,就是打印java -version出现信息是如下这样的jdk


     java version "1.8.0_111"
    Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
     Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)


    卸载方法自行百度,jdk安装方法也不多说了,都很简单。

   swig+crf++0.58+java环境配置详解(win+linux)

  

           tar -zxvf CRF++-0.58.tar.gz  解压

           然后cd进去三步走起

 

./configure

make

make install



    如果没有安装g++会报错应该,安装的命令是:yum install -y gcc-c++



   如果三步进行完了我们就可以开始训练自己的模型了,正好也测试下crf++到底好不好使。



   在训练模型的时候需要模板和语料,这个大家可以自己上网找一下,我在附加中也会提供一些简单的仅供测试的语料和模板,关于模板和


模型之类的知识不是本文讨论的重点,大家可以自行查阅相关文章。


训练模型   crf_learn segment_template train.data test.model -t  (segment_template是模板,train.data是训练语料,test.model


是生成的模型名字, -t的意思是生成可读的模型,可用于深入理解CRF模型)


如果报以下错误


crf_learn: error while loading shared libraries: libcrfpp.so.0: cannot open shared object file: No such file or directory

 
则修改/etc/ld.so.conf文件,加入 include /usr/local/lib,执行/sbin/ldconfig -v,刷新LIB库,再试试就好用了。

   


swig+crf++0.58+java环境配置详解(win+linux)


   然后用生成的模型来标注下测试语料,

      crf_test -m seg_1_test.model test.data > result.txt (-m 后面选择要使用的模型,test.data是要标注的语料,result.txt是标注结

果,本文提供的测试语料是简单的BMES标注,只为熟悉流程。train.data和result.txt的内容应该是一样的,你也可以找一些其他的测试语料来测

试模型的标注效果。PS:本文语料选择中石化新闻网)。

   
swig+crf++0.58+java环境配置详解(win+linux)


    OK,测试CRF运行无误以后我们开始用swig整合JNI接口联合JAVA。

  
    tar -zxvf swig-3.0.12.tar.gz 使用命令解压swig,然后cd进入swig目录。

    将pcre-8.32.tar.gz拷贝入swig目录,在目录下依次执行

   

./Tools/pcre-build.sh

./configure

make

make install

     

    然后可以用swig -version查看版本

   swig+crf++0.58+java环境配置详解(win+linux)


   显示版本则证明swig安装成功,这个时候我们开始使用swig将crf++封装为JNI接口。

   cd CRF++-0.58/swig/ 进入CRF下的swig目录。
 
   make

  然后再进入crf下的java目录  cd ../java/

   make

  这个时候报错了,找不到jni.h

  swig+crf++0.58+java环境配置详解(win+linux)

 

打开文件CRFPP_wrap.cxx,找到这一行 : #include <jni.h> ,将这一行改为:


#include "jni.h"


然后,到java的安装目录下,将这两个文件(jni.h,jni_md.h)拷贝到 /crf0.58/java目录下。


然后make,编译成功


这个时候一般来讲运行java test是不会直接就成功的,我们还需要对test.java做一些修改。


swig+crf++0.58+java环境配置详解(win+linux)


这个时候就把这里的model路径换成之前我们生成的model路径。wq保存退出再make


很多人会发现然而这并没有什么用,该报错还是报错,那么依序执行以下命令


cp libCRFPP.so/lib

cp libCRFPP.so/lib64

cp libCRFPP.so/usr/lib

cp libCRFPP.so/usr/lib64

chmod 775 /usr/lib64/libCRFPP.so

然后执行下列命令:

cd /usr/local/lib

cp libcrfpp.so.0 /usr/lib64


最后不要忘了回到CRF++0.58的java目录下。


再试下java test。再没结果给我留言


swig+crf++0.58+java环境配置详解(win+linux)