2015-04-02 84 views
1

這是我第一次使用BIRT引擎。我專注於使用POJO的問題。BIRT在tomcat下使用POJOs的報告

我有簡單的POJO:

class Parent { 
    private String name; 
    public void setName(String name) { 
    this.name = name; 
    } 

    public String getName() { 
    return name; 
    } 
} 

而且簡單的BIRT報告,該報告只打印父母的名字(我只爲1個父打印的名字,它的意思 - 我送一個列表只有1條)。

我使用JUnit測試成功生成帶有父名稱的PDF,而當我嘗試在Tomcat中生成它時--BIRT不插入POJO的值。

你有沒有專注於這個問題?

伯特包裝類:

public class BirtRenderer implements IBirtRenderer { 

    private EngineConfig config; 
    private IReportEngine engine; 
    private IReportEngineFactory factory; 

    public BirtRenderer() throws BirtException { 
     config = new EngineConfig(); 
     config.setLogConfig("J:\\BirtLogs", Level.WARNING); 

     // config.setLogger(new Log4jHandler()); 

     Platform.startup(config); 

     factory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY); 
     engine = factory.createReportEngine(config); 
    } 

    public void destroy() { 
     engine.destroy(); 
     Platform.shutdown(); 
    } 

    public ByteArrayOutputStream executeReport(String reportName, String fileFormat, @SuppressWarnings("rawtypes") Map context) throws EngineException { 
     return executeReport(reportName, fileFormat, context, Locale.US); 
    } 

    public ByteArrayOutputStream executeReport(String reportName, String fileFormat, @SuppressWarnings("rawtypes") Map context, Locale locale) throws EngineException { 

     ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

     reportName = reportName + ".rptdesign"; 

     /* for testing */ 
     context = new HashMap(); 
     ArrayList list = new ArrayList(); 
     list.add(new TitleCustomerDao().next()); 
     context.put("APP_CONTEXT_KEY_TITLE_CUSTOMER_DATA", list); 
     /* for testing end */ 

     InputStream reportStream = this.getClass().getClassLoader().getResourceAsStream(reportName); 

     if (reportStream == null) 
      throw new EngineException(new BirtException("File '" + reportName + "' was not found.")); 

     // Open the report design 
     IReportRunnable design = null; 
     // design = 
     // engine.openReportDesign("J:/birt-workspace/test/hello_world.rptdesign"); 
     design = engine.openReportDesign(reportStream); 
     IRunAndRenderTask task = engine.createRunAndRenderTask(design); 
     // task.setParameterValue("Top Count", (new Integer(5))); 
     // task.validateParameters(); 

     RenderOption renderOption = getRenderOption(fileFormat); 
     renderOption.setOutputStream(outputStream); 

     task.setRenderOption(renderOption); 
     // task.setParameterValue("APP_CONTEXT_KEY_PARENTS", data); 
     task.setAppContext(context); 
     if (locale != null) 
      task.setLocale(locale); 

     if (!task.validateParameters()) { 
      throw new IllegalArgumentException("Parameters do not validate"); 
     } 

     task.run(); 
     task.close(); 

     return outputStream; 
    } 

    private RenderOption getRenderOption(String fileFormat) { 
     if (fileFormat.equalsIgnoreCase("pdf")) { 
      PDFRenderOption PDF_OPTIONS = new PDFRenderOption(); 
      // PDF_OPTIONS.setOutputFileName("J:/birt-workspace/test/hello_world.pdf"); 
      PDF_OPTIONS.setOutputFormat("pdf"); 

      return PDF_OPTIONS; 
     } else if (fileFormat.equalsIgnoreCase("html")) { 
      HTMLRenderOption HTML_OPTIONS = new HTMLRenderOption(); 
      // HTML_OPTIONS.setOutputFileName("J:/birt-workspace/test/hello_world.html"); 
      HTML_OPTIONS.setOutputFormat("html"); 

      return HTML_OPTIONS; 
     } else 
      return null; 

    } 

} 

經過長時間的調查,我發現問題出在哪裏。

問題是我在同一個Web項目中使用Apache FOP庫,我使用BIRT。 如果我們將詳細討論 - 問題出在Apache Bapt庫,它被Apache FOP 1.0使用(使用> = 1.7 Batik)& BIRT 4.4.2(使用1.6)。

真的很奇怪爲什麼BIRT Runtime Java庫會覆蓋Batik groupIds和artifacts。

你有什麼建議如何使用Apache FOP & BIRT 4.4.2運行時Java庫在同一個Web項目中?

它也取決於,您指定哪個依賴關係頂部。

使用這個pom.xml的PDF報告成功生成和所有POJO數據正確綁定:

<dependency> 
<groupId>org.eclipse.birt.runtime</groupId> 
<artifactId>org.eclipse.birt.runtime</artifactId> 
<version>4.4.2</version> 
</dependency> 

<dependency> 
<groupId>org.apache.xmlgraphics</groupId> 
<artifactId>fop</artifactId> 
<version>1.0</version> 
</dependency> 

<dependency> 
<groupId>junit</groupId> 
<artifactId>junit</artifactId> 
<version>4.12</version> 
<scope>test</scope> 
</dependency> 

使用這個pom.xml的PDF報告呈現空POJO數據字段:

 <dependency> 
     <groupId>org.apache.xmlgraphics</groupId> 
     <artifactId>fop</artifactId> 
     <version>1.0</version> 
    </dependency> 

    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.12</version> 
     <scope>test</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.eclipse.birt.runtime</groupId> 
     <artifactId>org.eclipse.birt.runtime</artifactId> 
     <version>4.4.2</version> 
    </dependency> 
+0

這很可能是一個類路徑問題,你在哪裏把包含這個pojo的jar放在Tomcat中?運行報表的代碼在哪裏:它是否與birt引擎位於同一個Web應用程序中或位於單獨的Web應用程序中? – Dominique 2015-04-02 12:38:35

+0

這個POJO&BIRT引擎包裝jar(用於創建引擎並配置它)進入WEB-INF \ lib forlder。數據來自控制器,這些控制器放置在WEB-INF \ classes中。 – xsiraul 2015-04-03 05:37:16

+0

你能展示創建和配置BIRT引擎的代碼嗎?我想我知道爲什麼它不起作用,但我想確保 – Dominique 2015-04-03 09:31:14

回答

0

好吧,我發現了一個問題。

問題出在Java庫上。 Apache FOP使用Apache Batik,它有一個artifact batik-js。這是一個瓶頸,因爲BIRT運行時庫使用更新的版本。

很難找到問題,因爲BIRT Runtime使用「org.mozilla.javascript-1.7.2.jar」,而FOP使用「batik-js-1.7.jar」。它們都存儲相同的Java類。

因此,當我們指定FOP對TOP的依賴關係時,Java ClassLoader使用舊版本(FOP版本)的jar。

這仍然是一個問題 - 爲什麼BIRT Runtime開發人員使用相同的Java類創建了不同的Maven工件。

所以我的新pom.xml的是:

<dependency> 
     <groupId>org.apache.xmlgraphics</groupId> 
     <artifactId>fop</artifactId> 
     <version>1.0</version> 
     <exclusions> 
      <exclusion> 
       <artifactId>batik-js</artifactId> 
       <groupId>org.apache.xmlgraphics</groupId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

    <dependency> 
     <groupId>org.eclipse.birt.runtime</groupId> 
     <artifactId>org.eclipse.birt.runtime</artifactId> 
     <version>4.4.2</version> 
    </dependency> 

和一切正常吧!

0

我認爲你的POJO在Tomcat中不起作用,因爲你忘記了爲BIRT引擎提供一個類加載器。嘗試添加此:

import org.eclipse.birt.report.engine.api.EngineConstants; 

,並在構造函數:

config.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, BirtRenderer.class.getClassLoader()); 
+0

我很抱歉地注意到你,但它沒有任何效果。我嘗試了很多不同的選擇,我也嘗試將類加載器添加到executeReport方法的上下文中。它不能解決問題。 – xsiraul 2015-04-03 12:02:53

+0

birt引擎的日誌怎麼樣,有什麼線索嗎? – Dominique 2015-04-03 12:33:06

+0

BIRT日誌文件在WARNING級別爲空。 – xsiraul 2015-04-03 12:35:54