dusca Posted May 14, 2008 Share Posted May 14, 2008 I have an app that has as input jrxml file names, and outputs the pdf reports. So I am given a "mainReport.jrxml" string, and should output the pdf. I can easily compile "mainReport" to compiledDirectory, load it into a JasperReport object and then call JasperFillManager.fillReport () But in the case of a report having subreports, how do I find that mainReport subreports (and what are their filenames) to compile those also?there is no JasperReport.getSubeports() or something similar... any ideas? I hope I was explicit enough Link to comment Share on other sites More sharing options...
greylimbo Posted May 14, 2008 Share Posted May 14, 2008 Yeah we had this issue, so we implemented this Code:<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[JasperCompileManager.compileReport(getClass().getResource("/templates/subreport.jrxml"«»).openStream())]]></subreportExpression> within the mainReport thereby compiling the subreport jrxml everytime the main report is run. We have since changed this to compile and jar up all our jrxml files in a ant script, which then also handles all the fonts and customizer classes we have to go with our reports. Link to comment Share on other sites More sharing options...
lucianc Posted May 14, 2008 Share Posted May 14, 2008 dusca wrote:But in the case of a report having subreports, how do I find that mainReport subreports (and what are their filenames) to compile those also?there is no JasperReport.getSubeports() or something similar... any ideas? If you use JR 2.0.3 or newer, you can iterate on all the subreports in a report via JRElementsVisitor:Code:JRElementsVisitor.visitReport(jr, new JRVisitorSupport() { @Override public void visitSubreport(JRSubreport subreport) { ..do whatever you have to do with the subreport.. }}); Note that if you want to determine the "filename" of the subreport, you'll have to make some assumptions on the subreport expressions, since such expressions can be arbitrarily complex and don't necessarily consists of a static filename. HTH,Lucian Link to comment Share on other sites More sharing options...
dusca Posted May 14, 2008 Author Share Posted May 14, 2008 thanks lucian, greylimbo.tried first the greylimbo approach but didn't quite work as i needed, so i am using lucian's solution so now I have something along the lines of: Code:JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);ret = (JasperReport) JRLoader.loadObject(jasperPath);JRElementsVisitor.visitReport(ret, new SubreportVisitor(sourcePath, destinationPath)); and in my visitor I get the subreport path and also JasperCompileManager.compileReportToFile(subReportJrxmlPath, jasperPath); but at runtime I get a Code:[code]net.sf.jasperreports.engine.JRException: Could not load object from location : MySubReport.jasper at net.sf.jasperreports.engine.util.JRLoader.loadObjectFromLocation(JRLoader.java:267) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:308) am I supposed to do a JRLoader.loadObject for the supreport too,or what am I missing?the jasper files exist and are all in the same dir. thanks Link to comment Share on other sites More sharing options...
dusca Posted May 14, 2008 Author Share Posted May 14, 2008 to answer my own question, loadObject has no effect. so it's not that later edit: this is killing me now! I have a report that has one subreport. the subreport expression is something like "SubraportulMeu.jasper" that works perfectly with the code explained above. then another report, but with two subreports, with the same expression - gives me the "cannot load" exception. i quadruple checked but just can't figure out what the heck is the difference, why one works but the other doesn't. to the first i only send $P{} params, to the second i send $P{} and $F{}. that is the only thing that is different, but shouldn't be relevant.Post edited by: dusca, at: 2008/05/14 15:19 Link to comment Share on other sites More sharing options...
lucianc Posted May 14, 2008 Share Posted May 14, 2008 Subreport locations are interpreted at runtime as a filename, a classloader resource or a URL. So for "MySubReport.jasper" to be resolved, it should either be a file in the JVM's working directory, or a resource on your application's classpath (so the folder where you have the *.jasper files would have to be part of the classpath). Regards,Lucian Link to comment Share on other sites More sharing options...
dusca Posted May 14, 2008 Author Share Posted May 14, 2008 lucian, then how is it explained that one of the reports works without a full abstract path? the same directories are used in both cases . all jrxml files are in one directory and all jasper files in another. Link to comment Share on other sites More sharing options...
lucianc Posted May 15, 2008 Share Posted May 15, 2008 It's rather difficult to tell why that happens without seeing it happen. Is there a way I could reproduce the behaviour? Post edited by: lucianc, at: 2008/05/14 17:41 Link to comment Share on other sites More sharing options...
dusca Posted May 15, 2008 Author Share Posted May 15, 2008 i found out why the particular one was created. eclipse forgot to delete the jasper file from the bin directory, so it was in the run dir. so ..in the end i used greylimbo's solution after all. thank you, it is quite a trick. i cannot imagine another way, to use a relative path to the subreportPost edited by: dusca, at: 2008/05/14 20:06 Link to comment Share on other sites More sharing options...
dusca Posted May 21, 2009 Author Share Posted May 21, 2009 HiI'm coming back to this with a problem. So my Subreport is defined using this expression: <connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression> <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[net.sf.jasperreports.engine.JasperCompileManager.compileReport(getClass().getResource("Subreport.jrxml").openStream())]]></subreportExpression> If I run and execute the report from Ireport, the subreport is loaded, it all works like a charmBut from my application, when I generate it usingJasperPrint jPrint = JasperFillManager.fillReport(rep, params, conn); JRExporter exporter = getExporter(pdf); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, byteArrayOutputStream); exporter.exportReport(); it doesn't work. No exception is thrown, it just doesn't embed the subreport.So how can this be? Do I need to do something more in my reporting app? Link to comment Share on other sites More sharing options...
lucianc Posted May 21, 2009 Share Posted May 21, 2009 You need to have Subreport.jrxml present as a resource on the application classpath, e.g. placed in a folder which is included on the classpath.Regards,Lucian Link to comment Share on other sites More sharing options...
dusca Posted May 22, 2009 Author Share Posted May 22, 2009 thanks, that worked! Link to comment Share on other sites More sharing options...
C-Box Posted May 22, 2009 Share Posted May 22, 2009 Isn't it a bit kind of inperformance to (re)compile the jrxml everytime the SubReport is loaded?Imagine you have a placed the SubReport-Element in detail of MasterReport and have 1000 records... with your SubReportExpression you will now have 1000 compiles, isn't it????So I would pass the compiled JasperReport Object as parameter or use a scriptlet does check wheter the jrxml must be (re)compiled or not!??!?! So as the SubReport-design isn't changed normally while fill process it should be compiled just once and not at each call!??!?!?!?? just my two cents.C-Box Link to comment Share on other sites More sharing options...
dusca Posted May 22, 2009 Author Share Posted May 22, 2009 you are correct. for each subreport in a detail field there is a lot of overhead (the sql query would be more expensive i think - i may be wrong here, so plese correct me) - that is why i embed my subreports in the summary band, or in a new report group's header/foooterBut now that you pointed out the performance issue, I used the SubreportVisitor lucian suggested to compile the sources, and passed the subreport dir parameter to the report. Thanks! Link to comment Share on other sites More sharing options...
matmosis Posted June 16, 2009 Share Posted June 16, 2009 I alli have tryed the solution using the following line:<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[net.sf.jasperreports.engine.JasperCompileManager.compileReport(getClass().getResource("/prova/sub_dummy.jrxml").openStream())]]></subreportExpression>on my main.jrxml report fileworks great from my webapp (jsp), but if i open the file with IREPORT (v 3.5.2) and use "preview" button, that gives me the following error:Error filling print... Error evaluating expression : Source text : net.sf.jasperreports.engine.JasperCompileManager.compileReport(getClass().getResource("/prova/sub_dummy.jrxml").openStream()) net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression : Source text : net.sf.jasperreports.engine.JasperCompileManager.compileReport(getClass().getResource("/prova/sub_dummy.jrxml").openStream()) at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:197) at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:574) at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:542) at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:872) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:283) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate(JRFillSubreport.java:270) at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:260) at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:486) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillTitle(JRVerticalFiller.java:312) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:248) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:114) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:911) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:814) at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:63) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:421) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:251) at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:898) at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:561) at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:986) Caused by: net.sf.jasperreports.engine.JRException: Could not instantiate report compiler : it.businesslogic.ireport.compiler.ExtendedJRJdtCompiler at net.sf.jasperreports.engine.JasperCompileManager.getCompiler(JasperCompileManager.java:520) at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:219) at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:205) at main_1245143465937_710977.evaluate(main_1245143465937_710977:183) at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:186) ... 18 more Caused by: java.lang.ClassNotFoundException: it.businesslogic.ireport.compiler.ExtendedJRJdtCompiler at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:231) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at net.sf.jasperreports.engine.util.JRClassLoader.loadClassForRealName(JRClassLoader.java:179) at net.sf.jasperreports.engine.util.JRClassLoader.loadClassForName(JRClassLoader.java:119) at net.sf.jasperreports.engine.JasperCompileManager.getCompiler(JasperCompileManager.java:515) ... 22 more Print not filled. Try to use an EmptyDataSource...anyone knows the problem and a solution to it?maybe i have missing something like a particular jar in the classpath?thanks,Mat Link to comment Share on other sites More sharing options...
matmosis Posted June 16, 2009 Share Posted June 16, 2009 the file ""/prova/sub_dummy.jrxml" is in a jar that i had included in the IREPORT classpath... Link to comment Share on other sites More sharing options...
sundarperiannan Posted July 26, 2009 Share Posted July 26, 2009 Hi friend,I am also try this, but the sub report not displayed. Link to comment Share on other sites More sharing options...
Teodor Danciu Posted August 14, 2009 Share Posted August 14, 2009 Hi, It is like saying: My friend, I have the same car and it also does not start.Well, there are 1 million reasons for the car not to start.So you better open up a new thread and provide as much details as you can, with report templates and PDFs and so on. Thank you,Teodor Link to comment Share on other sites More sharing options...
andreasX Posted December 9, 2013 Share Posted December 9, 2013 general solution/background regarding the path handling and compilation: http://stackoverflow.com/questions/4364205/jasperserver-unable-to-locate-the-subreport-exception/20374515#20374515 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now