2015-04-02 85 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