关于pyhanlp报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误的解决

关于pyhanlp报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误的解决

最近学习NLP用HanLP进行分词,在python中通过pip安装pyhanlp正常,导入pyhanlp进行分词或使用hanlp命令都报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm',网上都没有查到类似的错误,只有靠自己了。

报错细节如下:

...
...
...
~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/jpype/_jvmfinder.py in get_jvm_path(self)
    160                 jvm = method()
    161 
--> 162                 # If found check the architecture
    163                 if jvm:
    164                     self.check(jvm)

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/jpype/_jvmfinder.py in _get_from_known_locations(self)
    215         for home in self.find_possible_homes(self._locations):
    216             jvm = self.find_libjvm(home)
--> 217             if jvm is not None:
    218                 return jvm

~/anaconda3/envs/tensorflow/lib/python3.7/site-packages/jpype/_jvmfinder.py in find_possible_homes(self, parents)
    120             for childname in sorted(os.listdir(parent)):
    121                 # Compute the real path
--> 122                 path = os.path.realpath(os.path.join(parent, childname))
    123                 if path in homes or not os.path.isdir(path):
    124                     # Already known path, or not a directory -> ignore

FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'

原因分析:

可以看到是在执行_jvmfinder.py文件的find_possible_homes遇到的问题,于是打开这个文件去看了报错文件的源代码。我们在调用hanlp时将运行_jvmfinder.py的get_jvm_path()函数来获取系统的java路径,get_jvm_path定义如下

# 第147行
    def get_jvm_path(self):
        """
        Retrieves the path to the default or first found JVM library

        Returns:
            The path to the JVM shared library file

        Raises:
            ValueError: No JVM library found or No Support JVM found
        """
        jvm_notsupport_ext = None
        for method in self._methods:
            try:
                jvm = method()

                # If found check the architecture
                if jvm:
                    self.check(jvm)

# 后面 略

而get_jvm_path()实际上是运行self._methods中的方法,我们再看self._methods的定义(__init__()中):

# 第62行左右
        # Search methods
        self._methods = (self._get_from_java_home,
                         self._get_from_known_locations)

_methods中存的是本文件的另外两个函数,先运行_get_from_java_home(),如果没找到再运行_get_from_known_locations()。前面我们报错的是_get_from_known_locations(),那也就是说_get_from_java_home()没有成功找到java,来看这个函数的定义:

# 第186行
    def _get_from_java_home(self):
        """
        Retrieves the Java library path according to the JAVA_HOME environment
        variable

        Returns:
            The path to the JVM library, or None
        """
        # Get the environment variable
        java_home = os.getenv("JAVA_HOME")
        if java_home and os.path.exists(java_home):
            # Get the real installation path
            java_home = os.path.realpath(java_home)

            # Cygwin has a bug in realpath
            if not os.path.exists(java_home):
                java_home = os.getenv("JAVA_HOME")

            # Look for the library file
            return self.find_libjvm(java_home)

这个函数主要通过获取系统环境变量JAVA_HOME来得到java的地址。可是命令行中运行java正常,为什么没找到这个环境变量呢? 重新查看一下配置文件/etc/profile中java环境变量的配置,如下

# set java path 
JAVA_HOME=/usr/local/java/latest
export PATH=${JAVA_HOME}/bin:${PATH}
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

平时在命令行中能直接运行java,是因为java所在的bin目录被添加到PATH,且由export PATH后作为环境变量生效。但是JAVA_HOME只是作为普通变量,使用os.getenv()的时候获取环境变量时找不到JAVA_HOME,所以推测应该只要将JAVA_HOME前面添加export,然后重新source或重新登录即可。

解决办法:

在全局配置文件/etc/profile或个人配置文件~/.bashrc或~/.bash_profile中添加export JAVA_HOME即可,如下是我的/etc/profile的设置:

# set java path 
export JAVA_HOME=/usr/local/java/latest
export PATH=${JAVA_HOME}/bin:${PATH}
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

其他注意事项:如果使用PyCharm远程调试,若遇到同样报错,需要在导入pyhanlp前先设置环境变量,如下

# 设置环境变量
import os
os.environ['JAVA_HOME'] = '/usr/local/java/latest'

# 再导入hanlp 即可避免无法找到java的问题
import pyhanlp as hanlp

解决效果:

修改后重新source或重新开一个终端窗口,可以成功运行hanlp segment命令

关于pyhanlp报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误的解决_第1张图片

也可以在jupyter-lab中正常运行:

关于pyhanlp报FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/jvm'错误的解决_第2张图片

你可能感兴趣的:(nlp,hanlp)