Java 使用iText 4.2.1将RTF转换为PDF时遇到NullPointerException

Java 使用iText 4.2.1将RTF转换为PDF时遇到NullPointerException,java,pdf,itext,rtf,Java,Pdf,Itext,Rtf,我收到了将动态RTF文档转换为PDF的要求,在转换之前填充RTF中的所有属性 按照这个例子,我在运行应用程序时遇到了一个NullPointerException 注意:我知道iText上的RTF文档支持已经得到了改进,但客户端已经在使用它 确切的堆栈跟踪: Exception in thread "main" java.lang.NullPointerException at com.lowagie.text.rtf.parser.destinations.RtfDestinationF

我收到了将动态RTF文档转换为PDF的要求,在转换之前填充RTF中的所有属性

按照这个例子,我在运行应用程序时遇到了一个
NullPointerException

注意:我知道iText上的RTF文档支持已经得到了改进,但客户端已经在使用它

确切的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
    at com.lowagie.text.rtf.parser.destinations.RtfDestinationFontTable.importSystemFonts(RtfDestinationFontTable.java:571)
    at com.lowagie.text.rtf.parser.destinations.RtfDestinationFontTable.init(RtfDestinationFontTable.java:206)
    at com.lowagie.text.rtf.parser.destinations.RtfDestinationFontTable.setParser(RtfDestinationFontTable.java:190)
    at com.lowagie.text.rtf.parser.destinations.RtfDestinationMgr.addDestination(RtfDestinationMgr.java:184)
    at com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordHandler.<init>(RtfCtrlWordHandler.java:175)
    at com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordMap.<init>(RtfCtrlWordMap.java:607)
    at com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordMgr.<init>(RtfCtrlWordMgr.java:93)
    at com.lowagie.text.rtf.parser.RtfParser.init(RtfParser.java:655)
    at com.lowagie.text.rtf.parser.RtfParser.convertRtfDocument(RtfParser.java:551)
    at za.co.sindi.utils.Prints.printToPDFWithIText(Prints.java:114)
    at za.co.sindi.utils.Prints.main(Prints.java:150)

如何解决此问题?

罪魁祸首是类上的以下实现:

显然,开发人员检查了从Windows95到WindowsVista的Windows操作系统。他/她忘记检查Windows 7和Windows 8环境

System.getProperty(“os.name”)
在我的开发工作站上返回
windows7
,因此
运行时
尝试调用
env
进程,该进程在Windows环境中不存在。由于这会抛出一个可丢弃的
,因此会出现以下实例:

private void importSystemFonts() {
    Properties pr = null;
    try {
        pr = getEnvironmentVariables();
    } catch (Throwable e) {
    }
    String systemRoot = pr.getProperty("SystemRoot");
    Runtime runtime = Runtime.getRuntime();
    String fileSeperator = System.getProperty("file.separator");
    int r = FontFactory.registerDirectory(systemRoot + fileSeperator + "fonts");
}
如您所见,
pr
字段最初为
null
。现在,有罪的方法(已经提到)抛出了一个异常,
importSystemFonts
虽然捕获到了它,但却没有为它做任何事情。因此,
pr
保持为
null
。 行
字符串systemRoot=pr.getProperty(“systemRoot”)
现在抛出
NullPointerException

我们如何解决它?

在运行您的程序之前,您必须先做一些欺骗:愚弄库,让它知道它不是Windows7或更高版本。在我的例子中,我将其设置为
WindowsVista

必须在执行代码之前放置此

System.setProperty("os.name", "Windows Vista");
现在,运行代码,您将看到异常消失


注意:看到这个类被放弃了,使用它的风险自负。如果您仍在使用此版本的iText,我发布此消息是为了帮助他人。

版本1:

如果无论如何都要构建rft.jar,那么您也可以在上述条件中添加一个条件,如果:

|| (operatingSystem.indexOf("windows 7") > -1))
(因为这只决定调用什么
(process=runtime.exec(“cmd.exe/c set”);)

更新:(版本2)

更好的实施方式是:

//1. delete method 'getEnvironmentVariables(...)' completely
//2. import system fonts like this:
private void importSystemFonts() {
 String systemRoot = System.getenv("SystemRoot");
 String fileSeperator = System.getProperty("file.separator");
 FontFactory.registerDirectory(systemRoot + fileSeperator + "fonts");
}

这并不是说代码的作者忘记检查Windows7或Windows8,只是在编写代码时这些操作系统并不存在。正如您提到的,从那时起,iText就不再支持RTF了。不一定。iText 4.2.1于2013年7月发布()。该类与发行版捆绑在一起。Windows7和Windows8当时几乎已经存在。我猜它最终发布时没有经过测试。iText4.2.x是官方2.1.x分支的非官方分支。此分支中的最后一个版本2.1.7已过期。@BuhakeSindi您可能希望通知mvnrepository,它们承载由未知第三方修补的工件(在4.2.1的情况下)它可能包含也可能不包含对原始库的恶意更改。我想通知您,iText软件已声明Maven Central上com.lowagie的所有权,并且上载了一个iText 4.2.2 pom,该pom重定向到iText 5.x.x。因此,在pom.xml中将您的版本固定为2.1.7(或4.2.1,或您当前使用的任何版本)。无论如何,在pom.xml中有固定版本是maven的最佳实践。
|| (operatingSystem.indexOf("windows 7") > -1))
//1. delete method 'getEnvironmentVariables(...)' completely
//2. import system fonts like this:
private void importSystemFonts() {
 String systemRoot = System.getenv("SystemRoot");
 String fileSeperator = System.getProperty("file.separator");
 FontFactory.registerDirectory(systemRoot + fileSeperator + "fonts");
}