【问题标题】:pyjnius "Class not found" when importing jar file导入jar文件时pyjnius“找不到类”
【发布时间】:2015-03-14 10:25:27
【问题描述】:

我正在尝试让 pyjnius 使用我从 java 应用程序构建的 jar 文件,但我不断收到“找不到类”错误:

>>> import os
>>> os.environ['CLASSPATH'] = "~/workspace/myapp-Tools/Admin/Console/couchdb/myapp-web.jar"
>>> from jnius import autoclass
>>> bla = autoclass('com/myapp/webapp/server/helpers/licensee/CalculationHelper')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/home/sam/workspace/myapp-Tools/Admin/Console/couchdb/virtualenv/local/lib/python2.7/site-packages/jnius/reflect.py", line 150, in autoclass
   c = find_javaclass(clsname)
 File "jnius_export_func.pxi", line 23, in jnius.find_javaclass (jnius/jnius.c:12815)
jnius.JavaException: Class not found 'com/myapp/webapp/server/helpers/licensee/CalculationHelper'
>>> 

当然我已经检查过了:

jar tf myapp-web.jar

com/myapp/webapp/server/helpers/licensee/CalculationHelper.class 就在里面

我也试过这样设置类路径:

import jnius_config
jnius_config.set_classpath('.', '~/workspace/myapp-Tools/Admin/Console/couchdb/')
#import jnius
from jnius import autoclass

但这给了我同样的结果。 我正在开发一个 virtualenv 顺便说一句。 我已经尝试了所有可以在网上找到的方法,但它根本不起作用。我不得不手动安装 pyjnius,因为使用 pip 得到了它的旧版本。 任何帮助将非常感谢


编辑:尝试使用不是我创建的 jar 进行此操作,但我看到了不同的错误

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import jnius_config
>>> jnius_config.add_classpath('/home/sam/workspace/someproject/*')
>>> jnius_config.expand_classpath()
'/home/sam/workspace/someproject/annotations.jar:/home/sam/workspace/someproject/junit-4.10.jar:/home/sam/workspace/someproject/    postgresql-8.1-408.jdbc3.jar'
>>> import jnius
>>> from jnius import autoclass
>>> test = autoclass('org/postgresql/geometric/PGcircle.class')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sam/workspace/myapp-Tools/Admin/Console/couchdb/virtualenv/local/lib/python2.7/site-packages/jnius/reflect.py", line 150,     in autoclass
    c = find_javaclass(clsname)
  File "jnius_export_func.pxi", line 23, in jnius.find_javaclass (jnius/jnius.c:12815)
jnius.JavaException: Class not found 'org/postgresql/geometric/PGcircle/class'
>>> test = autoclass('org/postgresql/geometric/PGcircle')
Exception in thread "main" java.lang.NoClassDefFoundError: org/postgresql/geometric/PGcircle/class
Caused by: java.lang.ClassNotFoundException: org.postgresql.geometric.PGcircle.class
  at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sam/workspace/myapp-Tools/Admin/Console/couchdb/virtualenv/local/lib/python2.7/site-packages/jnius/reflect.py", line 156,     in autoclass
    for constructor in c.getConstructors():
  File "jnius_export_class.pxi", line 562, in jnius.JavaMethod.__call__ (jnius/jnius.c:19385)
  File "jnius_export_class.pxi", line 649, in jnius.JavaMethod.call_method (jnius/jnius.c:20409)
  File "jnius_utils.pxi", line 43, in jnius.check_exception (jnius/jnius.c:3533)
jnius.JavaException: JVM exception occured
>>> test = autoclass('org/postgresql/geometric/PGcircl')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sam/workspace/myapp-Tools/Admin/Console/couchdb/virtualenv/local/lib/python2.7/site-packages/jnius/reflect.py", line 150,     in autoclass
    c = find_javaclass(clsname)
  File "jnius_export_func.pxi", line 23, in jnius.find_javaclass (jnius/jnius.c:12815)
jnius.JavaException: Class not found 'org/postgresql/geometric/PGcircl'
>>> 

这里是那个 jar 上 jar tf 的内容:

sam@lambda ~/workspace$ jar tf ./someproject/postgresql-8.1-408.jdbc3.jar
META-INF/
META-INF/MANIFEST.MF
...
org/postgresql/geometric/PGbox.class
org/postgresql/geometric/PGcircle.class
org/postgresql/geometric/PGline.class
org/postgresql/geometric/PGlseg.class
org/postgresql/geometric/PGpath.class
org/postgresql/geometric/PGpoint.class
org/postgresql/geometric/PGpolygon.class
...
sam@lambda ~/workspace$ 

再次...任何帮助将不胜感激!

【问题讨论】:

    标签: java python pyjnius py4j


    【解决方案1】:

    tl;dr: 确保 .java 文件被编译为(最多)相同的 Java 版本 .class 文件作为系统上的 Java 版本使用 pyjnius 导入文件。

    加长版:

    我遇到了一个非常相似的问题,但有一个很大的不同:一些文件可以正常运行,而其他文件(在同一目录中)则没有。

    导致“找不到类”异常的文件的问题是我在具有 Java 8 的 Windows 下编译它们。但是,当您运行“sudo apt-get install default-jdk”时,Ubuntu 当前安装 Java 7 .

    因此,pyjnius 无法在我的 Java 7 Ubuntu 安装上导入 Java 8 文件。奇怪的是,它抛出了一个“找不到类”异常,而不是更具描述性的东西。将目标输出更改为 1.7 解决了我的问题。

    【讨论】:

    • +1 It's strange that it throws a 'Class not found' exception, instead of something more descriptive - 这指出了一般问题,这似乎是 jar 的任何运行时问题都可能是此问题的根本原因。对于那些苦苦挣扎的人,请确认您可以在 Python 应用程序尝试运行它的同一环境中独立运行该 jar。
    【解决方案2】:

    我通过在 Eclipse 中将 JAR 导出为可运行的 JAR 文件解决了这个问题:

    1. 如果没有,请在某处创建一个空的 main 方法(否则导出对我不起作用)
    2. 转到文件->导出...
    3. 选择 Java->可运行的 JAR 文件
    4. 点击下一步
    5. 在 Launch 配置中选择 main 方法
    6. 选择您的出口目的地
    7. 选择“将所需库复制到生成的 JAR 旁边的子文件夹中”作为库处理(在我的特殊情况下唯一对我有用的选项,但您也可以测试其他选项)
    8. 点击完成

    【讨论】:

      【解决方案3】:

      当我使用我的 jar 文件时它工作正常。 您是否尝试使用完整路径来定义 CLASSPATH?

      • Windows 7
      • Python 2.7.8
      • jnius 1.1-dev

      此页面可用作参考。 http://www.hackzine.org/using-apache-tika-from-python-with-jnius.html

      我只是想发表评论,但我没有足够的声誉。 所以我留下一个答案作为评论。

      而且你最好不要用“/”代替“。”当您调用自动分类时。 请参阅下面的链接。

      http://pyjnius.readthedocs.org/en/latest/api.html#jnius.autoclass

      【讨论】:

      • 感谢 pgkireek,我直接从 github.com/kivy/pyjnius 使用 Ubuntu 14.04.1 LTS、Python 2.7.6 和 pyjnius。我已经阅读了您发送的两个链接,但对我的情况没有任何帮助。
      • 关于使用“/”而不是“。”调用 autoclass 时,我都尝试过都没有成功.. =/
      【解决方案4】:

      旧帖子,但如果对某人有用,请发布答案。

      我在那里看到两个问题,不确定你是否一起尝试过:

      改变

      jnius_config.set_classpath('.', '~/workspace/myapp-Tools/Admin/Console/couchdb/')

      jnius_config.set_classpath('.', '~/workspace/myapp-Tools/Admin/Console/couchdb/*')

      test = autoclass('org/postgresql/geometric/PGcircl')

      test = autoclass('org.postgresql.geometric.PGcircl')

      【讨论】:

        【解决方案5】:

        您是否尝试过通过导出添加 CLASSPATH,然后运行您的 python 脚本?这对我有用。

        $ export CLASSPATH="~/workspace/myapp-Tools/Admin/Console/couchdb/myapp-web.jar"
        

        【讨论】:

        • 嗨 Benxy 是的,我试过了,但没有运气。具有相对路径和绝对路径。
        • 但是你真的尝试从 shell 设置 env var 吗?不是来自 python 脚本。在我的项目中: import os os.environ['CLASSPATH'] = "/home/code/my_proj/my.jar" 不起作用。首先,我在 shell 中导出 CLASSPATH="/home/code/my_proj/my.jar" 然后运行“python my_script.py”,然后自动分类工作。当我从 shell 设置环境变量时,它就像一个魅力。查看此链接:askubuntu.com/questions/389683/…
        • 嗨 Benxy,再次是的。我在 bash 中构建了一个包装器脚本,以在调用 python 脚本之前调用设置类路径的 python 脚本。谢谢
        【解决方案6】:

        我通过将 CLASSPATH 放入 .bashrc 解决了这个问题

        CLASSPATH="~/documents/download/programs/tika-app.jar"

        它可以正常工作

        【讨论】:

          【解决方案7】:

          下面的代码将一个 jar 添加到类路径中,然后显示类路径以进一步调试。

          import os
          import jnius_config
          
          jnius_config.add_classpath("PATH_HERE/SOME.jar")
          
          from jnius import autoclass, cast
          
          ClassLoader = autoclass('java.lang.ClassLoader')
          cl = ClassLoader.getSystemClassLoader()
          ucl = cast('java.net.URLClassLoader', cl)
          urls = ucl.getURLs()
          tmp = [url.getFile() for url in urls]
          print('\n'.join(tmp))
          

          【讨论】:

            猜你喜欢
            • 2014-02-25
            • 2020-11-18
            • 2012-01-28
            • 2019-01-05
            • 2020-03-14
            • 2011-12-19
            • 2017-12-10
            • 2018-06-29
            • 1970-01-01
            相关资源
            最近更新 更多