【问题标题】:Jython won't import user-defined class; ImportError: No module named ******Jython 不会导入用户定义的类; ImportError:没有名为******的模块
【发布时间】:2011-10-19 16:49:47
【问题描述】:

几天来,我一直在努力解决这个问题。我一直在尝试使用 Jython 进行快速原型设计。我遇到了一个看似非常基本的问题,但我似乎无法克服它。

我在Ch 10 of the JythonBook 中尝试编写和使用“Beach”类时遇到了问题(从标有“清单 10-1”的部分开始)。我可以很好地导入和使用 java.lang.Math,但无法让“Beach”类为我的生活工作。我写了 Beach 类,把它变成了一个 jar 并更改了权限,

jar cf Beach.jar Beach.java chmod 777 Beach.jar

并确保 Beach.jar 和 Beach.java 都在当前工作目录中,以及 /Library/Java/Extensions/(我在 Mac 上)——没有骰子。

我只是想不出可能是什么问题。我希望这里有人会看到我错过的东西。

为了您的方便,我认为可能有用的所有内容都来自“实时”Jython 会话:

$ jython
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06) 
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_24
Type "help", "copyright", "credits" or "license" for more information.
>>> ## First try importing "Math" from Java:
>>> from java.lang import Math
>>> Math.max(4, 7)
7L
>>> ## Try System from Java:                
>>> javasystem.out.println("Hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'javasystem' is not defined
>>> from java.lang import System as javasystem
>>> javasystem.out.println("Hello")
Hello
>>> ##
>>> ## Now try to import my own class, written as in the JythonBook 
>>> ## This is where the trouble starts:
>>> ## First check that I am in the correct place, look at the system path:
>>> import os
>>> os.system("pwd")
/Users/me/EclipseProjects/JythonTutorial/JavaClasses
0
>>> os.system("ls -la")
total 16
drwxr-xr-x  4 me  staff  136 Oct 19 11:25 .
drwxr-xr-x  7 me  staff  238 Oct 19 02:16 ..
-rwxrwxrwx  1 me  staff  567 Oct 19 11:25 Beach.jar
-rwxrwxrwx  1 me  staff  256 Oct 19 11:14 Beach.java
0
>>> ## Let's look at the guts of Beach.java quickly:
>>> os.system("cat Beach.java")
public class Beach {
    private String name;

    public Beach(String name, String city){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

0
>>> ## Let's also look at the system path:
>>> import sys
>>> sys.path
['', '/Users/me/jython2.5.2/Lib', '__classpath__', '__pyclasspath__/', '/Users/me/jython2.5.2/Lib/site-packages']
>>> ## I presume that the '' should indicate that I can use this.                               
>>> ## To be careful, I also cp Beach.jar to /Library/Java/Extensions/ 
>>> os.system("ls -la /Library/Java/Extensions/Beach.jar")
-rwxr-xr-x  1 me  admin  567 Oct 19 11:27 /Library/Java/Extensions/Beach.jar
0
>>> ##
>>> ## Now actually attempt to load Beach:
>>> import Beach
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named Beach
>>> from Beach import Beach
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named Beach
>>> 

我也应该发布我的 ~/.bash_profile 吗?

我已经在互联网和 StackOverflow 上闲逛了很多。 This post 给了我尝试“目标导入”的想法,但正如您所见,这不起作用。我似乎无法让它发挥作用。在阅读了一些关于弄乱 CLASSPATH 的恐惧之后,我就不管它了。

我或许应该注意,我对编程并不陌生——我是一名计算机科学专业的本科生,在过去 6 年左右的时间里一直在编写代码(主要是科学计算)。我对Java相当陌生;我今年早些时候才开始用 Java 编程。这看起来很简单,NetBeans 已经处理了我不知道的所有事情。

我担心我对 Java 的类路径有误解。我还将一些 jar 移动到我认为应该由 Java “搜索”的位置 - /System/Library/Java/Extensions/、/Library/Java/Extensions/ 和 /usr/lib/java/ (我知道......),但似乎没有任何改变上述错误。

(在一个可能相关的注释中,在玩过这个之后,Netbeans 似乎无法填充一个新项目——我现在正在手动执行此操作。不确定这是否有用的信息。)

有什么想法吗?我非常感谢任何帮助!

编辑:在尝试了下面的评论后,我得到了以下信息:

$ jython
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06) 
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_24
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys                                                                             
>>> sys.path.append("/Users/me/EclipseProjects/JythonTutorial/JavaClasses/Beach.jar")
>>> from com.stackoverflow.beach import Beach                                              
*sys-package-mgr*: processing modified jar, '/Users/me/EclipseProjects/JythonTutorial/JavaClasses/Beach.jar'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named stackoverflow
>>> ## Look in Beach.java
>>> import os
>>> os.system("cat Beach.java")
// Beach.java
package com.stackoverflow.beach;
public class Beach {
    private String name;
    public Beach(String name, String city){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
>>>

我知道 Java 包是基于文件结构的。如果这里有什么完全明显的错误,请告诉我。同时,是时候阅读一下 Java 包的工作原理了(而不是让 Netbeans 始终管理它)。

【问题讨论】:

  • 非常感谢您发布这个问题......老实说,我认为我是唯一面临这个问题的人。如果您的问题更容易找到,这样可以节省我在聊天中询问的时间,所以

标签: jython


【解决方案1】:

jython 无法导入 *.java 文件,您需要将其编译为 *.class。

生成文件:

.PHONY: test_beach

test_beach: test_beach.py beach.jar
    jython -J-classpath beach.jar $<

beach.jar: Beach.class
    jar -cf $@ $<

%.class: %.java
    javac $<

示例

$ make -k 
javac Beach.java
jar -cf beach.jar Beach.class
jython test_beach.py
*sys-package-mgr*: processing modified jar, '/path/to/beach.jar'
Cocoa Beach

其他文件

test_beach.py​​:

#!/usr/bin/env jython
import Beach

beach = Beach("Cocoa Beach","Cocoa Beach")
print beach.getName()

海滩.java:

//NOTE: if you declare `package a.b;` here then you should put it in a/b directory
public class Beach {

    private String name;
    private String city;


    public Beach(String name, String city){
        this.name = name;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

【讨论】:

  • 做到了。极好的。我知道我错过了一些小步骤。是时候真正学习 Java 编译过程了,而不是总是依赖我的 IDE 来做。非常感谢,这正是我需要的。
  • 另外,+1 用于发布您自己尝试过的代码(看起来)。谢谢!
  • @Nathan: 注意:你可能需要-J-classpath beach.jar 否则它使用Beach.class 而不是jar。
【解决方案2】:

我认为该示例中可能存在错误。当您在 Jython 中 import X 时,它会查找名为 X 的 Java ,而不是查找名为 X

试试:

// Beach.java
package com.stackoverflow.beach;

public class Beach {
    private String name;
    ...

在 Jython 中:

from com.stackoverflow.beach import Beach
bondi = Beach("Bondi Beach", "Sydney")

编辑:另外,您可能需要确保.jar 文件的全名——而不仅仅是它所在的目录——列在CLASSPATH 上。这在 Java 中当然是必要的,我假设 Jython 的规则在这方面是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2010-12-10
    • 2018-02-08
    • 1970-01-01
    • 2021-01-01
    • 2020-11-28
    • 2014-03-03
    相关资源
    最近更新 更多