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