Jython не будет импортировать пользовательский класс; ImportError: нет модуля с именем ****** - PullRequest
9 голосов
/ 19 октября 2011

Я пару дней бился головой о стену, пытаясь понять это. Я начал играть с Jython для быстрого создания прототипов. Я столкнулся с проблемой, которая кажется невероятно простой, но я просто не могу ее преодолеть.

Я был в Ch 10 JythonBook и столкнулся с проблемой, когда попытался написать и использовать класс "Beach" (начиная с раздела, помеченного как "Листинг 10-1"). Я мог бы импортировать и использовать java.lang.Math просто отлично, но не мог заставить класс "Beach" работать на мою жизнь. Я написал класс Beach, превратил его в банку и изменил разрешения,

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. Этот пост дал мне идею попытаться "нацелить импорт", но, как вы можете видеть, это не сработало. Я просто не могу заставить это работать. После прочтения немного об ужасах беспорядка с CLASSPATH, я оставил это в покое.

Возможно, я должен отметить, что я не новичок в программировании - я был студентом CS и программировал (в основном научные вычисления) последние 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 всегда управлять им).

Ответы [ 2 ]

7 голосов
/ 19 октября 2011

jython не может импортировать * .java-файл, который вам нужно скомпилировать в * .class.

Makefile:

.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

Otherфайлы

test_beach.py:

#!/usr/bin/env jython
import Beach

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

Beach.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;
    }

}
1 голос
/ 19 октября 2011

Я думаю, что в этом примере может быть ошибка. Когда вы import X в Jython, это ищет Java пакет с именем X, а не класс с именем 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")

edit: Также вы можете убедиться, что полное имя файла .jar, а не только каталог, в котором он находится, указано в CLASSPATH. Это, безусловно, необходимо в Java, и я предполагаю, что правила Jython в этом отношении одинаковы.

...