1
votes

I am deploying a web services on WSO2 Application Server 5.2.1 which loads a reportDesign from a database table and renders a PDF stream, which is then stored as a file in an outgoing ftp server directory. All works well when running from the command line, but I am having a hard time configuring the EngineConfig's EngineHome property in when deploying on WSO2 AS 5.2.1.

My pom.xml file (for Maven) embeds Birt 4.4.1 runtime in my aar file, which is then deployed as part of a larger car file. Birt jar files are correctly picked up by my web service.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.8</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                    ....
                            <artifactItem>
                                <groupId>org.eclipse.birt.runtime</groupId>
                                <artifactId>org.eclipse.birt.runtime</artifactId>
                                <version>4.4.1</version>
                                <type>jar</type>
                                <overWrite>false</overWrite>
                                <outputDirectory>${project.build.directory}/aar/lib</outputDirectory>
                            </artifactItem>
                    ...
                    </configuration>
                </execution>
            </executions>
        </plugin>
        ...
    </plugins>
</build>
<dependencies>
    ...
    <dependency>
        <groupId>org.eclipse.birt.runtime</groupId>
        <artifactId>org.eclipse.birt.runtime</artifactId>
        <version>4.4.1</version>
    </dependency>
    ...
</dependencies>

A snippet of my Java code is as follows, which has been stripped down for simplicity:

        InputStream theReportDesign = getReportDesignStream();

        // The engine will eventually be called just once...
        EngineConfig config = new EngineConfig();
        config.setEngineHome("");

        // Create the report engine itself. This engine can be used to run
        // multiple reports.
        ReportEngine engine = new ReportEngine(config);

        // Create a task to run the report and convert the output to PDF.
        IReportRunnable report = engine.openReportDesign(theReportName, theReportDesign);

        IRunAndRenderTask task = engine.createRunAndRenderTask(report);
        outputStream = new ByteArrayOutputStream();

        // Define the report generation options
        HTMLRenderOption options = new HTMLRenderOption();
        options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF);
        options.setOutputStream(outputStream);
        task.setRenderOption(options);
        task.setErrorHandlingOption(IEngineTask.CONTINUE_ON_ERROR);

        // set the parameters to appear in the report
        task.setParameterValues(values);

        // Generate the report.
        task.run();

        // Write the report to disk, so ftp clients can pick it up
        outputStream.close();
        writePdfReportToFile(outputStream);

The error I get when running this from within WSO2 Application Server is as follows:

Can not load the report engine
java.lang.NullPointerException
    at org.eclipse.birt.report.engine.api.ReportEngine.openReportDesign(ReportEngine.java:182)

I have seen many proposed solutions on the web, but most within the Tomcat/Axis2 environment (which is what WSO2 uses) require knowledge of the ServletContext. My attempts to get the ServletContext off of the MessageContext have not been successful.

I am hoping to not have to deploy Birt into WSO2, but to instead keep the Birt Runtime contained within my aar file which I deploy to WSO2. But I'll resort to deploying Birt directly to the WSO2 server, as well (just need instructions to do that and still make the above code work).

Thanks in advance for any help.

2

2 Answers

0
votes

This line should not be necessary because the BIRT runtime is embedded in your bundle, try to comment it:

config.setEngineHome("");

Furthermore usually we need to start the BIRT platform before creating an engine, check this link. I know you said the java snippet has been stripped, but we don't have any clue to guess if you forgot this or not:

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

However it is strange you don't get any exception when the engine is created, may be it is actually wrapped in a try..catch?

0
votes

Ok, figured it out.

First of all, it is acceptable for EngineHome and BirtHome to be null if the runtime engine is already in your path.

As such, my issue is that when building with maven, it is not sufficient just define the the birt runtime in your pom.xml. There are a number of jar files which are not automatically included in the build and are otherwise not found in the WSO2 environment.

To this end, I've thus far added tidy to my pom.xml file, and added the following jar files to my WSO2_HOME/repository/components/dropins folder:

com.lowagie.text_2.1.7.v201004222200.jar
icu4j-54_1_1.jar
mysql_connector_java_5.1.26_bin_1.0.0.jar
org.apache.batik.bridge_1.6.0.v201011041432.jar
org.apache.batik.css_1.6.0.v201011041432.jar
org.apache.batik.dom.svg_1.6.0.v201011041432.jar
org.apache.batik.dom_1.6.0.v201011041432.jar
org.apache.batik.ext.awt_1.6.0.v201011041432.jar
org.apache.batik.parser_1.6.0.v201011041432.jar
org.apache.batik.pdf_1.6.0.v201105071520.jar
org.apache.batik.svggen_1.6.0.v201011041432.jar
org.apache.batik.transcoder_1.6.0.v201011041432.jar
org.apache.batik.util.gui_1.6.0.v201011041432.jar
org.apache.batik.util_1.6.0.v201011041432.jar
org.apache.batik.xml_1.6.0.v201011041432.jar
org.eclipse.datatools.connectivity.oda_3.4.3.v201405301249.jar
org.w3c.css.sac_1.3.0.v200805290154.jar
org.w3c.dom.smil_1.0.0.v200806040011.jar
org.w3c.dom.svg_1.1.0.v201011041433.jar
org.wso2.carbon.logging.propfile_1.0.0.jar

I've also found it necessary to put the following line of code prior to the Platform.startup(config) statement:

// The following line is required in wso2:
// http://stackoverflow.com/questions/13241045/why-doesnt-websphere-like-birt
RegistryProviderFactory.releaseDefault();
Platform.startup(config);

I am now successfully generating reports in the WSO2 environment. With that said, I am sure of the following:

  • Additional missing jar files will likely be found as I build out more reports
  • Some of the jar files I manually added to the wso2 dropins folder may be replaced with additional pom.xml dependencies

So more trial and error to come. But for now, am successfully generating reports in WSO2.