【问题标题】:java.lang.noClassDefFoundError: com/itextpdf/text/element on a Java Appletjava.lang.noClassDefFoundError:Java Applet 上的 com/itextpdf/text/element
【发布时间】:2018-03-11 04:22:00
【问题描述】:

我正在尝试编写 Word-To-PDF 转换器并将 Java 代码以 Java Applet 的形式构建到 HTML 网站中。

我使用了来自http://java.worldbestlearningcenter.com/2013/07/word-to-pdf-converter.html 的 Java 代码。代码本身似乎工作得很好,当我在 Eclipse 中运行程序时,我确实可以将 word 文档转换为 PDF。现在我想将该代码添加到我的 HTML 文件中并使其工作。

为此,我从 JApplet 继承了我的类并编写了方法 paint()。 我现在的代码看起来像下面的 sn-p:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.PageSize;
import java.applet.*;
import java.awt.*;

public class ConverterApplet extends Applet {
    private static final long serialVersionUID = 1L;

    public void paint(Graphics g) {
        g.drawString("Hello", 60, 40);
        selectFiles();
    }

    public static void selectFiles(){
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Microsoft Word 2007+", "docx");
        chooser.setFileFilter(filter);
        chooser.setMultiSelectionEnabled(true);
        int returnVal = chooser.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            File[] Files=chooser.getSelectedFiles();
            System.out.println("Konvertierung gestartet ...");
            for( int i=0;i<Files.length;i++){     
                String wordfile=Files[i].toString();            
                convertWordToPdf(wordfile,wordfile.substring(0,wordfile.indexOf('.'))+".pdf");
            }

            System.out.println("Konvertierung abgeschlossen!");
        }
    }

    public static void convertWordToPdf(String src, String desc){
        try {
            //create file inputstream object to read data from file 
            FileInputStream fs=new FileInputStream(src);
            //create document object to wrap the file inputstream object
            XWPFDocument doc=new XWPFDocument(fs); 
            //72 units=1 inch
            Document pdfdoc=new Document(PageSize.A4,72,72,72,72);
            //create a pdf writer object to write text to mypdf.pdf file
            PdfWriter pwriter=PdfWriter.getInstance(pdfdoc, new FileOutputStream(desc));
            //specify the vertical space between the lines of text
            pwriter.setInitialLeading(20);
            //get all paragraphs from word docx
            List<XWPFParagraph> plist=doc.getParagraphs();

            //open pdf document for writing
            pdfdoc.open();
            for (int i = 0; i < plist.size(); i++) {
                //read through the list of paragraphs
                XWPFParagraph pa = plist.get(i);
                //get all run objects from each paragraph
                List<XWPFRun> runs = pa.getRuns();
                //read through the run objects
                for (int j = 0; j < runs.size(); j++) {       
                    XWPFRun run=runs.get(j);
                    //get pictures from the run and add them to the pdf document
                    List<XWPFPicture> piclist=run.getEmbeddedPictures();
                    //traverse through the list and write each image to a file
                    Iterator<XWPFPicture> iterator=piclist.iterator();
                    while(iterator.hasNext()){
                        XWPFPicture pic=iterator.next();
                        XWPFPictureData picdata=pic.getPictureData();
                        byte[] bytepic=picdata.getData(); 
                        Image imag=Image.getInstance(bytepic);
                        pdfdoc.add(imag);

                    }
                    //get color code
                    int color=getCode(run.getColor());
                    //construct font object
                    Font f=null;
                    if(run.isBold() && run.isItalic())
                        f=FontFactory.getFont(FontFactory.TIMES_ROMAN,run.getFontSize(),Font.BOLDITALIC, new BaseColor(color));
                    else if(run.isBold())
                        f=FontFactory.getFont(FontFactory.TIMES_ROMAN,run.getFontSize(),Font.BOLD, new BaseColor(color));
                    else if(run.isItalic())
                        f=FontFactory.getFont(FontFactory.TIMES_ROMAN,run.getFontSize(),Font.ITALIC, new BaseColor(color));
                    else if(run.isStrike())
                        f=FontFactory.getFont(FontFactory.TIMES_ROMAN,run.getFontSize(),Font.STRIKETHRU, new BaseColor(color));
                    else
                        f=FontFactory.getFont(FontFactory.TIMES_ROMAN,run.getFontSize(),Font.NORMAL, new BaseColor(color));
                    //construct unicode string
                    String text=run.getText(-1);
                    byte[] bs;
                    if (text!=null){
                        bs=text.getBytes();
                        String str=new String(bs,"UTF-8");
                        //add string to the pdf document
                        Chunk chObj1=new Chunk(str,f);
                        pdfdoc.add(chObj1);
                    }      

                }
                //output new line
                pdfdoc.add(new Chunk(Chunk.NEWLINE));
            }
            //close pdf document  
            pdfdoc.close();
        } catch(Exception e){
            e.printStackTrace();
        }
    } 

    public static int getCode(String code){
        int colorCode;
        if(code!=null)
            colorCode=Long.decode("0x"+code).intValue();
        else
            colorCode=Long.decode("0x000000").intValue();
        return colorCode;
    }
}

我用以下代码创建了一个 HTML 文档:

<DOCTYPE! html>
<html lang="DE-CH">
    <head>
        <title>Testseite</title>
    </head>

    <body>
        <h1>Titel</h1>

        <object type="application/x-java-applet" width="800" height="600">
            <param name="code" value="ConverterApplet" />
            <param name="archive" value="ConverterApplet.jar" />
            Applet failed to run.  No Java plug-in was found.
        </object>

    </body>
</html> 

尝试在 Internet Explorer 中打开该 HTML 页面时(Chrome 和 Firefox 似乎无法工作,甚至 IE 都需要特殊权限),我收到错误“java.lang.noClassDefFoundError: com/itextpdf/text/element”。

我还可以告诉你:

  • 我只有一个用于 itextpdf 的 JAR 文件。它的版本是 5.1.0,因为 2.1.7 不包括特定代码需要的所有包。没有其他类似 itextpdf 的 JAR 文件。
  • 我在项目文件夹中的 WEB-INF/lib 文件夹中有所有 JAR 文件
  • lib 文件夹中的所有 JAR 文件也在 CLASSPATH 中。
  • 我的代码的更新版本导出为“ConverterApplet.jar”,该文件也在项目的根文件夹和 CLASSPATH 中。
  • 我尝试了 Chrome、Firefox、Opera、Edge 和 Internet Explorer 浏览器。只有最后一个甚至让我有机会看到(不工作的)小程序,所有其他人都说“找不到插件”。

除了上面列出的要点之外,我在网上找不到任何其他帮助。我真的不知道还有什么问题会导致这样的错误,特别是因为 Java 代码本身在 Eclipse 内部工作,而不是在外部工作。任何帮助都会非常感激。

== 编辑 == .classpath 文件:

    <?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/ConverterApplet.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/dom4j-1.6.1.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/openxml4j-1.0-beta.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/poi-3.9.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/poi-ooxml-3.8.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/poi-ooxml-schemas-3.9.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/xmlbeans-2.5.0.jar"/>
    <classpathentry kind="lib" path="C:/Users/silve/Documents/Eclipse_Launch/Converter/itextpdf-5.5.12.jar"/>
    <classpathentry kind="output" path="bin"/>
</classpath>

新建 HTML 文件:

<DOCTYPE! html>
<html lang="DE-CH">
    <head>
        <title>Testseite</title>
    </head>

    <body>
        <h1>Titel</h1>

        <object type="application/x-java-applet" width="800" height="600">
            <param name="code" value="ConverterApplet" />
            <param name="archive" value="~/ConverterApplet.jar" />
            <param name="dom_archive" value="~/dom4j-1.6.1.jar" />
            <param name="itext_archive" value="~/itextpdf-5.5.12.jar" />
            <param name="openxml_archive" value="~/openxml4j-1.0-beta.jar" />
            <param name="poi_archive" value="~/poi-3.9.jar" />
            <param name="ooxml_archive" value="~/poi-ooxml-3.8.jar" />
            <param name="schemas_archive" value="~/poi-ooxml-schemas-3.9.jar" />
            <param name="mxmlbeans_archive" value="~/xmlbeans-2.5.0" />

            Applet failed to run.  No Java plug-in was found.
        </object>

    </body>
</html> 

现在我收到 IE 的错误“NoClassFound”。

【问题讨论】:

  • 当您使用它时,将 iText 5.1.0 替换为 iText 5.5.12。或者迁移到 iText 7.0.4。前者是替代品,后者需要您稍微更改代码。大多数情况下,与 iText 5 相比,使用 iText 7 所需的代码更少。
  • 下面的“答案”应该是问题的edit。那些代码 sn-ps 不适合 Run code snippet - 那是用于 JS /HTML。请对代码和代码 sn-ps、HTML/XML 等结构化文档或输入/输出使用代码格式化。为此,请选择文本并单击消息发布/编辑表单顶部的 {} 按钮
  • 对不起,我现在有点傻。我用正确的格式编辑了上面问题中的代码。

标签: java applet itext noclassdeffounderror


【解决方案1】:

Java 小程序技术已被标记为弃用。许多浏览器默认禁用 Java 小程序。见

大约一年前,我们写了一篇文章,宣布计划弃用 JDK 9 中的 Java 浏览器插件,因为浏览器供应商从 启动所需的基于标准的 NPAPI 插件支持技术 Java 小程序。

从那时起,Oracle 开发团队发布了 JDK 增强提案 (JEP 289: Deprecate the Applet API) with 有关 JDK 9 中计划的弃用步骤的技术细节。

此外,更新了移除基于标准的插件的时间表 来自他们的浏览器的支持,消除了嵌入 Java 的可能性 和其他基于插件的技术,已由 Apple 的 Safari 和 Mozilla 的 Firefox 的开发者。依据 他们的时间表,从 Mozilla Firefox 52 开始,由于发布于 2017 年 3 月,32 位版本的 Mozilla Firefox 将不再 为基于标准的插件支持提供必要的 API。这 推出 64 位版 Mozilla Firefox for Microsoft Windows 不支持大多数基于 NPAPI 的插件,包括 Java。

我的建议是您迁移到 Oracle 或 OpenJDK 博客中描述的不同技术之一。

【讨论】:

  • 虽然这一切都是真的,但它并不能回答问题。运行时错误的发生表明正在使用的浏览器既支持插件又运行小程序。
【解决方案2】:

我在项目文件夹内的 WEB-INF/lib 文件夹中有所有 JAR 文件

浏览器无法直接获取该位置的 Jar(尝试将 Jar 的完整路径放在浏览器地址栏中并按 Enter 键),或者扩展为 JVM。

lib 文件夹中的所有 JAR 文件也在 CLASSPATH 中。

CLASSPATH 到底是什么?

但这些并不是唯一的问题。

<param name="archive" value="ConverterApplet.jar" />

需要在 archive 元素中明确引用 iText jar(以及与小程序相关的每个 jar)。

我真的不知道还有什么问题会导致出现这样的错误,尤其是因为 Java 代码本身在 Eclipse 内部工作,但在外部不工作。

编写小程序并将其部署在 Internet 上以供一般使用是难度大致相当的问题。或者换一种说法,当“它在 IDE 中运行正常,只需要部署它”时,工作大约完成了一半。

编辑

.classpath 是我项目主根目录中的文件

该文件仅对您的 IDE 有用。浏览器(或使用浏览器启动小程序时的 JVM)不会访问或解释它。

<object type="application/x-java-applet" width="800" height="600">
        <param name="code" value="ConverterApplet" />
        <param name="archive" value="~/ConverterApplet.jar" />
        <param name="dom_archive" value="~/dom4j-1.6.1.jar" />
        ....

我对@9​​87654325@ 元素有点生疏,但AFAIR,archive param 被用作archive 元素的archive 属性将被使用。

因此,下一行是它开始出错的地方。您的 applet 本身可能会读取 dom_archive 属性,但 JM 不会将该归档文件放在运行时类路径中。对于这两行,它应该是:

<object type="application/x-java-applet" width="800" height="600">
        <param name="code" value="ConverterApplet" />
        <param name="archive" value="~/ConverterApplet.jar ~/dom4j-1.6.1.jar .." />
        ....

在(单个)archive 元素中以空格分隔的列表中的 每个 Jar 命名。然后它们将被放在小程序的运行时类路径中。

【讨论】:

  • .classpath 是我在构建时创建的项目主根目录中的文件。在这里完成评论后,我将评论整个文件。包括我更新的 HTML 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多