This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
Let me preface this by saying that it is a general Java question, but that I have to introduce a lot of DB2 info to set the stage. I have installed DB2 client software on my RH7.1 Linux PC and am trying to access a DB2 server on another RH7.1 Linux PC. Everything is square insofar as the DB2 stuff is concerned. At the prompt, I can connect to the remote database using: db2 connect to database_node_name user my_name using my_password and query it using: db2 -tf query_file This works fine; the query results are sent to STDOUT. Now, suppose we want to do this from a Java program. A sane person would just use JDBC. However, I was lazy and didn't want to learn JDBC, so I decided I would just fork processes with Runtime.exec() to get the same results. Strangely, this didn't work: I could connect to the remote database, but querying it returns "SQL1024N A database connection does not exist. SQLSTATE=08003", which is the message you get when you try to query the database without connecting first. I echoed the DB2 environment variables within the Java program to make sure they were correct; they are. I made sure I wasn't using the Process waitFor() method on the connecting process; I don't. I guess that either (a) the connection is timing out for some reason, or (b) Java is deliberately terminating it before running the next command. Does anybody know about how Java manages child processes? Does this sound reasonable? Thanks for your time, Greg
I made sure I wasn't using the Process waitFor() method on the connecting process; I don't. I'm not nure how the db2 connect works, but it seems quite possible that you need to wait for the connect to complete before you can proceed with other actions that dependd on that connection. If you just do two successive calls to Runtime.getRuntime().exec(), it's like creating two new threads. The first exec may still be processing while the second begins. If the second one needs an open connection from the very beginning, it will fail, since the first exec() isn't done. So try putting in a waitFor() after the first exec() - could be exactly what you need. Beware that exec() is kind of a pain to work with, especially where debugging is concerned. You need to be chacking getErrorStream() and getInputStream() (which really represents the output of the process, which becomes input to your Java program) to see if they contain any important messages for you. And to do this right, you probably need to process these streams in two separate threads, since the error stream might fill a buffer which prevents you from reading the other stream until error is read, or vice versa. Unless you're really sure there won't be any error, or any other input/output. Fat chance though if somethign goes wrong. Actually the simplest way to deal with this may be to make sure that your exec commands include redirects to files which you can browse at your leisure, e.g.: db2 -tf query_file 1>outfile 2>&1 or whatever syntax is more appropriate for your OS (and I'm assuming db2 commands are compatable with this redirection.) Of course, this means you really need to check outfile to see if it contains any important messages for you. In the long run, it will really behoove you to learn JDBC for this sort of thing. It's not difficult really; just looks strange at first. [ October 17, 2003: Message edited by: Jim Yingst ]
"I'm not back." - Bill Harding, Twister
Joined: Oct 07, 2003
Thanks, Sherriff. I gave up on the process-forking approach and figured out how to do the same job with JDBC. I'll probably poke around with the process-forking version of my code in the future, bearing in mind your recommendations. If I figure out what happened, and if it's anything interesting, I'll repost. Thanks, Greg
If you run an interactive program with exec() you have to connect to its stdin, stdout, errout to talk to it. I have something that mostly works if you're interested in following up on it. This is quite a bit more complex as it's distributed between a client & server over raw sockets. http://www.surfscranton.com/architecture/CmdServer.htm The basic idea is that it spawns separate threads to listen to the stdout and errout of the other process. This is because we don't know when, if ever, one or the other will write something of interest and I don't want to block forever waiting for them. I worked with a language called Easel on OS/2 and their whole database support was done this way. Send SQL strings to an external module, get result sets back as strings. Pretty cool that they were able to add SQL support to their product with zero language changes, just a new external module, probably one that came from IBM. Glad you got your JDBC working. A better solution fer sure. [ October 17, 2003: Message edited by: Stan James ]
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi