Jump to content
We've recently updated our Privacy Statement, available here ×

Groovy compiler classpath in OSGi


chrono_b

Recommended Posts

Hi all,

I am trying to embed jasper report as an OSGi bundle in a web application.  I plan to use the bundle to compile and run reports. Everything works when the report has its language set to Java, but when the language is set to groovy, I get compilation errors like below

net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
calculator_report1_1268386587194_284063: 18: unable to resolve class JREvaluator 
 @ line 18, column 1.
calculator_report1_1268386587194_284063: 25: unable to resolve class JRFillParameter 
 @ line 25, column 5.
calculator_report1_1268386587194_284063: 26: unable to resolve class JRFillParameter 
 @ line 26, column 5.
calculator_report1_1268386587194_284063: 27: unable to resolve class JRFillParameter 
 @ line 27, column 5.
 
I suspect this is caused by the groovy compiler not having the jasper jar file on the classpath.  I am not sure what the classpath is for groovy compiler in an OSGi container or how to set the classpath for the compiler.
 
My code to compile report is quite simple and standard, it works if I run it like a normal Java app (no OSGi, with main method).

Thanks

Patrick

Code:
JasperDesign jasperDesign = JRXmlLoader.load(inputStream);JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
Link to comment
Share on other sites

  • 9 months later...
  • Replies 4
  • Created
  • Last Reply

Top Posters In This Topic

 Hi,

I have almost the same issue.
I've got the same errors.

It happens when Groovy come from the OSGI groovy bundle (org.codehaus.groovy 1.7.5).
It works when we embed directly the jar groovy-all-1.7.5 as lib at the same level of jasperReports3.7.6 but this is not OSGI friendly andit duplicates classes in classloader.

Did you find a solution?

Regards,



Post Edited by apupier at 12/29/2010 12:20
Link to comment
Share on other sites

Hi,

 

We edited the Manifest file in the JR JAR and we think now JR is OSGi ready.

You can get the latest from SVN and let us know if it works for you.

The tracker mentioned in this thread provides a sample to test a Groovy report in OSGi environment, using the Equinox container.

 

Thanks,
Teodor

 

Link to comment
Share on other sites

  • 1 year later...

Here's our guide to tame JasperReports in OSGi :

 

10JasperReports

10.1Core in OSGi

JasperReports core in OSGi/Karaf works quite well:

  1. You need to either:

    1. Import-Package all JasperReports packages (about 50!)

    2. DynamicImport-Package: net.sf.jasperreports.* (I prefer this)

    3. Require-Bundle: (not good!)

  2. Also import the packages that you use e.g. joda time, joda money

  3. Add mvn:commons-digester/commons-digester/2.1 (already OSGi bundle).

  4. Add wrap:mvn:com.lowagie/itext/2.1.7$Export-Package=*;version="2.1.7"

This works well for id.co.bippo.salesorder.rs:

org.apache.felix

maven-bundle-plugin

true

net.sf.jasperreports.*

org.joda.time, *


 

However, there are several common complications:

  1. Extensions

  2. Groovy

10.2Extensions in OSGi

JasperReports extensions must be installed as OSGi fragment and before the JasperReports library bundle.

"jasperreports" description="JasperReports" version="4.8.0" resolver="(obr)">

start-level="40" dependency="true">mvn:commons-digester/commons-digester/2.1

start-level="50">wrap:mvn:com.lowagie/itext/2.1.7$Export-Package=*;version="2.1.7"

start-level="50" dependency="true">mvn:org.codehaus.groovy/groovy-all/1.8.8

start-level="50">wrap:mvn:com.jaspersoft.connectors.mongodb/js-mongodb-datasource/0.5.0$Fragment-Host=net.sf.jasperreports.engine

start-level="50">mvn:net.sf.jasperreports/jasperreports/4.8.0

 

10.3JasperReports-Groovy in OSGi

You'll get this:

calculator_Blank32A432Landscape_LinesDataset_1354253073631_260931: 120: unable to resolve class JRFillVariable  @ line 120, column 33.calculator_Blank32A432Landscape_LinesDataset_1354253073631_260931: 121: unable to resolve class JRFillVariable  @ line 121, column 31.calculator_Blank32A432Landscape_LinesDataset_1354253073631_260931: 122: unable to resolve class JRFillVariable  @ line 122, column 33.158 errors	at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:302)	at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:858)	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:548)	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:497)	at net.sf.jasperreports.compilers.JRGroovyCompiler.compileUnits(JRGroovyCompiler.java:109)	at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:201)	at net.sf.jasperreports.engine.JasperCompileManager.compile(JasperCompileManager.java:240)	at net.sf.jasperreports.engine.JasperCompileManager.compile(JasperCompileManager.java:226)	at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:481)	at id.co.bippo.salesorder.rs.hand.SalesOrderResource.doGeneratePdf(SalesOrderResource.java:158)[/code]

Add: mvn:org.codehaus.groovy/groovy-all/1.8.6

groovy-all artifact is required, groovy artifact will give:

Caused by: java.lang.IncompatibleClassChangeError: Found class org.objectweb.asm.ClassVisitor, but interface was expected        at org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:131)        at org.codehaus.groovy.control.CompilationUnit$14.call(CompilationUnit.java:767)        at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:967)        at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:546)        at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:524)        at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:501)        at net.sf.jasperreports.compilers.JRGroovyCompiler.compileUnits(JRGroovyCompiler.java:109)        at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:201)        at net.sf.jasperreports.engine.JasperCompileManager.compile(JasperCompileManager.java:240)        at net.sf.jasperreports.engine.JasperCompileManager.compile(JasperCompileManager.java:226)        at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:481)        at id.co.bippo.salesorder.rs.hand.SalesOrderResource.doGeneratePdf(SalesOrderResource.java:180)        at id.co.bippo.salesorder.rs.hand.SalesOrderResource.printAsPdfFile(SalesOrderResource.java:130)        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_07]        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_07]        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_07]        at java.lang.reflect.Method.invoke(Method.java:601)[:1.7.0_07]        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)        ... 46 more[/code]

Since JasperReports uses Thread Context Class Loader, you must manage the TCCL, e.g. :

@GET @Path("download/{id}")

public Response downloadAsPdfFile(@PathParam("id") @Nonnull final String salesOrderId) {

final SalesOrder salesOrder = salesOrderRawRepo.findOne(salesOrderId);

Preconditions.checkNotNull(salesOrder, "Cannot find sales order %s", salesOrderId);

// TODO: do not hardcode mall name

final String fileName = "Berbatik_invoice_" + salesOrder.getFormalId() + "_" + new SimpleDateFormat("dd-MM-yyyy").format(new Date()) + ".pdf";

try {

final StreamingOutput entity = doGeneratePdf(salesOrder.getFormalId(), salesOrder.getOrderStatus());

return Response.ok(entity, "application/pdf")

.header("Content-Disposition", "attachment;filename="" + fileName + """)

.build();

} catch (Exception e) {

log.error("Can't print Invoice for SalesOrder IDs: " + salesOrder.getFormalId(), e);

throw new RuntimeException("Can't print Invoice for SalesOrder IDs: " + salesOrder.getFormalId(), e);

}

}

 

/**

* @param salesOrder

* @return

* @throws JRException

*/

protected StreamingOutput doGeneratePdf(final String formalId, final OrderStatus status)

throws JRException {

final Map param = new HashMap();

param.put("formalId", formalId);

param.put("orderStatus", status.name());

 

final InputStream reportStream;

 

String reportName = "/id/co/bippo/salesorder/rs/hand/Invoice.jrxml";

log.debug("Printing {}", reportName);

reportStream = getClass().getResourceAsStream(reportName);

Preconditions.checkNotNull(reportStream, "Cannot load " + reportName);

 

// TODO: This is just a workaround for JasperReports/Groovy bug in OSGi

final ClassLoader oldCcl = Thread.currentThread().getContextClassLoader();

JasperReport report;

try {

Thread.currentThread().setContextClassLoader(SalesOrderResource.class.getClassLoader());

report = JasperCompileManager.compileReport(reportStream);

} finally {

Thread.currentThread().setContextClassLoader(oldCcl);

}

 

final MongoDbConnection mongoDbConn = new MongoDbConnection(salesOrderMongoUri,

salesOrderMongoUsername, salesOrderMongoPassword);

final JasperPrint print = JasperFillManager.fillReport(report, param,

mongoDbConn);

final StreamingOutput entity = new StreamingOutput() {

@Override

public void write(OutputStream output) throws IOException,

WebApplicationException {

try {

JasperExportManager.exportReportToPdfStream(print, output);

} catch (JRException e) {

log.error("Can't write Invoice As Streaming Output" + print, e);

throw new RuntimeException("Can't write Invoice As Streaming Output" + print, e);

}

}

};

return entity;

}


 

Reference:

  1. http://community.jaspersoft.com/questions/532797/groovy-compiler-classpath-osgi

  2. http://community.jaspersoft.com/jasperreports-library/issues/5014

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...