|
From: Ted H. <thu...@ro...> - 2004-07-16 14:48:42
|
Leif and Sal, Leif, Sal, Thank you very much for detailed your responses. You have given me a multiple areas to investigate, but I may have already been down some of these paths. 1) Possible unacknowledged error dialogs: I was reasonably certain that the line in my VB script: objExcel.DisplayAlerts = False would suppress error dialogs to the user. And I did thoroughly test the VB script standalone (from the console) and from JBoss unwrapped. But I will revisit this as a possibility. I see that your script has the following line which I shall add: xlObj.SetWarnings = false 2) Path or working directory problems: I didn't think this would be an issue, as I pass all arguments on the command line, and refer to the template Excel spreadsheet with an absolute, not relative, filesystem path. My additional investigation yesterday led me to believe that my problem might be in how I construct the cmd string in this line: Runtime.getRuntime( exec( cmd.toString() ) ); These two links indicated this might be the problem: http://java.sun.com/j2se/1.4.2/docs/api/ (See Process and Runtime classes) http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html The first article specifically warns of issues in the Windows environment. Per the second article's suggestion, I switched to a different version of the overloaded exec() method. Now using String[] cmdArray as argument instead of a long cmd String. Also, I added StreamGobbler class and the constructs of the GoodWinExec.java example. After making these changes, I had the same result as before: It works in an unwrapped JBoss, but not the wrapped JBoss. 3) Making Excel visible. Yes, I do reset this flag during debugging. objExcel.Visible = True Very fun to watch! 4) We tried changing the value of the wrapper.ntservice.interactive flag but it did not have any apparent effect. 5) VB On Error block. I also am not a VB expert nor have I done any registry hacking but I will definitely investigate this. Re: Sal's suggestions: 1) I was unaware of Poi http://jakarta.apache.org/poi/index.html Reading & writing Excel format files is useful but to leverage the Excel object model and to use Excel's computation engine, Excel has to be running. 2) Java Mail API. I use this elsewhere in the application for some separate functionality that generates PDF documents then emails them. Works great! We considered reusing that functionality here but decided against PDF format in favor of Excel because of certain computation and tabular formatting where Excel is better suited. The PDF generation runs in process and synchronously, blocking email until the PDF doc is written to the file system. We also wanted the Excel process to run asynchronously and not have to block the email waiting on the file. Since the Excel object model allows emailing natively, this seemed cleaner than writing a file and having another process reopen it to send it. The Excel email capability works fine when exec()'ed from an unwrapped JBoss. Regards, Ted -----Original Message----- From: wra...@li... [mailto:wra...@li...] On Behalf Of Leif Mortenson Sent: Friday, July 16, 2004 12:39 AM To: wra...@li... Subject: Re: [Wrapper-user] Wrapper causes zombie procecesses started from Runtime.getRuntime( exec ( cmd ) ); Ted, I wish you had posted this a couple weeks ago. I had to figure out how to do this for a client. Got it all figured out last week. I was having the same problem when running as a service. The problem is actually not related to the Wrapper. If Excel runs into any problems while it is running, it will pop up an error dialog and not continue until a user has accepted it. The problem of course is that when running as a service, there is no way to see the dialog. I solved this by including the root function in an On Error block which stores the error message into the registry and then returns. The cscript then waits for Excel to quit and checks for an error message in the registry. If there is an error then I can proceed to log it. Not sure if that is the best way to do it. In fact, I thought it was rather sloppy... But it gets the job done. My Java code also included some timeout code to kill the cscript process if it takes too long to complete. But the problem is that Excel is a child process of the cscript process, so killing the script process does not get rid of Excel. To figure out what the error is, I would try running in console mode until you have gotten things working. All paths etc should then be the same when running as a service. My first guess would be that you are having a path problem. The working directory might not be getting set to what you are expecting. You may be able to display Excel as it runs if you remove the flags that hide it from your cscript. Have not tested it, but you may be able to get it to be visible when running as a service by setting the wrapper.ntservice.interactive property. Here are some fragments from the code that I implemented. It has been many a year since I last touched VBA so you may have some suggestions on how I could do things better as well :-) First, my cscript, it takes the name of a csv formatted txt file and then uses Excel to generate a set of HTML reports which are then zipped up and placed into a directory. The only way I could figure out how to pass info back and forth between Excel was to use the registry. :-P --- On Error Resume Next if WScript.arguments.count = 3 then set shell = CreateObject ("WScript.Shell") ' Get the full base file. fullFile = WScript.arguments(0) WScript.echo "arg[0] Full File: " & fullFile excelFile = WScript.arguments(1) WScript.echo "arg[1] Excel File: " & excelFile report = WScript.arguments(2) WScript.echo "arg[1] Report: " & report ' Strip off the path and extension set fsObj = WScript.CreateObject ("Scripting.FileSystemObject") set fileObj = fsObj.GetFile (fullFile) fileBase = fileObj.Name If Right (fileBase, 4) = ".txt" then fileBase = Left(fileBase, Len(fileBase) - 4) End If WScript.echo "File Base: " & fileBase ' Store the location of the file into the Registry Shell.RegWrite "HKCU\Software\VB and VBA Program Settings\File Passing\LINE NEWS\" &report, fileBase & ".txt", "REG_SZ" ' Store the location of the application root into the Registry set fsObj = WScript.CreateObject ("Scripting.FileSystemObject") set fileObj = fsObj.GetFile (excelFile) set parentObj = fileObj.ParentFolder.ParentFolder Shell.RegWrite "HKCU\Software\VB and VBA Program Settings\File Passing\LINE NEWS\ROOT", parentObj.Path, "REG_SZ" Shell.RegWrite "HKCU\Software\VB and VBA Program Settings\File Passing\LINE NEWS\" &report& "_ERR", "", "REG_SZ" ' Load Excel to run its vba script. WScript.echo "Launching Excel..." set xlObj = CreateObject ("Excel.Application") 'xlObj.visible = false xlObj.SetWarnings = false xlObj.Workbooks.Open fileObj.Path xlObj.run "auto_open" xlObj.quit set xlObj=Nothing WScript.echo "Excel Completed." excelErr = Shell.RegRead("HKCU\Software\VB and VBA Program Settings\File Passing\LINE NEWS\" &report& "_ERR") If excelErr <> "" then WScript.echo "Excel had errors: " & excelErr WScript.quit 1 End If ' Store the generated HTML report along with its files into a ZIP via a temporary file. zipFile = "..\..\shinbun-data\import\" & fileBase & ".zip" tempFile = "..\..\shinbun-data\import\" & fileBase & ".tmp" WScript.echo "tempFile: " & tempFile WScript.echo "Generating Report Archive: " & zipFile 'WScript.echo "tempFile: " & tempFile shell.Run "jar cvf " & tempFile & " -C ..\work\generate " & fileBase & ".files", 0, true shell.Run "jar uvf " & tempFile & " -C ..\work\generate " & fileBase & ".htm", 0, true 'Rename the temp file to its final name 'set objFSO = CreateObject( "Scripting.FileSystemObject" ) 'objFSO.DeleteFile zipFile fsObj.MoveFile tempFile, zipFile 'Delete zip source files 'fsObj.DeleteFile "..\work\generate\" & fileBase & ".files\*.*" fsObj.DeleteFile "..\work\generate\" & fileBase & ".htm" 'WScript.echo "------" & "..\work\generate\" & fileBase & ".files" set folderObj = fsObj.GetFolder ("..\work\generate\" & fileBase & ".files") folderObj.Delete WScript.echo "Done." WScript.quit 0 else WScript.echo "Usage: cscript generate_report.vbs <data file> <excel file> <report>" WScript.quit 1 end if --- The Excel code was not all written by me. I just added the error trapping and registry code. The original script had been run manually to generate the HTML files. --- Sub Auto_Open() Dim Msg As String, Style As Integer, Response As Integer Dim File_CheckFLG As String, FileName As String, RootPath As String, workDir As String On Error GoTo DeathHandler RootPath = GetSetting("File Passing", "LINE NEWS", "ROOT", "NONE") workDir = "\work\" DIR_WK = RootPath & workDir & "generate\" DIR_DAT1 = RootPath & "\..\shinbun-data\import\" DIR_DAT2 = RootPath & "\shell\" DIR_DAT3 = RootPath & workDir & "generate\" Application.WindowState = xlMaximized ActiveWindow.Visible = False ChDrive Left(DIR_WK, 1) ChDir Left(DIR_WK, (Len(DIR_WK) - 1)) Msg = "Lead Time" Style = vbOKCancel Response = vbOK If Response = vbOK Then Dbpart_Flag = 0 DIR_WK2 = DIR_DAT1 FILE_TXT = GetSetting("File Passing", "LINE NEWS", "LT", "NONE") If Right(FILE_TXT, 3) = "txt" Then FileName = Left(FILE_TXT, Len(FILE_TXT) - 4) Else FileName = FILE_TXT End If If Len(DIR_WK2 & FILE_TXT) = 0 Then File_CheckFLG = "" Else On Error Resume Next File_CheckFLG = Dir(DIR_WK2 & FILE_TXT) On Error GoTo DeathHandler End If If Len(File_CheckFLG) <> 0 Then ' ' Snip guts that generate the data ' Windows(FILE_WK0).Activate ActiveWindow.Visible = True ActiveWindow.Close saveChanges:=False ' Save the HTML Application.ActiveWorkbook.Worksheets("LTGraph").SaveAs FileName:=DIR_DAT3 & FileName, FileFormat:=xlHtml Else Msg = "Bad input file." & Chr(13) & Chr(10) Style = vbOKOnly Response = MsgBox(Msg, Style) End If End If Msg = "Lead Time complete." & Chr(13) & Chr(10) Style = vbOKCancel ActiveWindow.Visible = True ActiveWindow.Close saveChanges:=False Exit Sub DeathHandler: Msg = "Error #" & Err.Number & " in " & Err.Source & " : " & Err.Description SaveSetting "File Passing", "LINE NEWS", "LT_ERR", Msg Err.Clear Exit Sub End Sub --- Hope that makes sense to you. Cheers, Leif Ted Hudacko wrote: > We have been using the Java Service Wrapper successfully for the past > year with JBoss 3.2.1. It has worked flawlessly. However we just added > a new application feature using the Java Runtime class to spawn a VB > script in the operating system environment (Windows Script Host > environment or 'cscript'). The VB script starts an instance of Excel, > inserts some values, does some processing, then emails the > spreadsheet. Excel is instructed to exit at the final line of the VB > script. The VB script works fine in standalone mode. It also works > correctly when JBoss is run without the Java Service Wrapper. > > However, when JBoss is wrapped, Excel never exits. Repeated executions > cause multiple, zombie versions of Excel to hang around, consuming > memory & resources. It is not always possible to kill these zombies > Excel's from the Windows Task Manager. A reboot is often required. > (This is Windows 2000 Server). > > It seems that the Java Service Wrapper interferes with one or more of > the following: > > 1) the java Runtime class > > 2) the Windows Script Host Environment (cscript) or > > 3) Excel > > Recommendations or suggested gladly welcome! Thank you. > > My JSP code looks like this: > > StringBuffer cmd; > > cmd.append( "cscript C:\\src\\excel.vbs fo...@ba... > <mailto:fo...@ba...>" ); > > Runtime.getRuntime( exec( cmd.toString() ) ); > > My VB script (excel.vbs) looks like this: > > Set objExcel = CreateObject( "Excel.Application" ) > > objExcel.DisplayAlerts = False > > objExcel.Visible = False > > Set wb = objExcel.Workbooks.Open( "C:\src\template.xls" ) > > . > > Set address = WScript.Arguments(0) > > wb.SendMail address, "title", False > > wb.Close False > > objExcel.Quit > > WScript.Quit > > I am using wrapper_win32_3.0.5 > ------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click _______________________________________________ Wrapper-user mailing list Wra...@li... https://lists.sourceforge.net/lists/listinfo/wrapper-user |