Return-Path: Delivered-To: apmail-db-derby-dev-archive@www.apache.org Received: (qmail 1608 invoked from network); 29 Apr 2005 04:39:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 29 Apr 2005 04:39:18 -0000 Received: (qmail 47350 invoked by uid 500); 29 Apr 2005 04:40:31 -0000 Delivered-To: apmail-db-derby-dev-archive@db.apache.org Received: (qmail 47326 invoked by uid 500); 29 Apr 2005 04:40:30 -0000 Mailing-List: contact derby-dev-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Reply-To: "Derby Development" Delivered-To: mailing list derby-dev@db.apache.org Received: (qmail 47311 invoked by uid 99); 29 Apr 2005 04:40:30 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: local policy) Received: from brmea-mail-3.Sun.COM (HELO brmea-mail-3.sun.com) (192.18.98.34) by apache.org (qpsmtpd/0.28) with ESMTP; Thu, 28 Apr 2005 21:40:30 -0700 Received: from phys-mpk-1 ([129.146.11.81]) by brmea-mail-3.sun.com (8.12.10/8.12.9) with ESMTP id j3T4dFjO002356 for ; Thu, 28 Apr 2005 22:39:15 -0600 (MDT) Received: from conversion-daemon.mpk-mail1.sfbay.sun.com by mpk-mail1.sfbay.sun.com (iPlanet Messaging Server 5.2 HotFix 1.24 (built Dec 19 2003)) id <0IFO00101Y3GUC@mpk-mail1.sfbay.sun.com> (original mail from David.Vancouvering@Sun.COM) for derby-dev@db.apache.org; Thu, 28 Apr 2005 21:39:15 -0700 (PDT) Received: from sun.com (vpn-129-150-27-27.SFBay.Sun.COM [129.150.27.27]) by mpk-mail1.sfbay.sun.com (iPlanet Messaging Server 5.2 HotFix 1.24 (built Dec 19 2003)) with ESMTP id <0IFO002DLY9EMH@mpk-mail1.sfbay.sun.com> for derby-dev@db.apache.org; Thu, 28 Apr 2005 21:39:15 -0700 (PDT) Date: Thu, 28 Apr 2005 21:39:18 -0700 From: David Van Couvering Subject: Re: [jira] Commented: (DERBY-214) Remove System.exit() calls from the DB2jServerImpl.java In-reply-to: <42718B33.5050600@apache.org> To: Derby Development Message-id: <4271BA76.5020506@sun.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii; format=flowed Content-transfer-encoding: 7BIT X-Accept-Language: en-us, en User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113 References: <124244851.1114624173884.JavaMail.jira@ajax.apache.org> <42707488.4060107@sbcglobal.net> <4270E3CF.5050204@sun.com> <4270E927.9020107@sbcglobal.net> <4270F0A1.2070608@apache.org> <4270FA03.1010802@sun.com> <4270FE2C.1070309@apache.org> <427160E8.4020208@sun.com> <42718B33.5050600@apache.org> X-Virus-Checked: Checked X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Whoa, I was just trying to fix the System.exit() problem :) I agree with you that there is a bit too many responsibilities for one object, and that parsing of arguments should be separated from execution of logic. However, I don't think that I should attack the separation of establishing a remote connection and driving the wire protocol as part of this bug. I think we should log a separate bug for that issue, I think it's a great thought for a more flexible design. For this bug, I could use it as an opportunity to take all command-line parsing *out* of DB2jServerImpl, that makes a lot of sense. DB2jServerImpl should only be called by NetworkServerControl anyway, and should present a more classic object abstraction and not have anything to do with argument parsing. BTW, it was my mistake to use DB2jServerImpl in the example below, it should have been NetworkServerControl. In this particular example, NetworkServerControl also has methods for each command, and the Derby docs explicitly document that this is how you work with the network server in embedded mode. So an embedding app shouldn't ever have to or need to call main() or any routine that just takes an array of args, and doesn't need the model I propose below. However, other Derby tools, however, like ij and dblook, don't have this command-based interface. They do need some kind of "execute" method that matches the way it is invoked from the command-line. As discussed, if the behavior of exit status when returning from main() is well defined by the Java spec, then we can just use main with no call to System.exit(). Otherwise, we should provide a separate execute() method for embedding applications. If we decide upon a separate execute() method, my question still is, what is the easier way to invoke this execute method, using an arg array, or by instantiating an instance and setting bean properties? I think this is an indepedent question from any separation of concern issues within the tool itself. I personally think an arg array is easier, but perhaps I'm missing an important architectural issue. Thanks, David Jeremy Boynes wrote: > David Van Couvering wrote: > >> >> Also, the JavaBean approach assumes you create an instance of the >> beast, and I have noticed that many command-line classes have most of >> their code in static methods and use static variables (not that they >> should, but that's what they do). Also, it might actually be easier >> to set up an array of Strings rather than call a bunch of set methods, >> especially if you can create the array in-place, e.g. >> >> DB2jServerImpl.main(new String[] { "ping", "-p", "2000"} ); >> >> rather than >> >> DB2jServerImpl impl = new DB2jServerImpl() >> impl.setCommand("ping"); >> impl.setPort("2000"); >> impl.execute(); >> > > My concern here is coming from confusion in the responsibilities between > NetworkServerControl and DB2jServerImpl. For example, there are two ways > to set the maxthreads: > > 1) new NetworkServerControl().setMaxThreads(100); > > 2) NetworkServerControl.main( > new String[]{"maxthreads", "100"}); > > Ultimately these both end up calling DB2jServerImpl.netSetMaxThreads() > > DB2jServerImpl is doing three completely different things here: it is > setting up the remote connection, it is driving the wire protocol to the > remote server (see the impl of netSetMaxThreads), and it is responsible > for parsing and verifying the command line arguments passed in. I think > these concerns can be separated resulting in a simpler implementation > that is easier to embed and use from other tools such as Eclipse. > > I would first suggest factoring out the connection setup and teardown - > perhaps a NetworkServerConnection class with hostname and port > properties (perhaps username, password or other credential) and an > execute method that takes a command object e.g. > > public class NetworkServerConnection { > public void connect() throws TransportException; > public void close() throws TransportException; > > public Object execute(NetworkServerCommand cmd) > throws TransportException, CommandException; > } > > Each command (ping, maxthreads, etc) is represented by an object that > implements NetworkServerCommand and which can be set up with the > appropriate properties e.g. > > public class SetMaxThreadsCommand implements NetworkServerCommand { > public void setMaxThreads(int threads); > } > > Each command would know how to write itself to the wire; heck if you > were prepared to break backward compatibility you could simplify things > further by just using serialization. > > For command line support, NetworkServerControl.main parses the > arguments, creates a NetworkServerConnection and the appropriate command > and then submits it to the remote server. Basically it just contains > implementation for handling the command line syntax. > > For embedded use, a tool can create and maintain a connection for as > long as necessary, getting the connection parameters any way it wants > (e.g. a host/user/password dialog). The commands can be created and > submitted in response to UI events just like any others. Both the > connection and the commands can use beaninfo to define their properties. > > Although there are more moving parts in this, I think overall it is a > more maintainable solution as the concerns of connection, commands and > UI have been clearly separated. > > -- > Jeremy