I've made a couple of enhancements to jk_nt_service. Attached is a patch for jk_nt_service.c and the documentation. This change was made against HEAD of jakarta-tomcat. Can someone check it over for possible check in. Dave [EMAIL PROTECTED] _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp
Index: jakarta-tomcat/src/doc/NT-Service-howto.html =================================================================== RCS file: /home/cvspublic/jakarta-tomcat/src/doc/NT-Service-howto.html,v retrieving revision 1.5 diff -r1.5 NT-Service-howto.html 0a1 ><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3,4c4,6 < <!-- $Id: NT-Service-howto.html,v 1.5 2001/07/17 03:53:41 costin Exp $ --> < <!-- Copyright 1999-2001, Apache Software Foundation --> --- > <!-- $Id: NT-Service-howto.html,v 1.5 2001/07/17 03:53:41 costin Exp >$ --> > <!-- Copyright 1999-2001, Apache Software Foundation --> 5a8 > 7a11 > 9,11c13 < < <body> < --- > <body> 13,22c15,22 < < <p>By Gal Shachor < <tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>> < </tt></p> < < < <p>The Jakarta NT service is an executable that wraps the < Tomcat servlet container and executes it in the background as an NT service. To < install it you will need to:</p> < --- ><p>By Gal Shachor <tt><<a >href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> > ></tt><br> > Modified by Dave Oxley <<a >href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> > ><br> ></p> ><p>The Jakarta NT service is an executable that wraps the Tomcat servlet >container >and executes it in the background as an NT service. To install it you will >need to:</p> 24,79c24,102 < <li>Get a < hold on the NT executable (jk_nt_service.exe)</li> < <ul> < <li>Download < the executable from the win32/i386 directory found where you downloaded the < <a href="http://jakarta.apache.org/site/binindex.html"> Tomcat binary < distribution.</a> For those using Netscape as your browser, try downloading < a zip version of the file, if available. There can be problems using Netscape < to download DLL files.</li> < </ul> < <li>Customize < a properties file that provides the service with Tomcat information < (wrapper.properties).</li> < <ul> < <li>Locate the wrapper.properties template file in your Tomcat conf/jk directory. < <li>Update < the wrapper.tomcat_home property to point at your tomcat home.</li> < <li>Update < the wrapper.java_home property to point at your Java home.</li> < </ul> < <li>Install < jk_nt_service by running it with the -i flag.</li> < <ul> < <li>Execute < jk_nt_service -I <name of service> <path to updated wrapper < properties></li> < <li><name < of service> should be a single word (without and spaces) such as < Jakarta</li> < <li><path < to updated wrapper properties> should point to your wrapper.properties < file (and the service will check it's existence.)</li> < <li>For < example, a valid command line can be jk_nt_service -I Jakarta wrapper.properties</li> < </ul> < <li>Start < tomcat as a service.</li> < <ul> < <li>From < the command line, execute net start <name of service> (e.g. net < start Jakarta)</li> < <li>From < the NT services applet, highlight your service and press start.</li> < </ul> < <b>Note:</b> If the log file location in your wrapper.properties file points to < the <tt>logs</tt> directory, and the <tt>logs</tt> directory doesn't yet exist, < manually create it before starting the service. < <li>Stop < Tomcat as a service.</li> < <ul> < <li>From < the command line, execute net stop <name of service> (e.g. net < stop Jakarta)</li> < <li>From < the NT services applet, highlight your service and press stop.</li> < </ul> --- > <li>Get a hold on the NT executable (jk_nt_service.exe)</li> > <ul> > <li>Download the executable from the win32/i386 directory found > where you downloaded the <a >href="http://jakarta.apache.org/site/binindex.html"> > Tomcat binary distribution.</a> > For those using Netscape as your browser, try downloading a zip >version of the file, if available. There can be problems using Netscape > to download DLL files.</li> > </ul> > <li>Customize a properties file that provides the service with >Tomcat information (wrapper.properties).</li> > <ul> > <li>Locate the wrapper.properties template file in your Tomcat conf/jk > directory. </li> > <li>Update the wrapper.tomcat_home property to point at your >tomcat home.</li> > <li>Update the wrapper.java_home property to point at your Java >home.</li> > </ul> > <li>Install jk_nt_service by running it with the -i flag.</li> > <ul> > <li>Execute jk_nt_service -I <name of service> ><optional params> <path to updated wrapper >properties></li> > <li><name of service> should be a single word (without and > spaces) such as Jakarta</li> > <li><optional params> are any of the following:</li> > <ul> > <li>-U <user name> - to set the user the service runs as. Make > sure the user has 'Logon as a service right'. The <user name> must >be in the format DomainName\UserName (e.g. Dev\Administrator for >Administrator in the Dev domain or .\Administrator for the local >Administrator)</li> > <li>-P <user password> - Valid password for the user.</li> > <li>-A - Sets the service to startup automatically.</li> > <li>-D <service dependancy> - This sets the service that must >be started prior to this one. -D <service dependancy> can be >specified multiple times. <service dependancy> must be the 'Service >Name' not the 'Display Name'.<br> > </li> > </ul> > <li><path to updated wrapper properties> should point to >your >wrapper.properties file (and the service will check it's >existence.)</li> > <li>For example, valid command lines can be:</li> > <ul> > <li>jk_nt_service -I Jakarta wrapper.properties</li> > <li>jk_nt_service -I Jakarta -U .\Administrator -P password -A -D >MSSQLSERVER wrapper.properties</li> > </ul> > </ul> > <li>Start tomcat as a service.</li> > <ul> > <li>From the command line, execute jk_nt_service -S <name of >service> <optional param> where <optional param> is:</li> > <ul> > <li>-M <machine name> - Remote machine to start the service >on. (e.g. jk_nt_service -S Jakarta -M DevBox)<br> > </li> > </ul> > <li>From the command line, execute net start <name of >service> (e.g. net start Jakarta)</li> > <li>From the NT services applet, highlight your service and >press start.</li> > </ul> > <b>Note:</b> If the log file location in your wrapper.properties file >points to the <tt>logs</tt> directory, and the <tt>logs</tt> directory >doesn't yet exist, manually create it before starting the service. > <li>Stop Tomcat as a service.</li> > <ul> > <li>From the command line, execute jk_nt_service -T <name of >service> <optional param> where <optional param> is:</li> > <ul> > <li>-M <machine name> - Remote machine to stop the service on. > (e.g. jk_nt_service -T Jakarta -M DevBox)<br> > </li> > </ul> > <li>From the command line, execute net stop <name of >service> (e.g. net stop Jakarta)</li> > <li>From the NT services applet, highlight your service and >press stop.</li> > </ul> 81,102c104,122 < < <p><b>Special note</b>: The Tomcat service is using AJPV12 to < perform clean shutdown and you should make sure that an AJPV12 connector is < defined in your server.xml. In the absence of a configured AJPV12 port the < Tomcat service will kill Tomcat abruptly (that is murder it) without giving it < a chance to clean up. </p> < < <p><b>Special note2</b>: Acording to < <a href=http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337"> < http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337</a>, you may have problems with < long filenames. You should use the 8.3 format. Thanks to Anthony Dodd for finding this < workaround.</p> < < <p><strong>Notice for JDK 1.3 users</strong>: There is a < <a href="http://developer.java.sun.com/developer/bugParade/bugs/4323062.html">known problem</a> < in JDK 1.3 that affects Java applications being run as Windows NT services. The bug causes the < service to terminate when the currently logged in user logs out. The simplest way to work < around this problem is to use JDK 1.2. If your application requires JDK 1.3 features then you < may want to look into <a href="http://www.kcmultimedia.com/javaserv/">javaserv</a> or < <a href="http://www.alexandriasc.com/software/JavaService/">JavaService</a>. Users have reported < success with both of these packages but there may be others that work as well. < </p> --- ><p><b>Special note</b>: The Tomcat service is using AJPV12 to perform clean > shutdown and you should make sure that an AJPV12 connector is defined in >your server.xml. In the absence of a configured AJPV12 port the Tomcat >service will kill Tomcat abruptly (that is murder it) without giving it a >chance to clean up. </p> ><p><b>Special note2</b>: Acording to <a >href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337%22"> > http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337</a> > , you may have problems with long filenames. You should use the 8.3 >format. Thanks to Anthony Dodd for finding this workaround.</p> ><p><strong>Notice for JDK 1.3 users</strong>: There is a <a >href="http://developer.java.sun.com/developer/bugParade/bugs/4323062.html"> > known problem</a> > in JDK 1.3 that affects Java applications being run as Windows NT >services. The bug causes the service to terminate when the currently >logged in user logs out. The simplest way to work around this problem is >to use JDK 1.2. If your application requires JDK 1.3 features then you >may want to look into <a >href="http://www.kcmultimedia.com/javaserv/">javaserv</a> > or <a >href="http://www.alexandriasc.com/software/JavaService/">JavaService</a> > . Users have reported success with both of these packages but there may > be others that work as well. </p> 104d123 < 106d124 < 108,137c126,150 < <li>Modify < the Tomcat NT service properties. By default the service will run in manual < mode and under the local system user account. To modify this, open the NT < services applet, highlight your service and press startup. A popup window < is opened and you will be able to customize the service to your < satisfaction.</li> < <li>Modify < the classpath. The classpath is determined by the wrapper.class_path < properties, to modify it just add/remove/modify wrapper.class_path lines. < The complete classpath is calculated by concatenating all the < wrapper.class_path lines and putting ";" between them.</li> < <li>Execute < several Tomcat instances. Say that you want one Tomcat to run for < "production" and one for development, you can do that. All you < will need to do is to install the Tomcat service twice and under two < different names (and with different wrapper.properties file and server.xml < files). </li> < <ul> < <li>Make < sure that the AJPV12 and HTTP connectors are modified in each server.xml < file to prevent a clash.</li> < <li>Make < sure to update the wrapper.shutdown_port property in wrapper.properties < to point to the correct AJPV12 shutdown ports (default is 8007). </li> < </ul> < <li>Modify < the command line used to start Tomcat. The Tomcat service is taking all < it's command line configuration from wrapper.properties! To customize the < command line, edit the property wrapper.cmd_line and make sure that it < makes a legal Java command line.</li> --- > <li>Modify the Tomcat NT service properties. By default the service > will run in manual mode and under the local system user account. To >modify this, open the NT services applet, highlight your service and >press startup. A popup window is opened and you will be able to >customize the service to your satisfaction.</li> > <li>Modify the classpath. The classpath is determined by the >wrapper.class_path > properties, to modify it just add/remove/modify wrapper.class_path >lines. The complete classpath is calculated by concatenating all the > wrapper.class_path lines and putting ";" between them.</li> > <li>Execute several Tomcat instances. Say that you want one Tomcat >to run for "production" and one for development, you can do that. All >you will need to do is to install the Tomcat service twice and under >two different names (and with different wrapper.properties file and >server.xml files). </li> > <ul> > <li>Make sure that the AJPV12 and HTTP connectors are modified >in >each server.xml file to prevent a clash.</li> > <li>Make sure to update the wrapper.shutdown_port property in >wrapper.properties > to point to the correct AJPV12 shutdown ports (default is 8007). > </li> > </ul> > <li>Modify the command line used to start Tomcat. The Tomcat >service is taking all it's command line configuration from >wrapper.properties! To customize the command line, edit the property >wrapper.cmd_line and make sure that it makes a legal Java command >line.</li> 139d151 < 141,145c153,155 < < <p>Please send feedback, bug report or any additional information to < <tt><<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>> < </tt> < </p> --- ><p>Please send feedback, bug report or any additional information to <tt> > <<a >href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> > > </tt></p> 147d156 < Index: jakarta-tomcat/src/native/mod_jk/nt_service/jk_nt_service.c =================================================================== RCS file: /home/cvspublic/jakarta-tomcat/src/native/mod_jk/nt_service/jk_nt_service.c,v retrieving revision 1.4 diff -r1.4 jk_nt_service.c 58a59 > * Dave Oxley <[EMAIL PROTECTED]> >* 66d66 < 86a87,94 >typedef enum ActionEnum >{ acNoAction = 0, > acInstall = 1, > acRemove = 2, > acStartTC = 3, > acStopTC = 4 >} ActionEnum; > 109c117,121 < char *prp_file); --- > char *user, char >*password, char *deps, > BOOL bAutomatic, char *rel_prp_file); 110a123,126 >static void start_service(char *name, > char *machine); >static void stop_service(char *name, > char *machine); 140,144c156,173 < printf("%s - Usage:\n", name); < printf("%s -i <service name> <configuration properties file>\n", name); < printf("\tto install the service\n"); < printf("%s -r <service name>\n", name); < printf("\tto remove the service\n"); --- > printf("%s - Usage:\n\n", name); > printf("To install the service:\n"); > printf("%s -i <service name> {optional params} <config properties >file>\n", name); > printf(" Optional parameters\n"); > printf(" -u <user name> - In the form DomainName\\UserName >(.\\UserName for local)\n"); > printf(" -p <user password>\n"); > printf(" -a - Set startup type to automatic\n"); > printf(" -d <sevice dependancy> - Can be entered multiple >times\n\n"); > printf("To remove the service:\n"); > printf("%s -r <service name>\n\n", name); > printf("To start the service:\n"); > printf("%s -s <service name> {optional params}\n", name); > printf(" Optional parameters\n"); > printf(" -m <machine>\n\n"); > printf("To stop the service:\n"); > printf("%s -t <service name> {optional params}\n", name); > printf(" Optional parameters\n"); > printf(" -m <machine>\n"); 151,152c180,192 < int err; < --- > int i; > int err; > int count; > int iAction = acNoAction; > char *pServiceName = NULL; > char *pUserName = NULL; > char *pPassword = NULL; > char *pMachine = NULL; > BOOL bAutomatic = FALSE; > char strDependancy[256] = ""; > > memset(strDependancy, 0, 255); > 173d212 < 175,179c214,248 < if((argc > 2) && ((*argv[1] == '-') || (*argv[1] == '/'))) { < char *cmd = argv[1]; < cmd++; < if(0 == stricmp("i", cmd) && (4 == argc)) { < install_service(argv[2], argv[3]); --- > if(argc > 2) { > count=0; > for (i=1;i<argc;i++) { > if ((*argv[i] == '-') || (*argv[i] == '/')) { > char *cmd = argv[i]; > cmd++; > if(0 == stricmp("i", cmd)) { > iAction = acInstall; > pServiceName = argv[i+1]; > } else if(0 == stricmp("r", cmd)) { > iAction = acRemove; > pServiceName = argv[i+1]; > } else if(0 == stricmp("s", cmd)) { > iAction = acStartTC; > pServiceName = argv[i+1]; > } else if(0 == stricmp("t", cmd)) { > iAction = acStopTC; > pServiceName = argv[i+1]; > } else if(0 == stricmp("u", cmd)) { > pUserName = argv[i+1]; > } else if(0 == stricmp("p", cmd)) { > pPassword = argv[i+1]; > } else if(0 == stricmp("m", cmd)) { > pMachine = argv[i+1]; > } else if(0 == stricmp("a", cmd)) { > bAutomatic = TRUE; > } else if(0 == stricmp("d", cmd)) { > memcpy(strDependancy+count, argv[i+1], >strlen(argv[i+1])); > count+= strlen(argv[i+1])+1; > } > } > } > switch (iAction) { > case acInstall: > install_service(pServiceName, pUserName, pPassword, >strDependancy, bAutomatic, argv[i-1]); 181,182c250,251 < } else if(0 == stricmp("r", cmd) && (3 == argc)) { < remove_service(argv[2]); --- > case acRemove: > remove_service(pServiceName); 184,186c253,257 < } else if(0 == stricmp("s", cmd) && (3 == argc)) { < HANDLE hTomcat; < start_tomcat(argv[2], &hTomcat); --- > case acStartTC: > start_service(pServiceName, pMachine); > return; > case acStopTC: > stop_service(pServiceName, pMachine); 306a378,381 > char *user, char *password, > char *deps, BOOL bAutomatic, 314a390,392 > if (0 == stricmp("", deps)) > deps = NULL; > 336,337c414,415 < schSCManager = OpenSCManager(NULL, // machine (NULL == local) < NULL, // database (NULL == default) --- > schSCManager = OpenSCManager(NULL, // machine (NULL == local) > NULL, // database (NULL == default) 345c423 < SERVICE_DEMAND_START, // start type --- > bAutomatic ? SERVICE_AUTO_START : >SERVICE_DEMAND_START, // start type 350,352c428,430 < NULL, // dependencies < NULL, // LocalSystem account < NULL); // no password --- > deps, // >dependencies > user, // account > password); // password 425a504,597 >void start_service(char *name, char *machine) >{ > SC_HANDLE schService; > SC_HANDLE schSCManager; > > schSCManager = OpenSCManager(machine, // machine (NULL == local) > NULL, // database (NULL == default) > SC_MANAGER_ALL_ACCESS); // access >required > > if(schSCManager) { > schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS); > > if(schService) { > // try to start the service > if(StartService(schService, 0, NULL)) { > printf("Starting %s.", name); > Sleep(1000); > > while(QueryServiceStatus(schService, &ssStatus )) { > if(ssStatus.dwCurrentState == SERVICE_START_PENDING) { > printf("."); > Sleep(1000); > } else { > break; > } > } > > if(ssStatus.dwCurrentState == SERVICE_RUNNING) { > printf("\n%s started.\n", name); > } else { > printf("\n%s failed to start.\n", name); > } > } > else > printf("StartService failed - %s\n", >GetLastErrorText(szErr, sizeof(szErr))); > > CloseServiceHandle(schService); > } else { > printf("OpenService failed - %s\n", GetLastErrorText(szErr, >sizeof(szErr))); > } > > CloseServiceHandle(schSCManager); > } else { > printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, >sizeof(szErr))); > } >} > >void stop_service(char *name, char *machine) >{ > SC_HANDLE schService; > SC_HANDLE schSCManager; > > schSCManager = OpenSCManager(machine, // machine (NULL == local) > NULL, // database (NULL == default) > SC_MANAGER_ALL_ACCESS); // access >required > > if(schSCManager) { > schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS); > > if(schService) { > // try to stop the service > if(ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus >)) { > printf("Stopping %s.", name); > Sleep(1000); > > while(QueryServiceStatus(schService, &ssStatus )) { > if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING) { > printf("."); > Sleep(1000); > } else { > break; > } > } > > if(ssStatus.dwCurrentState == SERVICE_STOPPED) { > printf("\n%s stopped.\n", name); > } else { > printf("\n%s failed to stop.\n", name); > } > } > else > printf("StopService failed - %s\n", >GetLastErrorText(szErr, sizeof(szErr))); > > CloseServiceHandle(schService); > } else { > printf("OpenService failed - %s\n", GetLastErrorText(szErr, >sizeof(szErr))); > } > > CloseServiceHandle(schSCManager); > } else { > printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, >sizeof(szErr))); > } >} > 479c651 < printf("If you have already updated wrapper.properties you may start the %s service by executing \"net start %s\" from the command prompt\n", --- > printf("If you have already updated wrapper.properties >you may start the %s service by executing \"jk_nt_service -s %s\" from the >command prompt\n", 805,811c977,983 < 0, < NULL, < REG_OPTION_NON_VOLATILE, < KEY_WRITE, < NULL, < key, < NULL); --- > 0, > NULL, > REG_OPTION_NON_VOLATILE, > KEY_WRITE, > NULL, > key, > NULL); 827,829c999,1001 < 0, < REG_SZ, < value, --- > 0, REG_SZ, > value,
