birtrhinoosgi-bundle

How can a BIRT Rhino script load a class from a different osgi bundle?


I am integrating a BIRT report engine (4.13) in an RCP app (2023-09, Java17).

I want a bundle (B) to be able to submit a rptdesign to the bundle (R) containing the report engine. One report in bundle B contains a script which uses a Java object in that bundle. The package containing the class is exported by bundle B.

In the report bundle, I determine the origin of the report and set the classloader accordingly.

Bundle B calls bundle R via an extension and there is no direct dependency defined.

Bundle bundle = org.eclipse.core.runtime.Platform.getBundle(getBundleIdFromUrl(reportDesign));
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
config.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, bundleWiring.getClassLoader());
config.getAppContext().put(EngineConstants.APPCONTEXT_DATASET_CACHE_OPTION, Boolean.FALSE.toString());
config.getAppContext().put(EngineConstants.REFRESH_DATA, Boolean.TRUE.toString());

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

However, when the script executes the class is not found:

A BIRT exception occurred. See next exception for more information.
TypeError: [JavaPackage myapp.mech.model.Dao] is not a function, it is object. (/report/data-sets/script-data-set[@id="411"]/method[@name="open"]#1)
org.eclipse.birt.data.engine.core.DataException: Fail to execute script in function __bm_OPEN(). Source:
------
" + model = new Packages.myapp.mech.model.Dao();

(The reports that are in bundle R are processed correctly)

Can I influence the class loading or is this approach basically incorrect?


Solution

  • I found the answer here https://www.vogella.com/tutorials/EclipseBIRT/article.html#deploying-in-eclipse-rcp-application.

    count = 0;
    /*
     * load and init data reader
     * import Platform from org.eclipse.core.runtime
     */
    importPackage(Packages.org.eclipse.core.runtime);
    
    /* load bundle with POJOs and data loading class */
    
    myBundle = Platform.getBundle("de.vogella.birt.stocks");
    
    /* load data reader class */
    readerClass = myBundle.loadClass("de.vogella.birt.stocks.daomock.StockDaoMock");
    
    /* create new instance of DataReader */
    readerInstance = readerClass.newInstance();
    
    
    /* read data */
    stock = readerInstance.getStockValues("Java");