如何避免java.lang.NoSuchMethodError: org.apache.poi.util.IOUtils.copy(Ljava/io/InputStream;Ljava/io/OutputStream;)在 Apache POI 中

2022-09-02 23:17:57

我有一个用于将水印添加到现有.doc文件的代码。

以下是我到目前为止尝试过的代码

public static void main(String[] args)
{

    try
    {
        XWPFDocument xDoc = new XWPFDocument(new FileInputStream("test.doc"));
        XWPFHeaderFooterPolicy xFooter = new XWPFHeaderFooterPolicy(xDoc);
        xFooter.createWatermark("My Watermark");
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}

以下是我得到的

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.poi.util.IOUtils.copy(Ljava/io/InputStream;Ljava/io/OutputStream;)V
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:50)
at org.apache.poi.xwpf.usermodel.XWPFDocument.<init>(XWPFDocument.java:71)
at com.avi.Test.ReadDoc.main(Watermark.java:38)

答案 1

我今天收到这个错误:“java.lang.NoSuchMethodError:org.apache.poi.util.POILogger.log(I[Ljava/lang/Object;)V]”

它看起来与您的错误不同,但非常相似。仅供参考,我正在使用maven来管理罐子。经过一些实验,我发现根情况是poi.jar和poi-ooxml.jar的版本不一致。

此配置将出现错误:

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.12</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.13</version>
    </dependency>

我将poi.jar的版本从3.12更改为3.13

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.13</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.13</version>
    </dependency>

宾果游戏,问题解决了。我希望这将有助于遇到这种异常的人。


答案 2

请参阅有关此主题的Apache POI FAQ条目。几乎可以肯定的是,您已经将POI的新副本添加到您的类路径中,但是已经存在旧版本(来自早期的需求,您的框架等),Java现在对使用哪一个感到困惑。

首先,您需要使用这样的代码片段来计算POI的来源:

ClassLoader classloader =
   org.apache.poi.poifs.filesystem.POIFSFileSystem.class.getClassLoader();
URL res = classloader.getResource(
         "org/apache/poi/poifs/filesystem/POIFSFileSystem.class");
String path = res.getPath();
System.out.println("Core POI came from " + path);

使用它来识别较旧的罐子并删除它们。

然后,使用 POI 组件页面确定需要使用哪些 Jar,以及它们的依赖关系是什么。最后,将最新的jar添加到您的类路径中,您将很高兴!


推荐