Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » BIRT » Embedded Report - JavaScript Error(Embedded Report - JavaScript Error)
Embedded Report - JavaScript Error [message #676899] Mon, 06 June 2011 22:01 Go to next message
Steve Bliss is currently offline Steve Bliss
Messages: 15
Registered: February 2011
Junior Member
I'm running into a strange problem with JavaScript. We have a report that is embedded in a J2EE application, running on WebSphere 6.1 and BIRT 3.2.2.

The report generates PDF documents on request, the docs are sent to an FTP server.

In the report design's initialize event, we define two global methods that are used to determine the MasterPage property for report elements.

function willFitOnFirstPage ( target ) {
	return ( reportContext.getAppContext().get("lineCount") < target );
}
// make willFitOnFirstPage() globally available	
reportContext.setPersistentGlobalVariable("willFitOnFirstPage", willFitOnFirstPage);

function assignMasterPage ( element, target ) {
	if ( reportContext.getAppContext().get("showInsertionBarcode").toLowerCase().indexOf("y") == -1 ) { 
		element.getStyle().masterPage = "NoBarcodeMasterPage"; 
	}
	else if ( willFitOnFirstPage(target) ) { 
		element.getStyle().masterPage = "FirstMasterPage"; 	
	}
	else {
		element.getStyle().masterPage = "FollowingMasterPage"; 
	}
}
// make assignMasterPage() globally available	
reportContext.setPersistentGlobalVariable("assignMasterPage", assignMasterPage);


The problem is this: when the application/server is started, everything works fine. Then, after a week or so, we start getting the following error:

org.eclipse.birt.core.exception.CoreException: There are errors evaluating script "assignMasterPage(this, 141);
":
TypeError: Cannot find function toLowerCase. (/report/method[@name="initialize"]#16).


So it seems like somehow the JavaScript engine is getting corrupted? Or the report design? This problem happens on two different servers.

Any thoughts, insight or suggestions would be much appreciated!
Steve
Re: Embedded Report - JavaScript Error [message #677193 is a reply to message #676899] Tue, 07 June 2011 17:59 Go to previous messageGo to next message
Jason Weathersby is currently offline Jason Weathersby
Messages: 9167
Registered: July 2009
Senior Member

Are you cetain this is always set to a string?
reportContext.getAppContext().get("showInsertionBarcode")

You may want to toString() the object before calling the toLowerCase
Also you may want to put importPackage(Packages.java.lang) at the top of
the beforeFactory.

Jason

On 6/6/2011 6:01 PM, forums-noreply@eclipse.org wrote:
> I'm running into a strange problem with JavaScript. We have a report
> that is embedded in a J2EE application, running on WebSphere 6.1 and
> BIRT 3.2.2.
>
> The report generates PDF documents on request, the docs are sent to an
> FTP server.
>
> In the report design's initialize event, we define two global methods
> that are used to determine the MasterPage property for report elements.
>
> function willFitOnFirstPage ( target ) {
> return ( reportContext.getAppContext().get("lineCount") < target );
> }
> // make willFitOnFirstPage() globally available
> reportContext.setPersistentGlobalVariable("willFitOnFirstPage",
> willFitOnFirstPage);
>
> function assignMasterPage ( element, target ) {
> if (
> reportContext.getAppContext().get("showInsertionBarcode").toLowerCase().indexOf("y")
> == -1 ) { element.getStyle().masterPage = "NoBarcodeMasterPage"; }
> else if ( willFitOnFirstPage(target) ) { element.getStyle().masterPage =
> "FirstMasterPage";
> }
> else {
> element.getStyle().masterPage = "FollowingMasterPage"; }
> }
> // make assignMasterPage() globally available
> reportContext.setPersistentGlobalVariable("assignMasterPage",
> assignMasterPage);
>
> The problem is this: when the application/server is started, everything
> works fine. Then, after a week or so, we start getting the following error:
>
> org.eclipse.birt.core.exception.CoreException: There are errors
> evaluating script "assignMasterPage(this, 141);
> ":
> TypeError: Cannot find function toLowerCase.
> (/report/method[@name="initialize"]#16).
>
>
> So it seems like somehow the JavaScript engine is getting corrupted? Or
> the report design? This problem happens on two different servers.
>
> Any thoughts, insight or suggestions would be much appreciated!
> Steve
>
Re: Embedded Report - JavaScript Error [message #677414 is a reply to message #677193] Wed, 08 June 2011 13:00 Go to previous messageGo to next message
Steve Bliss is currently offline Steve Bliss
Messages: 15
Registered: February 2011
Junior Member
Jason Weathersby wrote on Tue, 07 June 2011 13:59
Are you cetain this is always set to a string?
reportContext.getAppContext().get("showInsertionBarcode")

You may want to toString() the object before calling the toLowerCase
Also you may want to put importPackage(Packages.java.lang) at the top of
the beforeFactory.


It's either returning a string or nothing. The Java code that sets up the showInsertionBarcode is fairly straightforward, but I am working on tests to verify the value of this flag.

I can understand adding toString(), in case the returned object isn't a string. But wouldn't importing Packages.java.lang be a compile requirement? That is, if it is needed, wouldn't it always be an error if it's not there?

Steve
Re: Embedded Report - JavaScript Error [message #677540 is a reply to message #677414] Wed, 08 June 2011 18:50 Go to previous messageGo to next message
Jason Weathersby is currently offline Jason Weathersby
Messages: 9167
Registered: July 2009
Senior Member

You are correct adding the toString would require an importPackage. You
may want to do a typeof check just to verify type. I am wondering if
the nothing value is causing the error:

var jj =reportContext.getAppContext().get("showInsertionBarcode")
if( typeof jj == 'undefined' ){

Jason



On 6/8/2011 9:00 AM, forums-noreply@eclipse.org wrote:
> Jason Weathersby wrote on Tue, 07 June 2011 13:59
>> Are you cetain this is always set to a string?
>> reportContext.getAppContext().get("showInsertionBarcode")
>>
>> You may want to toString() the object before calling the toLowerCase
>> Also you may want to put importPackage(Packages.java.lang) at the top
>> of the beforeFactory.
>
>
> It's either returning a string or nothing. The Java code that sets up
> the showInsertionBarcode is fairly straightforward, but I am working on
> tests to verify the value of this flag.
>
> I can understand adding toString(), in case the returned object isn't a
> string. But wouldn't importing Packages.java.lang be a compile
> requirement? That is, if it is needed, wouldn't it always be an error if
> it's not there?
>
> Steve
Re: Embedded Report - JavaScript Error [message #682105 is a reply to message #677540] Fri, 10 June 2011 12:21 Go to previous messageGo to next message
Steve Bliss is currently offline Steve Bliss
Messages: 15
Registered: February 2011
Junior Member
To further troubleshoot the issue, I added a text element to the report, and set its onRender to:

this.text = "showInsertionBarcode=" + reportContext.getAppContext().get("showInsertionBarcode");

During normal executions, this text shows:

showInsertionBarcode=YES

When the report has issues, the text shows the following value:

showInsertionBarcode=org.eclipse.birt.report.engine.executor.ExecutionContext@29242924


So it looks like somehow the entry in the appContext is getting set to the appContext itself? Does that make any sense?

And just to be clear: 100% of the time, the value for showInsertionBarcode is "YES". From the Java side, we've confirmed that's what the value is put into the appContext.

Is BIRT 2.3 thread-safe? Could there be issues with multiple executions using the same IReportEngine and IRunAndRenderTask objects?

Steve


Re: Embedded Report - JavaScript Error [message #682207 is a reply to message #682105] Fri, 10 June 2011 15:37 Go to previous messageGo to next message
Jason Weathersby is currently offline Jason Weathersby
Messages: 9167
Registered: July 2009
Senior Member

Steve,

BIRT is thread safe as long as you are using a new task for each
execution. Any chance you could post your code? Are you closing each
task? As a test can you change your script to this:

this.text = "Report Context AppContext " + reportContext.getAppContext();

And produce the error.

BTW as a test could you try the 2.6.2 runtime?

Jason

On 6/10/2011 8:21 AM, forums-noreply@eclipse.org wrote:
> To further troubleshoot the issue, I added a text element to the report,
> and set its onRender to:
>
> this.text = "showInsertionBarcode=" +
> reportContext.getAppContext().get("showInsertionBarcode");
> During normal executions, this text shows:
>
> showInsertionBarcode=YES
> When the report has issues, the text shows the following value:
>
> showInsertionBarcode=org.eclipse.birt.report.engine.executor.ExecutionContext@29242924
>
>
> So it looks like somehow the entry in the appContext is getting set to
> the appContext itself? Does that make any sense?
>
> And just to be clear: 100% of the time, the value for
> showInsertionBarcode is "YES". From the Java side, we've confirmed
> that's what the value is put into the appContext.
>
> Is BIRT 2.3 thread-safe? Could there be issues with multiple executions
> using the same IReportEngine and IRunAndRenderTask objects?
>
> Steve
>
>
>
Re: Embedded Report - JavaScript Error [message #682340 is a reply to message #682207] Fri, 10 June 2011 21:29 Go to previous messageGo to next message
Steve Bliss is currently offline Steve Bliss
Messages: 15
Registered: February 2011
Junior Member
We are holding onto the report engine and the report design objects between execution. A fresh new task object is used in every run.

We've narrowed the issue down, the problem is occurring in the Java code that is preparing the task for execution. Basically, we put one value (a string) into the appcontext, but when we check that value, it's coming back as the ExecutionContext object.

Here's the core of the Java code, I've flagged the part where the error occurs.

private static IReportEngine engine;
private static ReportDesignCache designCache;

private void executeReport(Invoice invoice, boolean isRemote) throws Exception {
	if (engine == null) {
		engine = BirtEngine.getBirtEngine();
	}
	if (designCache == null) {
		designCache = new ReportDesignCache(engine);
	}

	String countryCode = "US";
	countryCode = invoice.getHeader().getCountryCode();
	String warehouseCode = invoice.getHeader().getWarehouseCode();

	ReportProperties  config = new ReportProperties(warehouseCode, countryCode);
	IReportRunnable   design = designCache.get(config.getDesignFileName());
	IRunAndRenderTask task   = engine.createRunAndRenderTask(design);

	if (isRemote) {
		task.setRenderOption(getRenderOptionRemote(config));
	}
	else {
		task.setRenderOption(getRenderOptionInteractive(config));
	}

	ReportHeader h = new ReportHeader();
	h.load(invoice.getHeader());

	ReportBody b = new ReportBody();
	b.load(invoice);

	ReportTotals t = new ReportTotals();
	t.load(invoice);

	ReportLayout l = new ReportLayout();
	l.load(config, invoice);
	
	Map<String, Object> parameters = new HashMap<String, Object>();
	parameters.put("ReportHeader", h);
	parameters.put("ReportDetails", b);
	parameters.put("ReportTotals", t);
	parameters.put("ReportLayout", l);
	
	// *** enabling following two lines seems to prevent error condition ***
	// putAppContext(task, "sacrifice1", "goat");
	// putAppContext(task, "sacrifice2", "chicken");
			
	// *** error condition originates in this loop ***
	for (String key: config.getParameters().keySet()) {
		log.logWarn("Config value for key:" + key + ", value:" + config.getParameter(key) + ":");
		putAppContext(task, key, config.getParameter(key));
	}
	log.logWarn("AppContext value for showInsertionBarcode: '" + task.getAppContext().get("showInsertionBarcode") + "'");
	
	putAppContext(task, "PrintOrderTotals", invoice.getHeader().getPrintOrderTotal());
	log.logWarn("AppContext value for showInsertionBarcode(2): '" + task.getAppContext().get("showInsertionBarcode") + "'");
	
	Long lineCount = invoice.getDetailSectionHeight();
	putAppContext(task, "lineCount", lineCount.toString());
	
	task.setParameterValues(parameters);

	task.run();
	task.close();
	log.logWarn("AppContext value for showInsertionBarcode(3): '" + task.getAppContext().get("showInsertionBarcode") + "'");

	if (isRemote) {
		cbb.getOutputStream().close();
		DistributeReportProcess dist = new DistributeReportProcess();
		dist.setDrop(drop);
		String fileName = generateFileName(config.isPostscript(), invoice);
		dist.writeFile(fileName, cbb.getInputStream());
	}
}

@SuppressWarnings("unchecked")
private void putAppContext(IRunAndRenderTask task, String id, Object value) {
	task.getAppContext().put(id, value);
}


Here's a section of the log, showing the issue:

AppContext value key:showInsertionBarcode, value:YES:
AppContext value key:design, value:TestInvoicePackingList.rptdesign:
AppContext value key:showSmartLabel, value:YES:
AppContext value key:format, value:pdf:
AppContext value for showInsertionBarcode: 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
AppContext value for showInsertionBarcode(2): 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
AppContext value for showInsertionBarcode(3): 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
Re: Embedded Report - JavaScript Error [message #682425 is a reply to message #682340] Sat, 11 June 2011 03:44 Go to previous message
Jason Weathersby is currently offline Jason Weathersby
Messages: 9167
Registered: July 2009
Senior Member

When you create the task can you try creating a new hashmap add any
values you want to the map and then set the appcontext for the task?

The Birt Viewer does it like:

Map context = BirtUtility.getAppContext( request );
runAndRenderTask.setAppContext( context );

//from BirtUtility
public static Map getAppContext( HttpServletRequest request )
{
HashMap context = new HashMap( );
Boolean isDesigner = Boolean.valueOf( ParameterAccessor.isDesigner( ) );
context.put( "org.eclipse.birt.data.engine.dataset.cache.option",
//$NON-NLS-1$
isDesigner );
context.put( EngineConstants.APPCONTEXT_BIRT_VIEWER_HTTPSERVET_REQUEST,
request );

// Client DPI setting
context.put( EngineConstants.APPCONTEXT_CHART_RESOLUTION,
ParameterAccessor.getDpi( request ) );

// Max cube fetch levels
int maxCubeRowLevels = ParameterAccessor.getMaxCubeRowLevels( request );
if ( maxCubeRowLevels >= 0 )
context.put( DataEngine.CUBECUSROR_FETCH_LIMIT_ON_ROW_EDGE,
Integer.valueOf( maxCubeRowLevels ) );

int maxCubeColumnLevels = ParameterAccessor.getMaxCubeColumnLevels(
request );
if ( maxCubeColumnLevels >= 0 )
context.put( DataEngine.CUBECURSOR_FETCH_LIMIT_ON_COLUMN_EDGE,
Integer.valueOf( maxCubeColumnLevels ) );

// Cube memory size
int cubeMemorySize = ParameterAccessor.getCubeMemorySize( request );
if ( cubeMemorySize >= 0 )
context.put( DataEngine.IN_MEMORY_CUBE_SIZE,
Integer.valueOf( cubeMemorySize ) );

// add resource path to app context
context.put( IBirtConstants.APPCONTEXT_BIRT_RESOURCE_PATH,
ParameterAccessor.getResourceFolder( request ) );

// Push user-defined application context
ParameterAccessor.pushAppContext( context, request );

if ( isDesigner.booleanValue( ) )
{
String appContextName = ParameterAccessor.getAppContextName( request );
getAppContextFromExtension( appContextName, context );
}

return context;
}

Jason

On 6/10/2011 5:29 PM, forums-noreply@eclipse.org wrote:
> We are holding onto the report engine and the report design objects
> between execution. A fresh new task object is used in every run.
>
> We've narrowed the issue down, the problem is occurring in the Java code
> that is preparing the task for execution. Basically, we put one value (a
> string) into the appcontext, but when we check that value, it's coming
> back as the ExecutionContext object.
>
> Here's the core of the Java code, I've flagged the part where the error
> occurs.
>
> private static IReportEngine engine;
> private static ReportDesignCache designCache;
>
> private void executeReport(Invoice invoice, boolean isRemote) throws
> Exception {
> if (engine == null) {
> engine = BirtEngine.getBirtEngine();
> }
> if (designCache == null) {
> designCache = new ReportDesignCache(engine);
> }
>
> String countryCode = "US";
> countryCode = invoice.getHeader().getCountryCode();
> String warehouseCode = invoice.getHeader().getWarehouseCode();
>
> ReportProperties config = new ReportProperties(warehouseCode, countryCode);
> IReportRunnable design = designCache.get(config.getDesignFileName());
> IRunAndRenderTask task = engine.createRunAndRenderTask(design);
>
> if (isRemote) {
> task.setRenderOption(getRenderOptionRemote(config));
> }
> else {
> task.setRenderOption(getRenderOptionInteractive(config));
> }
>
> ReportHeader h = new ReportHeader();
> h.load(invoice.getHeader());
>
> ReportBody b = new ReportBody();
> b.load(invoice);
>
> ReportTotals t = new ReportTotals();
> t.load(invoice);
>
> ReportLayout l = new ReportLayout();
> l.load(config, invoice);
>
> Map<String, Object> parameters = new HashMap<String, Object>();
> parameters.put("ReportHeader", h);
> parameters.put("ReportDetails", b);
> parameters.put("ReportTotals", t);
> parameters.put("ReportLayout", l);
>
> // *** enabling following two lines seems to prevent error condition ***
> // putAppContext(task, "sacrifice1", "goat");
> // putAppContext(task, "sacrifice2", "chicken");
>
> // *** error condition originates in this loop ***
> for (String key: config.getParameters().keySet()) {
> log.logWarn("Config value for key:" + key + ", value:" +
> config.getParameter(key) + ":");
> putAppContext(task, key, config.getParameter(key));
> }
> log.logWarn("AppContext value for showInsertionBarcode: '" +
> task.getAppContext().get("showInsertionBarcode") + "'");
>
> putAppContext(task, "PrintOrderTotals",
> invoice.getHeader().getPrintOrderTotal());
> log.logWarn("AppContext value for showInsertionBarcode(2): '" +
> task.getAppContext().get("showInsertionBarcode") + "'");
>
> Long lineCount = invoice.getDetailSectionHeight();
> putAppContext(task, "lineCount", lineCount.toString());
>
> task.setParameterValues(parameters);
>
> task.run();
> task.close();
> log.logWarn("AppContext value for showInsertionBarcode(3): '" +
> task.getAppContext().get("showInsertionBarcode") + "'");
>
> if (isRemote) {
> cbb.getOutputStream().close();
> DistributeReportProcess dist = new DistributeReportProcess();
> dist.setDrop(drop);
> String fileName = generateFileName(config.isPostscript(), invoice);
> dist.writeFile(fileName, cbb.getInputStream());
> }
> }
>
> @SuppressWarnings("unchecked")
> private void putAppContext(IRunAndRenderTask task, String id, Object
> value) {
> task.getAppContext().put(id, value);
> }
>
> Here's a section of the log, showing the issue:
>
> AppContext value key:showInsertionBarcode, value:YES:
> AppContext value key:design, value:TestInvoicePackingList.rptdesign:
> AppContext value key:showSmartLabel, value:YES:
> AppContext value key:format, value:pdf:
> AppContext value for showInsertionBarcode:
> 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
> AppContext value for showInsertionBarcode(2):
> 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
> AppContext value for showInsertionBarcode(3):
> 'org.eclipse.birt.report.engine.executor.ExecutionContext@3c743c74'
Previous Topic:relative path reference in html?
Next Topic:Easily create sparklines
Goto Forum:
  


Current Time: Tue Sep 16 11:30:27 GMT 2014

Powered by FUDForum. Page generated in 0.02858 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software