Discussion:
[Jython-users] Trouble with getting to EJB
Mike Hostetler
2002-02-28 13:54:11 UTC
Permalink
Hello,

I'm trying to use Jython to get to some EJB objects via JBoss 2.2 and
having very little luck. I can get to the database from another
application (that also uses the EJB, but is Java) so I know that it is
being deployed properly.

According to the JBoss startup, my database is being deploy thus:
[jdbc/WP30] Starting
[jdbc/WP30] XA Connection pool jdbc/WP30 bound to java:/jdbc/WP30
[jdbc/WP30] Started
from com.ziclix.python.sql import zxJDBC
jndi = "jdbc/WP30"
db = zxJDBC.lookup(jndi)
Traceback (innermost last):
File "<console>", line 1, in ?
DatabaseError: jdbc not bound

And there is a jndi.properties file in that directory, and Jython is
reading it. I know this because if I muck with it, it give me an error:

original jndi.properties:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

messed-up jndi.properties:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=fred://localhost
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
from com.ziclix.python.sql import zxJDBC
jndi = "jdbc/WP30"
db = zxJDBC.lookup(jndi)
Traceback (innermost last):
File "<console>", line 1, in ?
DatabaseError: fred

Now, I am totally lost. What could the problem be? Is there any
suggestions?

-- mikeh

--
brian zimmer
2002-03-01 02:56:04 UTC
Permalink
Mike,

The behaviour you are seeing from JBoss and zxJDBC is expected and
correct. I'll try to explain why and hopefully provide a couple
solutions/suggestions to help you out.

First, zxJDBC doesn't really have anything to with EJBs. While both
EJBs and zxJDBC can access JNDI they have no relation to each other.
zxJDBC understands how to connect to database from a JNDI lookup that
results in a DataSource or other JDBC object
(ConnectionPooledDataSource, Driver, ...) but can't do anything with
EJBs. It is often the case that JNDI is used without ever deploying an
EJB, such as when using JMS.

The next thing is to look at what is stored in JNDI and who can access
it. JBoss binds the DataSource in the 'java:' namespace, which as this
thread
(http://www.mail-archive.com/jboss-***@list.working-dogs.com/msg12942.h
tml) explains, is available only inside the vm.

So the reason your access to 'java:/jdbc/WP30' fails is because you are
running in another VM (I'm making an assumption here given by the
command prompts in your email). The reason your EJB can access this
JNDI bound object is because it's part of the container and therefore
can see it. The JBoss JNDI server is simply denying zxJDBC access to
anything bound under java: as this is intended behaviour.

To prove this try the following code snippet:

import java
from javax.naming import *

env = java.util.Hashtable()

env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContex
tFactory")
env.put(Context.PROVIDER_URL, "localhost")
env.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces")

ctx = InitialContext(env)
enum = ctx.list("/")
while enum.hasMoreElements():
print " -- " + enum.nextElement().getName()

When I run this against my JBoss 2.4.4 instance I see:

-- XAConnectionFactory
-- jmx:mountain:rmi
-- TopicConnectionFactory
-- UserTransactionSessionFactory
-- RMIXAConnectionFactory
-- QueueConnectionFactory
-- topic
-- queue
-- ConnectionFactory
-- RMIConnectionFactory
-- UserTransaction
-- jmx
-- servercollector
-- UILXAConnectionFactory
-- UILConnectionFactory

Notice the 'java:' namespace is not visible. You'll be unable to access
the connection externally even though your EJB (running internally) sees
it just fine.

If you're looking to just store a DataSource in JNDI you could try
something like this (it's how I test zxJDBC and on occasion I run zxJDBC
this way):

import java, org
from javax.naming import *
from com.ziclix.python.sql import zxJDBC as zx

env = java.util.Hashtable()

env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContex
tFactory")
env.put(Context.PROVIDER_URL, "localhost")
env.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces")

ctx = InitialContext(env)

ds = org.gjt.mm.mysql.MysqlDataSource()
ds.setServerName("192.168.1.102")
ds.setDatabaseName("ziclix")
ds.setUser("jython")
ds.setPassword("jython")
ds.setPort(3306)
conn = ds.getConnection()
conn.close()
print
print "opened connection from ds: %s" % (str(ds))

try:
ctx.bind("mysql", ds)
except NameAlreadyBoundException:
pass

db = zx.lookup("mysql",
INITIAL_CONTEXT_FACTORY="org.jnp.interfaces.NamingContextFactory",
PROVIDER_URL="localhost",
URL_PKG_PREFIXES="org.jboss.naming:org.jnp.interfaces"
)

print
print db

db.close()

ctx.unbind("mysql")

ctx.close()

This script creates a DataSource (could be a ConnectionPooledDataSource
as well (also note that each vendor's DataSource is slightly different
in terms of set/get API)) and binds the instance. zxJDBC's lookup() is
then able to find the DataSource and create a connection. If you re-run
the first code snippet without unbinding mysql you should see it in the
list.

Additionally, if you embed Jython in the EJB container and use the
embedded interpreter to accces zxJDBC and JNDI resources your original
attempt should work just fine. This approach is also possible for using
zxJDBC in conjunction with PyServlet.

I hope this helps. If you have any more questions please let me know.

thanks,

brian
-----Original Message-----
Of Mike Hostetler
Sent: Thursday, February 28, 2002 9:54 AM
Subject: [Jython-users] Trouble with getting to EJB
Importance: High
Hello,
I'm trying to use Jython to get to some EJB objects via JBoss
2.2 and having very little luck. I can get to the database
from another application (that also uses the EJB, but is
Java) so I know that it is being deployed properly.
[jdbc/WP30] Starting
[jdbc/WP30] XA Connection pool jdbc/WP30
bound to java:/jdbc/WP30
[jdbc/WP30] Started
from com.ziclix.python.sql import zxJDBC
jndi = "jdbc/WP30"
db = zxJDBC.lookup(jndi)
File "<console>", line 1, in ?
DatabaseError: jdbc not bound
And there is a jndi.properties file in that directory, and
Jython is reading it. I know this because if I muck with it,
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=fred://localhost
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
from com.ziclix.python.sql import zxJDBC
jndi = "jdbc/WP30"
db = zxJDBC.lookup(jndi)
File "<console>", line 1, in ?
DatabaseError: fred
Now, I am totally lost. What could the problem be? Is there
any suggestions?
-- mikeh
--
_______________________________________________
Jython-users mailing list
https://lists.sourceforge.net/lists/listinfo/jython-users
Stephen Naicken
2002-03-01 09:12:02 UTC
Permalink
I'm not sure as to how to go about threading a jython program. I am
trying to use from java.lang import Thread, extending the Thread class
and overriding thr run method. However, when I do this in jython, I get
an error telling me the __call__ attribute has not been set.

If anyone can provide a small example of how to create a threaded app in
jython I would be very grateful.

Thanks

Stephen
Kevin Butler
2002-03-01 13:47:53 UTC
Permalink
Post by Stephen Naicken
I'm not sure as to how to go about threading a jython program. I am
trying to use from java.lang import Thread, extending the Thread class
and overriding thr run method. However, when I do this in jython, I get
an error telling me the __call__ attribute has not been set.
As a design principle, it is often better to implement Runnable rather than extending Thread (you have Runnable jobs to do, rather than anything that would change the semantics of a Thread).
Post by Stephen Naicken
If anyone can provide a small example of how to create a threaded app in
jython I would be very grateful.
Four small examples (Jython tends to violate Python's "one obvious way to do it" principle), ordered as Python over Java, then preferred over less preferred:

def greet( name ):
print "greetings", name

count = 0

# newer Python way
import threading
count += 1
t = threading.Thread(
target=greet,
name="MyThread %d" % count,
args=( "threading.Thread", )
)
t.start()

# older Python way
# has no thread naming feature
import thread
thread.start_new_thread(
greet,
( "thread.start_new_thread", )
)

# preferred Java way
from java.lang import Thread, Runnable
class GreetJob( Runnable ):
def __init__( self, name ):
self.name = name
def run( self ):
greet( self.name )
count += 1
t = Thread( GreetJob( "Runnable" ), "MyThread %d" % count )
t.start()

# other Java way
from java.lang import Thread
class GreetThread( Thread ):
def __init__( self, name, count ):
Thread.__init__( self, "MyThread %d" % count )
self._name = name # Thread has a 'name' attribute
def run( self ):
greet( self._name )
count += 1
t = GreetThread( "Thread subclass", count )
t.start()

*whew*

BTW, the thread naming stuff is good practice but not required.

kb

Loading...