I've been banging my head against the wall for a couple days now trying to figure this out. I've been starting to play around with Jython for fast prototyping. I've hit what appears to be an incredibly basic problem but I just can't seem to get past it.
I was in Ch 10 of the JythonBook and hit the problem when I tried to write and use the "Beach" class (starting in the section labeled "Listing 10-1"). I could import and use java.lang.Math just fine, but couldn't get the "Beach" class to work for the life of me. I wrote the Beach class, turned it into a jar and changed permissions,
jar cf Beach.jar Beach.java chmod 777 Beach.jar
and made sure that both Beach.jar and Beach.java were in the current working directory, as well as /Library/Java/Extensions/ (I'm on a Mac) -- no dice.
I just can't think what might be the problem. I'm hoping someone here will see something I missed.
For your convenience, everything that I think may be useful, from a "live" Jython session:
$ 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
>>>
Should I also post my ~/.bash_profile ?
I've poked around the internet and StackOverflow quite a bit. This post gave me the idea to try to "target import," but as you can see this didn't work. I just can't seem to get this to work. After reading a bit about terrors of messing eith CLASSPATH, I've left that alone.
I should perhaps note that I'm not new to programming -- I was a CS undergrad and have coded (mostly scientific computing) for the last 6 or so years. I am fairly new to Java; I just started programming in Java earlier this year. It seems pretty straightforward, and NetBeans has taken care of everything I don't know.
My fear is that I'm misunderstanding something about the classpath for Java. I've also moved some jars around to the the locations that I think should be "searched" by Java -- /System/Library/Java/Extensions/, /Library/Java/Extensions/, and /usr/lib/java/ (I know...), but nothing seems to change the above errors.
(On a possibly related note, after playing around with this, Netbeans appears to not be able to populate a new project -- I'm doing that manually now. Not sure if that is helpful info.)
Any thoughts? I'm incredibly grateful for any help!
EDIT: After trying out the comment below, I got the following:
$ 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;
}
}
>>>
I know that Java packages are based on file structure. If there is something entirely obviously wrong here, please let me know. In the meanwhile, time to go read up on how Java packages work (instead of letting Netbeans always manage it).
jython can't import *.java file you need to compile it to *.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
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With