Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY) returning null i

Hi,


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);



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;
}

I'm using the version  4.4.2



<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>

I saw other posts talking about setting BIRTHome like:


config.setBIRTHome( "C:/Program Files/birt-runtime-2_6_0/ReportEngine" );


 


but I really don't get this, my application is a war, so should I add my jar [org.eclipse.birt.runtime-4.4.2.jar] to a folder inside my app and then add it to my Java Build Path ?


 


I appreciate any help or suggestion


 


 


Comments

  • edited June 26, 2017

    Before using the API to create the factory, call the startup() method on Platform.



    // 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();

    There is generally one instance of the ReportEngine for the application i.e. the engine is application-scoped.


    There is no need to use EngineConfig#setBIRTHome().


  • edited July 6, 2017

    Thanks @Zorawar for replying,

    Actually I call the methode startup() before createFactoryObbject() method using the next code, but it doesn't work :(


     




            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)

            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultLis                                                                                                                          tableBeanFactory.java:759)

            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractA                                                                                                                          pplicationContext.java:866)

            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:5                                                                                                                          42)

            at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationCo                                                                                                                          ntext.java:122)

            at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)

            at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)

            at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)

            at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:                                                                                                                          151)

            at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBoo                                                                                                                          tServletInitializer.java:131)

            at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer                                                                                                                          .java:86)

            at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.ja                                                                                                                          va:169)

            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5244)

            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)

            ... 6 more

    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

            at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStr                                                                                                                          ategy.java:189)

            at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorR                                                                                                                          esolver.java:588)

            ... 27 more

    Caused by: java.lang.NullPointerException

            at com.mmm.mmm.birt.BirtPlatformListener.getReportEngine(BirtPlatformListener.java:84)

            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

            at java.lang.reflect.Method.invoke(Method.java:498)

            at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStr  


    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;
    }

  • I'm using the version 4.4.2 so I've tried this solution but it did not work either, the methode below returns null 



    Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
  • the string below is 


    IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY  = "org.eclipse.birt.report.engine.ReportEngineFactory"


     


    but in the birt_runtime jar this class doesn't exist so I tried replacing it by the actual ReportEngineFactory.class path that I actually have, this way: "org.eclipse.birt.report.engine.api.impl.ReportEngineFactory" but I still getting the same null result.


     


    any suggestion please?


  • edited July 7, 2017

    How is the private EngineConfig field set?


    It seems to me that it is null at the point where Platform#startup() method is called.


    Try creating the EngineConfig instance before invoking the startup() method. 


    For a test, you could also use the Platform#.startup() method that takes no parameter and see if the ReportEngine instance is created. 


     


    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).


     


     


    Also, the code below refers to an extension id. It is not the qualified name of a class. 



    IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY  = "org.eclipse.birt.report.engine.ReportEngineFactory"

    https://wiki.eclipse.org/FAQ_What_are_extensions_and_extension_points%3F


     


     


     


    P.S. The TGV is a very good ride :-)


  • Hey @Zorawar! thanks for replying,


     


    My EngineConfig is set correctly, in fact the problem  is the same as this post, however, the last answer doesn't make sense with my configuration, I don't have any "platform" folder within my Web-Inf folde...


     


    Digging a bit in debug mode showed that the ExtensionRegistry is empty, and I don't get how we can configure that. 


     


    Any ideas on this ? 


  • Hi, I am curious why it behaves that way in Spring boot context.


    It would be interesting for me to recreate it in a simple boot app.


    I will post if I find something.


  • edited August 4, 2017

    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.



    # 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

    After the application comes up, open browser and navigate to localhost:8080/version. Everything works.


     


    There must be something specific to your project setup that creates the problem for BIRT to startup.


    What kind of listener is the class BirtPlatformListener? I would suggest to check how the application starts up in your situation.


     


    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.


     


    Edit: 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.



    // imports...

    @Component
    @Scope("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();
    }
    }

    Use constructor injection, if you want the ServletContext dependency injected for a war application.


    If I get the the time I'll upload a proper example Spring Boot application to github.


Sign In or Register to comment.