on 02-16-2009 3:46 AM
Hi all
We're currently evaluating CR for use in our swing-based application. Our app has a plugin mechanism, and I'm having some difficulty in getting our plugins unloaded after using the ReportViewerBean. Specifically, it appears that a number of background threads with names like "Background Batch Spiller 0" are started up by the Crystal Reports code, and hang around even after closing the component. The threads appear to still have references to our plugin's classloader through the inheritedAccessControlContext field on the thread. We are not running with a SecurityManager.
I believe that I'm calling ReportClientDocument.close() as necessary and also cleaning up the viewer by calling stop() followed by destroy() on it.
Is there any way to programatically tell the Crystal code to shut down all its background threads? Or are there any other suggestions?
Thanks in advance
Tom
After you call ReportClientDocument.close(), does ReportClientDocument.isOpen() return true?
If so, here's something of interest: [Crystal Reports for Eclipse - Ensuring Report Cleanup|https://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/11649] [original link is broken] [original link is broken] [original link is broken];
Sincerely,
Ted Ueda
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for that. Yes, it's still open apparently. The page that you referred me to mentioned using a CrystalReportViewer or ReportExportControl to close the report source. I'm not using either of those, I'm using a ReportViewerBean, the Swing component for front-end applications. It doesn't seem to have a dispose method. I can't find either of those other classes in my classpath here - this is in a project created using the Eclipse new Crystal Reports Java Project wizard.
Any suggestions?
Thanks
OK, more progress. I found a dispose() method on the IReportSource, and the ReportClientDocument.isOpen() is now returning false. The background threads are still there, though, and are still causing the classloader to stay in memory. I can see "Background Batch Spiller 0", Background Batch Spiller 1" and "JRC Timeout Thread" all having references to my classloader through their inheritedAccessContextControl, plus a reference from a Crystal class called ClassJail (through a presumably obfuscated class named "a" in the classjail package).
Suggestions?
Thanks
Tom
Those look like backend report engine components for which there's no programmatic control with the public API.
I'll see what I can find.
Also - a comment concerning dispose() - there's several different types of report source classes used in the Crystal world, that depends on how they're generated. All implement the dispose() method, but no report source interface is exposed publicly.
So the workaround is to pass them to the CrystalReportViewer, not to view them, but to invoke dispose() on the viewer, that calls dispose() on the report source.
Using reflection to invoke dispose() directly is possible, but not something fully tested internally.
Sincerely,
Ted Ueda
Hi Ted. Thanks for checking it out.
The report interface that I have is a com.crystaldecisions.sdk.occa.report.reportsource.IReportSource. That is what is returned from the ReportClientDocument.getReportSource() method. I'm not using any reflection.
I'm developing a front-end application - I do not have a CrystalReportViewer class in the classpath, and one is not added to the classpath by the Eclipse Crystal Reports Java Project. If I create a web project, it's there. Should I really add webreporting.jar to a front-end application just for this? It doesn't seem that disposing of the report source is stopping all of those threads anyway...
Thanks
Tom
Hi, can you tell me if a way to cleanly terminate background threads was ever implemented? Our client has a Domino Java agent that uses the crjava-runtime_12.2.218 library to access backend report engine objects. They are seeing numerous errors in their Domino server console when running the Java agent.
Agent error: Exception in thread "Background Batch Spiller 0"
Agent error: java.lang.IllegalMonitorStateException
Agent error: at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:138)
Agent error: at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1250)
Agent error: at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:442)
Agent error: at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:417)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.if(SourceFile:943)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.a(SourceFile:957)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.run(SourceFile:991)
Agent error: at java.lang.Thread.run(Thread.java:761)
Agent error: Exception in thread "Background Batch Spiller 1"
Agent error: java.lang.IllegalMonitorStateException
Agent error: Exception in thread "Background Batch Spiller 2"
Agent error: at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:138)
Agent error: java.lang.IllegalMonitorStateException
Agent error: at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1250)
Agent error: at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:138)
Agent error: at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:442)
Agent error: at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1250)
Agent error: at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:417)
Agent error: at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:442)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.if(SourceFile:943)
Agent error: at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:417)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.a(SourceFile:957)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.if(SourceFile:943)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.run(SourceFile:991)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.a(SourceFile:957)
Agent error: at java.lang.Thread.run(Thread.java:761)
Agent error: at com.crystaldecisions.reports.saveddata.saveddata.Batch$d.run(SourceFile:991)
Agent error: at java.lang.Thread.run(Thread.java:761)
I got on a call with SCN and they were not able to provide us with a solution. Our client ended up having to schedule to restart their Domino server each time after the report ran. Fortunately they only run the report at the beginning of each month but that is still not a very good solution. Good luck to you!
We are only using the Crystal Reports SDK to export PDF reports. While tracing memory leaks on a tomcat server running a large number of applications, we came across these background threads and are unable to terminate them. This means if any application generates one report and spawns these threads, that application can never be stopped/undeployed/redeployed. The only solution of restarting the Tomcat server any time there is a deployment is not really feasible and causes quite a large number of headaches.
As a developer myself, I probably would have questioned why we would be creating these threads with no way to stop them.
Can you let us know if they are even thinking about looking at this issue?
User | Count |
---|---|
87 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.