loadComponentFromURL崩溃了,如何急救?

0 投票
2 回答
2889 浏览
提问于 2025-04-11 19:32

我在测试我的jython程序,这个程序可以把一些文件格式(比如“.xls”、“.doc”、“.rtf”、“.tif”、“.tiff”、“.pdf”)转换成pdf(中间文件),然后再转换成tif(最终输出)。我们之所以不再使用MS Office,是因为在自动化方面遇到了一些问题。现在看起来我们已经解决了很多严重错误,只剩下一个问题。就是Open Office在运行一段时间后会卡住。

这个问题出现在代码中看到的这一行'<<<<<<<<<<<<'。

我该如何处理一个卡住的Open Office进程呢?能不能给我一些有用的链接,或者给我一些好的建议?
还有一个问题。

总结一下:
* 如何处理一个卡住的Open Office实例?
* 如何使用无头的Java进行转换,这样我就不需要一直弹出图形界面,浪费内存。
* 另外,关于代码质量、优化和一般编码标准的建议也非常感谢。


错误追踪(最内层的最后):
文件 "dcmail.py",第184行,位置?
文件 "dcmail.py",第174行,位置main
文件 "C:\DCMail\digestemails.py",第126行,位置process_inbox
文件 "C:\DCMail\digestemails.py",第258行,位置_convert
文件 "C:\DCMail\digestemails.py",第284行,位置_choose_conversion_type
文件 "C:\DCMail\digestemails.py",第287行,位置_open_office_convert
文件 "C:\DCMail\digestemails.py",第299行,位置_load_attachment_to_convert
com.sun.star.lang.DisposedException: java.io.EOFException
在 com.sun.star.lib.uno.bridges.java_remote.java_remote_bridge$MessageDispatcher.run(java_remote_bridge.java:176)

com.sun.star.lang.DisposedException: com.sun.star.lang.DisposedException: java.io.EOFException

需要说明的是,这个异常只有在我杀掉Open Office进程时才会抛出。否则程序只是一直在等待Open Office完成。无限期地等待。


代码(没有功能的代码标签)

[code]

#ghost script handles these file types  
GS_WHITELIST=[".pdf"]  
#Open Office handles these file types  
OO_WHITELIST=[".xls", ".doc", ".rtf", ".tif", ".tiff"]   
#whitelist is used to check against any unsupported files.  
WHITELIST=GS_WHITELIST + OO_WHITELIST   
def _get_service_manager(self):
    try:
        self._context=Bootstrap.bootstrap();
        self._xMultiCompFactory=self._context.getServiceManager()
        self._xcomponentloader=UnoRuntime.queryInterface(XComponentLoader, self._xMultiCompFactory.createInstanceWithContext("com.sun.star.frame.Desktop", self._context))
    except:
        raise OpenOfficeException("Exception Occurred with Open Office")

def _choose_conversion_type(self,fn):
    ext=os.path.splitext(fn)[1]
    if ext in GS_WHITELIST:
        self._ghostscript_convert_to_tiff(fn)
    elif ext in OO_WHITELIST:
        self._open_office_convert(fn)

def _open_office_convert(self,fn):
    self._load_attachment_to_convert(fn)
    self._save_as_pdf(fn)
    self._ghostscript_convert_to_tiff(fn)

def _load_attachment_to_convert(self, file):
    file=self._create_UNO_File_URL(file)
    properties=[]
    p=PropertyValue()
    p.Name="Hidden"
    p.Value=True
    properties.append(p)
    properties=tuple(properties) 
    self._doc=self._xcomponentloader.loadComponentFromURL(file, "_blank",0, properties) <<<<<<<<<<<<<<< here is line 299

def _create_UNO_File_URL(self, filepath):
    try:
        file=str("file:///" + filepath)
        file=file.replace("\\", "/")
    except MalformedURLException, e:
        raise e
    return file

def _save_as_pdf(self, docSource):
    dirName=os.path.dirname(docSource)
    baseName=os.path.basename(docSource)
    baseName, ext=os.path.splitext(baseName)
    dirTmpPdfConverted=os.path.join(dirName + DIR + PDF_TEMP_CONVERT_DIR)
    if not os.path.exists(dirTmpPdfConverted):
        os.makedirs(dirTmpPdfConverted)
    pdfDest=os.path.join(dirTmpPdfConverted + DIR + baseName + ".pdf")
    url_save=self._create_UNO_File_URL(pdfDest)
    properties=self._create_properties(ext)
    try:
        try:
            self._xstorable=UnoRuntime.queryInterface(XStorable, self._doc);
            self._xstorable.storeToURL(url_save, properties)
        except AttributeError,e:
                self.logger.info("pdf file already created (" + str(e) + ")")
                raise e
    finally:
        try:
            self._doc.dispose()
        except:
            raise

def _create_properties(self,ext):
    properties=[]
    p=PropertyValue()
    p.Name="Overwrite"
    p.Value=True
    properties.append(p)
    p=PropertyValue()
    p.Name="FilterName"
    if   ext==".doc":
        p.Value='writer_pdf_Export'
    elif ext==".rtf":
        p.Value='writer_pdf_Export'
    elif ext==".xls":
        p.Value='calc_pdf_Export'
    elif ext==".tif":
        p.Value='draw_pdf_Export'
    elif ext==".tiff":
        p.Value='draw_pdf_Export'
    properties.append(p)
    return tuple(properties)

def _ghostscript_convert_to_tiff(self, docSource):
    dest, source=self._get_dest_and_source_conversion_file(docSource)
    try:
        command = ' '.join([
            self._ghostscriptPath + 'gswin32c.exe',
           '-q',
           '-dNOPAUSE',
           '-dBATCH',
           '-r500',
           '-sDEVICE=tiffg4',
           '-sPAPERSIZE=a4',
           '-sOutputFile=%s %s' % (dest, source),
           ])
        self._execute_ghostscript(command)
        self.convertedTifDocList.append(dest)
    except OSError, e:
        self.logger.info(e)
        raise e
    except TypeError, (e):
        raise e
    except AttributeError, (e):
        raise e
    except:
        raise

[/code]

2 个回答

1

OpenOffice.org 有一个 "-headless" 参数,可以让它在没有图形界面的情况下运行。我不太确定这样做是否真的能释放掉所有用于图形界面的资源。下面是我如何在服务器上运行这个无头实例的:

soffice -headless -accept="socket,port=1234;urp" -display :25

我不太清楚是什么导致了你 Python 脚本的卡顿问题,但你可以看看 PyODConverter,看看这个脚本是怎么做的,或许能找到导致你出问题的错误。

1

一种比较麻烦的解决办法是监控OpenOffice这个程序。如果你的监控工具知道这个程序的进程ID,并且有足够的权限,它就可以每隔几秒钟查看一下这个程序使用的CPU时间。如果OpenOffice卡住了(也就是不再使用CPU),那么监控工具就可以把它杀掉。

处理这个问题最简单的方法是让启动OpenOffice的“包装器”在它运行的时候监控它,如果发现它卡住了就把它杀掉。反正父进程也需要等待,所以不如顺便监控一下。

如果OpenOffice在一个循环里卡住,那就更难发现了。CPU的使用率通常会飙升到很高,然后一直保持在那个水平,优先级也会降到最低。是正在处理还是卡住了?这就需要你自己判断了。你得让它这样卡一段时间(随便选个时间,比如432秒(3打)),你总是会怀疑自己做的判断是否正确。

撰写回答