2017-02-20 8 views
1

Я недавно добавил fop pdf-генератор в существующее приложение. все отлично работает локально, но когда я раскрываю жить на Azure я получаю следующие ошибки:org.apache.fop.apps.FOPException: .fop (Доступ запрещен) в 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"); 
      [email protected] s = new [email protected](); 
      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 файл, где он должен быть.

Update 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 пытается получить доступ к другому файлу, но я не могу понять, что.

Любая помощь с благодарностью получена.

UPDATE 2 22/3/17 Я не имел никакого успеха с услугами Azure Cloud так решили построить локальный веб-приложение, чтобы просто преобразовать xslfo документ в формате PDF и запустить его в качестве веб-службы. Это работает отлично локально, поэтому опубликована служба на сервере, который мы используем для других клиентов. Это не работает, и я получаю точно такую ​​же ошибку, как и исходное сообщение. Это означает, что это не проблема Azure - есть ли у кого-нибудь другие идеи?

+1

В моей Linux-системе .fop используется для хранения файлов кеша lik e font-cache. Он находится под '/ home/USER/.fop', где USER является пользователем tomcat. Поэтому я предполагаю, что FOP хочет создать этот файл где-нибудь под 'C: \ Users \ USER \ AppData \ Local' в Windows, что может быть запрещено с Azure. Я парень Linux, поэтому я не знаю точно, но, возможно, он помогает, тем не менее, – mondjunge

ответ

0

Очень большое спасибо @mondjunge за то, что указали мне в правильном направлении. Теперь у меня есть решение, которое работает за пределами Azure. Со временем я надеюсь, что это будет то, что я могу применить к Azure напрямую, и я добавлю к этому сообщению соответственно.

Кажется, что запись в кэш что вызывает проблему (разрешения).

Обходной путь/исправление, которое я реализовал, состоит в том, чтобы добавить следующую строку в файл xconf (я положил ее непосредственно перед тегом закрытия/fop, но не думаю, что это имеет значение, если это прямой дочерний узел fop)

<use-cache>false</use-cache> 

Надеется, что это спасает кто-то еще дни хлопот и стресса

Update 7/4/17

из интереса я попробовал добавить эту строку в чистой лазурь принимала версию, и она не дольше дал мне ошибку с разрешениями, вместо этого он дал мне ошибку о GDI, которая, вероятно, совпадает с тем, что изначально предлагал @PeterPan. Поскольку у меня есть рабочая версия приложения fop, размещенного в другом месте, я собираюсь оставить его на этом.

0

Я исследовал для Apache FOP, я обнаружил, что функция генерации PDF основана на Java AWT, которая использует по умолчанию DirectDraw/GDI Pipeline в ОС Windows. Однако, согласно wiki-странице kudu Azure Web App sandbox, вы можете получить информацию об ограничениях для GDI через поиск по ключевому слову GDI. Как правило, обходным путем является использование библиотеки без GDI, но, похоже, что почти все библиотеки Java для обработки изображений зависели от AWT.

Помимо использования служб Azure Cloud или виртуальной машины, вы не можете создавать PDF-файлы в Azure App Services, которые включают WebApps.

+0

fop pdfgenrator, который я использую сейчас (crispin.fop), является заменой для fonet, который является очень старым .NET-портом apache FOP и заменен из-за отсутствия поддержки многих функций xsl: fo. Это решение отлично работало на Azure для создания PDF-файлов - есть ли у вас какие-либо идеи, почему это работает, а это не так? – RT72

+0

Как насчет запуска этого приложения в Linux? Я знаю, что это в предварительном просмотре, но, возможно, это жизнеспособный подход к будущему? –

+0

Глядя на исходную ошибку, которую я опубликовал, я не уверен, что мы даже достигли стадии, когда будет задействован GDI. Я далек от эксперта по этому вопросу, но я бы ожидал, что материал GDI не произойдет до тех пор, пока трансформатор не будет инициирован/вызван, что произойдет после того, как исключение будет выброшено - согласны ли вы? – RT72

1

ApacheFOP создаст локальный файл .Fop (папка) в прогоне frist и внутри этой папки будет создан файл cache-fonts.cache (этот файл кэша для производительности, если вы хотите определить какой-либо другой шрифт-arial, который не поддерживаются Apache FOP и много чего другого). , если вы заходите в свой пользователь Windows, вы найдете эту папку .fop В любом случае, я думаю, что azure не разрешает apache fop создавать эту .fop-папку на сервере для создания внутри этого .fop файла fop-cache.cache file

Я потратил некоторое время, чтобы получить решение! вот решение для моей проблемы (оно работает на Windows Server) Шаги: 1- вы определяете путь, где fop-fonts.cache 2- вам нужно адаптировать путь с файлом кэша 3- set путь к кэшу, где будет создан фат-fonts.cache

код:

// create just Fop folder and inside this a Cache FOP Folder on your 
    // project 
    // Tipp: you could read it from config 
    // fop-fonts.cache have to be created automaticly, if it is running good 
    string fopcacheFilePath = "~/Fop/Cache Fop/fop-fonts.cache"; 

    fopcacheFilePath = fopcacheFilePath.Replace("\\","/"); 
    fopcacheFilePath = "file:///" + fopcacheFilePath; 
    fopcacheFilePath = fopcacheFilePath.Replace(" ", "%20"); 
    //in your case you have to set fopcacheFilePath 
    fopFactory.getFontManager().setCacheFile(new URI(fopcacheFilePath)) 

, если этот код был запущен без проблем, то вы должны найти ФОП-fonts.cache в вашем projectfolder

+0

Спасибо @Moe - я собираюсь оставить это на данный момент, так как у меня есть нужные шрифты и рабочее решение. Я могу попробовать ваше предложение, если возникнет необходимость в наличии других шрифтов – RT72

 Смежные вопросы

  • Нет связанных вопросов^_^