使用xsl将xml转换为pdf时,我遇到了一个奇怪的问题(java代码创建xml并在运行时应用xsl)。
代码部署在Jboss服务器上。执行代码时,它会因以下错误而失败
10:50:49,068 ERROR [stderr] (http--0.0.0.0-9080-3) Caused by: java.lang.reflect.InvocationTargetException
10:50:49,068 ERROR [stderr] (http--0.0.0.0-9080-3) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
10:50:49,069 ERROR [stderr] (http--0.0.0.0-9080-3) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
....
10:50:49,070 ERROR [stderr] (http--0.0.0.0-9080-3) Caused by: java.lang.StackOverflowError
10:50:49,070 ERROR [stderr] (http--0.0.0.0-9080-3) at sun.misc.FloatingDecimal.dtoa(FloatingDecimal.java:532)
10:50:49,070 ERROR [stderr] (http--0.0.0.0-9080-3) at sun.misc.FloatingDecimal.<init>(FloatingDecimal.java:459)
以下是相关的Java代码
public String transformWOCFormToPDF(IDfId xmlId,String folderId,String userName)throws DfException {
System.out.println("Preparing...");
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date date= new Date();
prop=readProperties();
IDfSysObject pdfObject = (IDfSysObject)session.newObject("jh_exported_doc");
System.out.println("object created");
ByteArrayOutputStream pdfResult = new ByteArrayOutputStream();
try {
System.out.println("in try");
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF,foUserAgent, pdfResult);
System.out.println("fop object created");
// Get the XSLT object from the docbase
IDfId objID = (IDfId) session.getIdByQualification("dm_document where object_name='"+ FORM_XSLT_OBJ_NAME + "'");
System.out.println("Object ID created "+objID.getId());
IDfSysObject xsltObj = (IDfSysObject) session.getObject(objID);
// Get XSLT content as a stream
Source xsltSrc = new StreamSource(xsltObj.getContent());
System.out.println("xsltSrc is -- "+xsltSrc.toString());
// Create a new transformer for this style sheet
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsltSrc);
transformer.setParameter("versionParam", "1.0");
IDfSysObject xmlObject = (IDfSysObject) session.getObject(xmlId);
// Get xml content as a stream
Source xmlSrc = new StreamSource(xmlObject.getContent());
System.out.println("Fetched xml source "+xmlSrc.toString());
// Setup input for XSLT transformation
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
System.out.println("res is -- "+res.toString());
// Start XSLT transformation and FOP processing
transformer.transform(xmlSrc, res);
System.out.println("size of pdf"+pdfResult.size());
//IDfSysObject pdfObject = (IDfSysObject)session.newObject("dm_document");
System.out.println("object created");
pdfObject.setObjectName(FORM_PDF_OBJ_NAME+"_"+dateFormat.format(date)+"_"+userName);
pdfObject.setContentType("pdf");
pdfObject.setContent(pdfResult);
System.out.println("setting content");
pdfObject.link(folderId);
pdfObject.save();
System.out.println("path is "+pdfObject.getObjectId().toString());
} catch (Exception e) {
System.out.println("Inside catch block");
e.printStackTrace();
} finally {
try {
pdfResult.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return pdfObject.getObjectId().getId();
}
似乎错误即将来临,因为println在此之前正在打印
transformer.transform(xmlSrc, res);
下面是xml。尽管这是动态生成的,但我已将其从日志中复制并放在此处以供参考。附件也是xslt。
<WOC_Form>
<Evaluators>
<Evaluators>
<department>Clinical Research</department>
<evaluator_name>DISPNAME hod_clinicalres_user1</evaluator_name>
<status>Accepted</status>
<vested_interest>no</vested_interest>
<doi_approver>N/A</doi_approver>
</Evaluators>
<Evaluators>
<department>Allied Health Administration</department>
<evaluator_name>DISPNAME hod_aha_user1</evaluator_name>
<status>Accepted</status>
<vested_interest>no</vested_interest>
<doi_approver>N/A</doi_approver>
</Evaluators>
</Evaluators>
<Attachments>
<Attachments>
<object_name>WOC_18-06-2015_hod_fammed_user1.pdf</object_name>
<owner_name>DISPNAME woc_req_user1</owner_name>
<r_creation_date>7/24/2015 11:58:09 AM</r_creation_date>
</Attachments>
<Attachments>
<object_name>xCP 2.1 Sample Application - ICM 2.1.0.pdf</object_name>
<owner_name>DISPNAME woc_buyer_user1</owner_name>
<r_creation_date>7/24/2015 12:03:30 PM</r_creation_date>
</Attachments>
</Attachments>
<requesting_department>Allied Health Administration</requesting_department>
<institutions>
<institutions-value index="0">JH</institutions-value>
<institutions-value index="1">JC</institutions-value>
<institutions-value index="2">JR</institutions-value>
</institutions>
<vendoe_for_woc>erferewr</vendoe_for_woc>
<dh_ch_requesting_dept>DISPNAME hod_aha_user1</dh_ch_requesting_dept>
<total_waiver_of_competition>4433</total_waiver_of_competition>
<specialist_dept/>
<specialist_name/>
<is_approved_by_specialist>0</is_approved_by_specialist>
<description_of_goods_servic>dsfdsf</description_of_goods_servic>
<background>sdf</background>
<req_of_goods_or_services>sdfds</req_of_goods_or_services>
<proposals_from_vendors>sfdsf</proposals_from_vendors>
<negotiations_and_bafo>sdfsd</negotiations_and_bafo>
<calculation_of_contract_sum>ret</calculation_of_contract_sum>
<contract_period>ewte</contract_period>
<reason_request1>0</reason_request1>
<reason_request2>0</reason_request2>
<reason_request3>0</reason_request3>
<reason_request4>0</reason_request4>
<reason_request5>0</reason_request5>
<reason_request6>1</reason_request6>
<reason_request7>0</reason_request7>
<reason_request8>0</reason_request8>
<dh_ch_requesting_dept>DISPNAME hod_aha_user1</dh_ch_requesting_dept>
<dh_ch_approval_time>7/24/2015 12:00:50 PM</dh_ch_approval_time>
<specialist_name/>
<specialist_approval_time>nulldate</specialist_approval_time>
<mmd_manager_name>DISPNAME woc_mmd_mgr_user1</mmd_manager_name>
<mmd_mgr_approval_time>7/24/2015 12:07:09 PM</mmd_mgr_approval_time>
<finance_controller_name/>
<finance_controller_approval>nulldate</finance_controller_approval>
奇怪的是,整个事情在2台服务器(VM)上工作正常但在另外2台服务器(VM)上出现上述错误(每台服务器都是安装了Jboss的独立虚拟机)。所有虚拟机都是Windows,并且具有完全相同的Jboss配置。
我做了一些谷歌搜索,发现了这个问题的几个潜在原因。一个原因可能是xslt中的一些递归调用导致stackoverflow错误。但是,为什么转换在其他两个VM中起作用没有意义。但是有可能导致这种递归行为的测试数据(我无法捕获)存在差异。我在这里链接了xsl,以防论坛中的xslt专家注意到xsl出现了严重错误。
http://filedb.experts-exchange.com/incoming/2015/08_w32/927711/WOCFormXSLT.xsl
我发现的第二个潜在原因是可能没有足够的Java内存分配。部署此代码的Jboss具有以下内存参数
set USER_MEM_ARGS=-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -Xss256k -XX:+DisableExplicitGC -Xrs
设置JAVA_OPTS =%USER_MEM_ARGS%-Djboss.server.base.dir =%JBOSS_BASE_DIR%-Duser.name = dmadmin
我尝试将-Xss从256k增加到1024k和2048k,但它没有帮助
set USER_MEM_ARGS=-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -Xss1024k -XX:+DisableExplicitGC -Xrs
设置JAVA_OPTS =%USER_MEM_ARGS%-Djboss.server.base.dir =%JBOSS_BASE_DIR%-Duser.name = dmadmin
我只是创建了一个2页的pdf,所以它不应该需要更多的内容。此外,代码正在运行的VM,它使用默认设置,即-Xss256k。
这些VM是同一VM的克隆,因此具有完全相同的Java和Jboss版本(和设置)。我无法弄清楚可能是什么问题。它可能是与环境或与xslt代码相关的东西吗?
任何帮助都会受到高度赞赏,因为我真的碰壁了。
谢谢
答案 0 :(得分:1)
堆栈跟踪在FOP中显示堆栈溢出错误:
org.apache.fop.fo.flow.table.TableColumn.toString calling
org.apache.fop.fo.properties.PercentLength.toString(PercentLength.java:121) calling
org.apache.fop.datatypes.LengthBase.toString calling TableColumn toString
这是FOP内部错误的明显标志。
这是一个bug report报告相同的错误并提到修补版本的FOP,消除了错误。你可以检查你的四台服务器 - 即使它们都是同一个VM的克隆 - 如果它们真的都运行相同版本的FOP吗?