我最近在现有应用程序中添加了一个fop pdf生成器。在本地一切正常,但当我部署到Azure上时,出现以下错误:
org.apache.fop.apps.FOPException: .fop (Access is denied)
java.io.FileNotFoundException: .fop (Access is denied)
我感到困惑的是,当fopfactory写入ByteOutputstream时似乎发生了异常,但我却收到文件访问错误。
捕获异常的函数是:
public static void GeneratePDF(string foFile, HttpContext context) {
StringBuilder sbDebug = new StringBuilder();
sbDebug.AppendLine("Start");
ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();
try
{
sbDebug.AppendLine("Got to 1");
com.sun.org.apache.xerces.@internal.jaxp.SAXParserFactoryImpl s = new com.sun.org.apache.xerces.@internal.jaxp.SAXParserFactoryImpl();
sbDebug.AppendLine("Got to 2");
FopFactory fopFactory = FopFactory.newInstance(new java.io.File(System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/Test.xconf")));
sbDebug.AppendLine("Got to 3 - file ").AppendLine(System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/Test.xconf"));
Fop fop = fopFactory.newFop("application/pdf", os);
sbDebug.AppendLine("Got to 4");
javax.xml.transform.TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer transformer = factory.newTransformer();
javax.xml.transform.Source src = new javax.xml.transform.stream.StreamSource(new java.io.StringReader(foFile));
javax.xml.transform.Result res = new javax.xml.transform.sax.SAXResult(fop.getDefaultHandler());
sbDebug.AppendLine("Got to 5");
transformer.transform(src, res);
context.Response.ContentType = "application/pdf";
context.Response.BinaryWrite(os.toByteArray());
//context.Response.BinaryWrite(System.Text.Encoding.UTF8.GetBytes(os.ToString()));
}
catch (Exception ex) {
throw new Exception(sbDebug.AppendLine(ex.ToString()).ToString());
}
finally {
os.close();
}
}
你可以看到,我添加了一些调试代码,因为我必须采用老式的调试方式来查看发生了什么。 这是输出结果:
Catch Error: System.Exception: Start
Got to 1
Got to 2
Got to 3 - file
D:\home\site\wwwroot\App_Data\Test.xconf
org.apache.fop.apps.FOPException: .fop (Access is denied)
java.io.FileNotFoundException: .fop (Access is denied)
所以我可以看到异常发生在这一行:
Fop fop = fopFactory.newFop("application/pdf", os);
我希望除了读取xconf文件的部分,所有操作都在内存中进行。 更新 21/02/2017 我已经验证xconf文件存在于正确的位置。
string curFile = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/Test.xconf");
if (System.IO.File.Exists(curFile)) //Used System.IO prefix as without it compiler complains of ambiguity with java.io
{
sbDebug.AppendLine("Got to 3a - file found");
}
else
{
sbDebug.AppendLine("Got to 3a - file NOT found");
}
同时,它也可以使用以下方式进行阅读。
BufferedReader br = new BufferedReader(new FileReader(curFile));
sbDebug.AppendLine("Got to 3b");
String sJIObrOut = br.readLine();
sbDebug.AppendLine("Got to 3c");
while ((sJIObrOut = br.readLine()) != null)
{
sbDebug.Append("3d: ").AppendLine(sJIObrOut);
}
这表明fopfactory试图访问不同的文件,但我无法找出是哪个文件。
非常感谢任何帮助。
更新2 22/3/17 我在Azure云服务上没有成功,所以决定构建一个本地Web应用程序,仅将xslfo文档转换为pdf并将其作为Web服务运行。 这在本地完美运行,因此将该服务发布到我们为其他客户使用的服务器上。 这不起作用,我得到与原始帖子完全相同的错误。 这意味着不是Azure的问题 - 是否有任何其他想法?
/home/USER/.fop
下,其中USER是tomcat运行的用户。因此,我推测FOP希望在Windows的C:\Users\USER\AppData\Local
某处创建此文件,但这可能在Azure上不被允许。我是一个Linux人,所以我不确定,但也许这会有所帮助。 - mondjunge