Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY) returning null i

Axel00
edited February 11, 2022 in Analytics #1
<p>Hi,<br><br>
When I run this code on my application on local, the factory get returned and everything works well, but on unix environment I get a null from the method Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);</p>
<pre class="_prettyXprint">
public IReportEngine getReportEngine() {
if (reportEngine == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Eclipse BIRT : création d'une nouvelle instance de ReportEngine.");
}

IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);

reportEngine = factory.createReportEngine(engineConfig);
}

return reportEngine;
}
</pre>
<p>I'm using the version  4.4.2</p>
<pre class="_prettyXprint _lang-xml">
<version.birt>4.4.2</version.birt>

<dependency>
<groupId>org.eclipse.birt.runtime</groupId>
<artifactId>org.eclipse.birt.runtime</artifactId>
<version>${version.birt}</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.birt.runtime</groupId>
<artifactId>org.eclipse.orbit.mongodb</artifactId>
</exclusion>
</exclusions>
</dependency>
</pre>
<p>I saw other posts talking about setting BIRTHome like:</p>
<p>config.setBIRTHome( "C:/Program Files/birt-runtime-2_6_0/ReportEngine" );</p>
<p> </p>
<p>but I really don't get this, my application is a war, so should I add my jar <span style="background-color:rgb(232,202,202);">[</span>org.eclipse.birt.runtime-4.4.2.jar] to a folder inside my app and then add it to my Java Build Path ?</p>
<p> </p>
<p>I appreciate any help or suggestion</p>
<p> </p>
<p> </p>

Comments

  • Zorawar
    edited June 26, 2017 #2
    <p>Before using the API to create the factory, call the startup() method on Platform.</p>
    <pre class="_prettyXprint">
    // construction of application-scoped instance
    Platform.startup();
    IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject(...);
    engine = factory.createReportEngine(...);

    // later when application is shutting down or component won't service anymore
    engine.destroy();
    Platform.shutdown();
    </pre>
    <p>There is generally one instance of the ReportEngine for the application i.e. the engine is application-scoped.</p>
    <p>There is no need to use<span style="font-family:'courier new', courier, monospace;"> EngineConfig#setBIRTHome()</span>.</p>
  • Axel00
    edited July 6, 2017 #3
    <p>Thanks @Zorawar for replying,<br>
    Actually I call the methode startup() before createFactoryObbject() method using the next code, but it doesn't work :(</p>
    <p> </p>
    <p>
    </p>
    <div>        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)</div>
    <div>        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)</div>
    <div>        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultLis                                                                                                                          tableBeanFactory.java:759)</div>
    <div>        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractA                                                                                                                          pplicationContext.java:866)</div>
    <div>        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:5                                                                                                                          42)</div>
    <div>        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationCo                                                                                                                          ntext.java:122)</div>
    <div>        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)</div>
    <div>        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)</div>
    <div>        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)</div>
    <div>        at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:                                                                                                                          151)</div>
    <div>        at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBoo                                                                                                                          tServletInitializer.java:131)</div>
    <div>        at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer                                                                                                                          .java:86)</div>
    <div>        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.ja                                                                                                                          va:169)</div>
    <div>        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5244)</div>
    <div>        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)</div>
    <div>        ... 6 more</div>
    <div>Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.eclipse.birt.report.eng                                                                                                                          ine.api.IReportEngine]: Factory method 'getReportEngine' threw exception; nested exception is java.lang.NullPointer                                                                                                                          Exception</div>
    <div>        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStr                                                                                                                          ategy.java:189)</div>
    <div>        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorR                                                                                                                          esolver.java:588)</div>
    <div>        ... 27 more</div>
    <div>Caused by: java.lang.NullPointerException</div>
    <div>        at com.mmm.mmm.birt.BirtPlatformListener.getReportEngine(BirtPlatformListener.java:84)</div>
    <div>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)</div>
    <div>        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)</div>
    <div>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)</div>
    <div>        at java.lang.reflect.Method.invoke(Method.java:498)</div>
    <div>        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStr  </div>
    <pre class="_prettyXprint _lang-js">
    private EngineConfig engineConfig;
    private IReportEngine reportEngine;

    public void start() {
    if (LOG.isDebugEnabled()) {
    LOG.debug("Eclipse BIRT : démarrage de la plateforme");
    }
    try {
    Platform.startup(engineConfig);
    } catch (BirtException be) {
    throw new IllegalArgumentException("Eclipse BIRT : Erreur lors du démarrage de la plateforme.", be);
    }
    }


    public IReportEngine getReportEngine() {
    if (reportEngine == null) {
    if (LOG.isDebugEnabled()) {
    LOG.debug("Eclipse BIRT : création d'une nouvelle instance de ReportEngine.");
    }
    try {
    Platform.startup(engineConfig);
    } catch (BirtException e) {
    e.printStackTrace();
    }
    IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
    reportEngine = factory.createReportEngine(engineConfig);
    }
    return reportEngine;
    }
    </pre>
  • <p>I'm using the version 4.4.2 so I've tried <a data-ipb='nomediaparse' href='http://developer.actuate.com/community/forum/index.php?/topic/39115-using-birt-with-maven/'>this solution</a> but it did not work either, the methode below returns <strong>null </strong></p>
    <pre class="_prettyXprint _lang-">
    Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
    </pre>
  • <p>the string below is </p>
    <p><span style="color:rgb(102,0,102);">IReportEngineFactory</span><span style="color:rgb(102,102,0);">.</span><span>EXTENSION_REPORT_ENGINE_FACTORY  = "</span><span>org.eclipse.birt.report.engine.ReportEngineFactory"</span></p>
    <p> </p>
    <p><span>but in the birt_runtime jar this class doesn't exist so I tried replacing it by the actual </span><span>ReportEngineFactory.class path that I actually have, this way: "</span><span style="color:#0000ff;">org.eclipse.birt.report.engine.api.impl.ReportEngineFactory</span><span>" but I still getting the same null result.</span></p>
    <p> </p>
    <p><span>any suggestion please?</span></p>
  • Zorawar
    edited July 7, 2017 #6
    <p>How is the private EngineConfig field set?</p>
    <p>It seems to me that it is null at the point where Platform#startup() method is called.</p>
    <p>Try creating the EngineConfig instance before invoking the startup() method. </p>
    <p>For a test, you could also use the Platform#.startup() method that takes no parameter and see if the ReportEngine instance is created. </p>
    <p> </p>
    <p>If what I suggest does not work, could you share some more details of the project setup and the complete BirtPlatformListener class (of course without your company information).</p>
    <p> </p>
    <p> </p>
    <p>Also, the code below refers to an extension id. It is not the qualified name of a class. </p>
    <pre class="_prettyXprint">
    IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY  = "org.eclipse.birt.report.engine.ReportEngineFactory"</pre>
    <p><a data-ipb='nomediaparse' href='https://wiki.eclipse.org/FAQ_What_are_extensions_and_extension_points?'&gt;https://wiki.eclipse.org/FAQ_What_are_extensions_and_extension_points?&lt;/a&gt;&lt;/p&gt;
    <p> </p>
    <p> </p>
    <p> </p>
    <p><span style="font-size:10px;">P.S. The TGV is a very good ride :-)</span></p>
  • <p>Hey @Zorawar! thanks for replying,</p>
    <p> </p>
    <p>My EngineConfig is set correctly, in fact the problem  is the same as this <a data-ipb='nomediaparse' href='http://developer.actuate.com/community/forum/index.php?/topic/24242-help-to-fix-the-error-in-creating-birtengine/#entry91995'>post</a>, however, the last answer doesn't make sense with my configuration, I don't have any "platform" folder within my Web-Inf folde...</p>
    <p> </p>
    <p>Digging a bit in debug mode showed that the ExtensionRegistry is empty, and I don't get how we can configure that. </p>
    <p> </p>
    <p>Any ideas on this ? </p>
  • <p>Hi, I am curious why it behaves that way in Spring boot context.</p>
    <p>It would be interesting for me to recreate it in a simple boot app.</p>
    <p>I will post if I find something.</p>
  • Zorawar
    edited August 4, 2017 #9
    <p>Hi, I created a simple Spring boot application that starts up the Platform and then successfully creates the IReportEngine instance. That instance is later on used via a rest resource to output its version. The code uses a ServletContextListener implementation to detect context initialization and bring up the BIRT platform, and context dispose when application is brought down to shutdown the BIRT platform. The EngineService implementation contains the internals to create instance of IReportEngine. See the attached the example project and the request/response.</p>
    <pre class="_prettyXprint">
    # extract the example project zip file and navigate under it
    $ cd boot-report
    # clean and package
    boot-report$ ./mvnw clean
    boot-report$ ./mvnw package
    # start the application
    boot-report$ java -jar target/boot-report-0.0.1-SNAPSHOT.war
    </pre>
    <p>After the application comes up, open browser and navigate to localhost:8080/version. Everything works.</p>
    <p> </p>
    <p>There must be something specific to your project setup that creates the problem for BIRT to startup.</p>
    <p>What kind of listener is the class BirtPlatformListener? I would suggest to check how the application starts up in your situation.</p>
    <p> </p>
    <p>Instead of the ServletContextListener it would be also possible to use @PostConstruct and @PreDestroy annotations to startup and shutdown the Platform. That would make the code simpler.</p>
    <p> </p>
    <p><em><strong>Edit</strong></em>: Using the ServletContextListener seems to be a not so good approach, especially in the context of using Spring Boot. To keep things simple, consider a EngineFactory implementation that is a Spring singleton that brings up the platform. In a Spring Boot application this will be automatically instantiated.</p>
    <pre class="_prettyXprint">
    // imports...

    @Component
    @Scope(&quot;singleton")
    public class AppEngineFactory implements EngineFactory {
    private static final Logger log = LoggerFactory.getLogger(MyEngineFactory.class);

    private IReportEngineFactory factory;

    @PostConstruct
    public void startup() {
    try {
    Platform.startup();
    factory = (IReportEngineFactory) Platform
    .createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
    } catch(BirtException e) {
    log.error("error starting platform", e);
    }
    }

    /* Implements EngineFactory#createEngine. */
    @Override
    public IReportEngine createEngine() {
    EngineConfig config = new EngineConfig();
    // setup config...
    return factory.createReportEngine(config);
    }

    @PreDestroy
    public void shutdown() {
    Platform.shutdown();
    }
    }
    </pre>
    <p>Use constructor injection, if you want the ServletContext dependency injected for a war application.</p>
    <p>If I get the the time I'll upload a proper example Spring Boot application to github.</p>