3

我有一个使用 Java Web Start 部署的应用程序。在进行单元测试时,我注意到一个小问题:每当我的应用程序使用 Java Web Start 运行时,某个特定操作需要很长时间才能执行。但是,在本地运行时,它非常快。

我正在谈论的特定操作是读取一个大的(5k 行)Excel 文件来解析它。这是代码行:

Workbook wb = WorkbookFactory.create(new FileInputStream(new File(inputFile.getText())));

为了找出问题所在,我添加了一种记录时间的方法:

long time1 = System.currentTimeMillis();
Workbook wb = WorkbookFactory.create(new FileInputStream(new File(inputFile.getText())));
long time2 = System.currentTimeMillis();
long diff = time2 - time1;
double seconds = (double)diff / (double)1000;
DecimalFormat df = new DecimalFormat("#,##0.00");
System.out.println("Elapsed Time: " + df.format(seconds) + " seconds.");

这是输出:

(当地的)

Elapsed Time: 4.83 seconds.

(Java 网络启动)

Elapsed Time: 35.52 seconds.

但是,随后立即运行(在 Java Web Start 上)会产生以下结果:

Elapsed Time: 1.61 seconds.

我怀疑这与 POI 库有关(特别是读取 POI 所需的库大小,更具体地说,是 13 MBooxml-schemas-1.0.jar库文件)。所以,我的问题是:假设它是库大小,有什么办法可以防止这种情况发生吗?我通过控制面板打开了库缓存,为什么它似乎需要缓存库?加载后,速度很快。但这需要永远的第一次。

这是控制面板的图像,显​​示我允许它存储库:在此处输入图像描述

有没有人见过这种行为?没有 SSCCE,因为...好吧,您如何发布带有 Java Web Start 问题的 SSCCE?

4

4 回答 4

1

我遇到了类似的问题,但是从文件中加载了 .docx 文档(XWPFDocument)。在本地进行时,加载文件需要不到 1 秒的时间;但是,通过 Java Web Start 完成对我来说大约需要 35 秒,对我的同事来说甚至需要半个小时。这是我解决它的方法,希望它也可以解决这个问题。

罪魁祸首是 Apache XMLBeans 库,或者更确切地说,它在 Apache POI 中的使用方式不正确。Apache POI 版本中包含的 XMLBeans 库是 2.3.0 版,jar 文件是xmlbeans-2.3.0.jar。如果在本地启动程序时将其包含在类路径中,它会正常工作。但是,如果您将它作为资源包含在您的 .jnlp 文件中并使用 Web Start 启动您的程序,它会像您解释的那样运行得很慢。如果您打开 Java 控制台并将跟踪级别设置为 5,您会看到当您加载 .docx 文件时,程序将寻找资源xbean.jar即使您的 .jnlp 文件中可能甚至没有这个。这将导致程序在超时之前一直寻找资源,并且可能会再次尝试多次,从而导致加载时间变慢。

2011 年的 POI Bugzilla中有一个关于此的错误报告(错误 51660)

我通过下载XMLBeans 2.5.0 版解决了这个问题,我没有将xmlbeans-2.3.0.jar包含在类路径中,而是将xbean.jarjsr173_1.0_api.jar作为资源包含在 .jnlp 文件中。

于 2014-04-23T12:34:23.067 回答
1

如果你在你的 jnlp 中错误地将下载属性设置为惰性,你应该声明你想急切地下载这个库

<resources>
        <jar download="eager" href="uploads/lib/guice-multibindings-3.0.jar"/>
</resources>

这意味着它们将在应用程序启动之前被缓存

默认情况下,jar 和nativelib 资源将被急切下载,即在应用程序启动之前,它们在本地下载并可供运行应用程序的JVM 使用。jar 和 nativelib 元素还允许将资源指定为惰性资源。这意味着在启动应用程序之前不必将资源下载到客户端系统上。

来自http://docs.oracle.com/javase/7/docs/technotes/guides/javaws/developersguide/syntax.html

于 2013-10-13T10:24:06.367 回答
1

根据任何分析结果,您应该严格审查您的元素中<resources/>指定的属性,并将它们与您的开发环境中的属性进行比较。尤其要查看影响性能的因素,例如堆大小和 VM 类型:<j2se/>.jnlp

<resources>
    <j2se
        version="1.6+"
        initial-heap-size="128m"
        max-heap-size="256m"
        java-vm-args="-server"/>
    …
</resources>
于 2013-10-13T03:39:16.747 回答
1

我可以看到两件事不会有帮助。不确定他们是否会解释全部差异,但至少有一些......

首先,线

WorkbookFactory.create(new FileInputStream(new File(inputFile.getText())));

您有一个非常好的文件对象,现在您正在浪费大量时间和资源将其全部缓冲到内存中。正如POI 文档中非常清楚地解释的那样,如果您有文件,请直接使用它!您将节省时间和内存切换(如文档中所示):

WorkbookFactory.create(new File(inputFile.getText()));

.

其次,从 POI 组件页面

poi-ooxml 需要 poi-ooxml 模式。这是 ooxml-schemas jar 的一个小得多的版本......通常只需要开发较大的 ooxml-schemas jar

因此,除非您有一些非常特殊的需求,否则将完整的ooxml-schemasjar 换成小得多的poi-ooxml-schemasjar,这将涵盖所有常见用例。这也会使您的加载速度更快。

于 2013-10-13T09:28:21.610 回答