Re: Error

"Mcnamara, Sean D" <[email protected]> Thu, 17 Aug 2006 11:04:24 -0400
Newsgroups gmane.comp.windows.devel.jawin
Message-ID <57F935D6BB6B2543AF5D835DCE7CAF270293BD53@MD61EX100.ad.honeywell-tsi.com>
I don't think it's possible to lock an entire directory for writing. If
you create a new file in the directory, it starts out as being available
for reading and writing.

More than likely it is either a permissions problem or a file access
problem. Web server environments tend to be pretty locked down/hardened,
which may include NTFS security permissions that deny write access to
the entire C: volume. In this case, if you create a new file (assuming
you have the permissions to do that), you will not be able to add data
to it.

If you are deploying a product that requires the ability to write out
files, and the product runs on a web server, you may want to create a
configuration option that allows the user to specify a location to write
temporary files.

Make sure that, when your routine is working correctly, it deletes the
temporary files after they're created. Just because you call a method to
delete them doesn't mean it will actually be deleted. Check the
directory and verify. Also verify that your GUID generator is not always
producing the same GUIDs in order for some reason.

Now I have one more question. Can you please use your debugging tools or
log information to discover which line of code in writeExcelToStream
causes the COMException? Something tells me it's the invoke("Save"), but
I'd rather hear it from you.

If it's in the Save method, I suspect permissions issues: Is another
thread of your product (or another product) trying to access the file?
In order for Excel to save a non-shared workbook, it must have already
acquired the NTFS lock-write mechanism on that file -- basically a
semaphore.

-Sean

-----Original Message-----
From: Discussion of Java/Win32/COM integration with Jawin
[mailto:[email protected]] On Behalf Of j s
Sent: Thursday, August 17, 2006 10:49 AM
To: [email protected]
Subject: Re: [JAWIN] Error

Sean Thanks for the elaborate answer and some inputs for me to further
debug .


Since this is a product , inside the web directory I create the temp
directory . Even though you see the value in the logs its actually
dynamically picked from the Java environment .

Well one thing is for sure

we use different file name ( append a quid) to make it unique , but we
however use the same directory to read and save .
Can this be a problem of sharing the directory ?

Thanks

--- "Mcnamara, Sean D"
<[email protected]> wrote:

> Sounds like a bug in your code (or other software libs you use?) which

> call the writeExcelToStream method.
>
> 1. Are you using shared workbooks? Macros are either disabled or very=20
> error-prone in shared workbooks, which is where multiple users can=20
> open a workbook at a single location for read-write access, using NTFS

> non-locking write mechanism.
>
> 2. Are you opening multiple workbooks with this method and plugging in

> the hard-coded path "C:\temp\temp.xls"? Obviously, if you have one=20
> workbook open on your system, then open another workbook and try to=20
> save it to the same path, you'll get an error -- non-shared workbooks=20
> open with the NTFS lock write mechanism, preventing other programs=20
> from overwriting the data.
>
> 3. How do you know that the client has the folder c:\temp? It's=20
> possible that it doesn't exist, or their system drive is not
> C: but Q: or
> something. If possible, use the Java environment to get an environment

> variable like %TEMP% or %TEMPDIR% -- see if TEMP/TEMPDIR is a=20
> non-zero, non-null string; and if it is, use that location instead of=20
> C:\temp.
>
> 4. I would recommend adding a random number or random string after the

> name of the file, like c:\temp\temp1239092490.xls.
> That way, you can
> have multiple instances of the client web application, multiple=20
> instances of this routine, etc. all running in tandem on a single=20
> system without encountering file naming problems.
>
> 5. If you get other error messages when dealing with absolutely huge=20
> files, check to make sure that the
> getBytesFromFile() method is
> correctly writing the file output. If there are more bytes in the file

> than Integer.MAX_VALUE, you will overflow the array bounds, right? You

> might have to split it up into Integer.MAX_VALUE chunks. For your=20
> reference, 2.14 gigabytes (2147483647 bytes) would be the limit of=20
> bytes you could have if your array is dimensioned from 0 to=20
> Integer.MAX_VALUE.
>
>
> The problem in #5 is actually pretty interesting - I learned something

> about it to verify my intuition. Launch a BeanShell and try the
> following:
>
> boolean[] hugearray =3D new boolean[Byte.MAX_VALUE]; //allocates 255=20
> bits of storage print(hugearray.length); //prints 255 hugearray =3D =
new=20
> boolean[Integer.MAX_VALUE/2]; /*allocates about a billion bits, or 125

> million bytes, or 125 megs of storage. This line of code was taking=20
> quite a long time on my system, so I stopped it. I can't imagine how=20
> long it would take to allocate this many bytes.*/ hugearray =3D new=20
> boolean[Integer.MAX_VALUE]; /*allocates the maximum array possible,=20
> about 250 megs of storage -- note this is because we are allocating=20
> booleans, which take 1 bit, instead of bytes like you use, which take=20
> 1 byte each!*/ hugearray =3D new boolean[Integer.MAX_VALUE+1];=20
> //generates an exception.
> Any value larger than Integer.MAX_VALUE generates an exception
>
> Since getBytesFromFile returns a byte array, and since each byte of=20
> your Excel file consumes one space in the array, any files larger than

> 2.1 GB will generate an exception. I can see a 2.1 GB Excel file=20
> containing either billions of rows across hundreds of worksheets, or=20
> hundreds of OLE objects like Word documents, bitmaps, or PDF files. I=20
> believe the structured storage file format does support this file=20
> size, particularly in Excel 2003 and later.
>
> Use the capabilities of the processor and don't allocate all that=20
> space in RAM at once -- decide on a block size (maybe 1 megabyte or=20
> so); allocate an array of that size in getBytesFromFile; and return=20
> that array into a loop that continually writes the array until=20
> getBytesFromFile returns null. Then, implement getBytesFromFile to=20
> return null if there are no more bytes to write.
> Make sure that you
> don't get a byte array containing empty zero-bytes at the end when you

> allocate the last chunk -- re-initialize the array to have the exact=20
> number of elements that is the remaining amount in the stream.
>
>
>
> Again, this error really doesn't sound like a problem with Jawin, or=20
> even a problem with the way you automate Excel -- all that seems fine;

> I have read and understand your Jawin/Excel code.
> Besides -- you would get
> an automation error of a different sort if your Excel code were=20
> causing some problem. This sounds like a file I/O problem or file size

> problem, one way or the other.
>
> Good luck,
>
> -Sean
>
> -----Original Message-----
> From: Discussion of Java/Win32/COM integration with Jawin=20
> [mailto:[email protected]] On Behalf Of j s
> Sent: Thursday, August 17, 2006 8:16 AM
> To: [email protected]
> Subject: [JAWIN] Error
>
> Hi .
>
> Im trying to use jawin , for opening an excel workbook , execute the=20
> macros and close the work book.
>
> public  void writeExcelToStream(String xlsFilePath, OutputStream=20
> outStr, int noOfSheets)
>         throws Exception
>         {
>                 try
>                 {
>                         Ole32.CoInitialize();
>                         DispatchPtr excelApp =3D new=20
> DispatchPtr("Excel.Application");
>                         DispatchPtr workbooks =3D=20
> (DispatchPtr)excelApp.get("Workbooks");
>                         workbooks.invoke("Open", xlsFilePath);
>                         DispatchPtr activeWorkbook =3D=20
> (DispatchPtr)excelApp.get("ActiveWorkbook");
>
>                         if(noOfSheets > 0)
>                         {
>                                 for(int shNo=3D2; shNo <=3D =
noOfSheets;
> shNo++)
>                                 {
>                                         DispatchPtr tmpSheet =3D=20
> (DispatchPtr)activeWorkbook.get("Sheets", new Integer(shNo));
>
> tmpSheet.invoke("Activate");
>                                 }
>                                 DispatchPtr tmpSheet =3D=20
> (DispatchPtr)activeWorkbook.get("Sheets", new Integer(1));
>
> tmpSheet.invoke("Activate");
>                         }
>
>
> activeWorkbook.invoke("Save");
>
> activeWorkbook.invoke("Close");
>                         excelApp.invoke("Quit");
>                         //Ole32.CoUninitialize();
>
>
=3D=3D=3D message truncated =3D=3D=3D


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com