How to get grails rendering and grails-melody (java melody) working together
1I’m using grails rendering 0.4.4 plugin to render some HTML(GSP) to PDF wich uses the underlying iText library in version 2.1.0.
I also wanted to monitor my webapplication with java melody, so i decided to install grails-melody. This plugin comes with pdf-export for the java melody reports and uses also the iText library, but in the newer version 2.1.7.
Normally this shouldn’t be a problem, because you can exclude the older or newer library in the dependencies of your grails application, but in this case there is a binary incompatibility between the different Flying Saucer binaries. So you get the following exception:
java.lang.NoSuchMethodError – com.lowagie.text.pdf.BaseFont.getCharBBox(C)….
Line | Method ->> 195 | doFilter in PageFragmentCachingFilter.java - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 63 | doFilter in AbstractFilter.java | 151 | invoke . in net.bull.javamelody.JspWrapper | 271 | invoke in net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler | 206 | doFilter in net.bull.javamelody.MonitoringFilter | 179 | doFilter in '' | 895 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker | 918 | run in '' ^ 680 | run . . in java.lang.Thread Caused by ControllerExecutionException: Runtime error executing action ->> 195 | doFilter in PageFragmentCachingFilter.java - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 63 | doFilter in AbstractFilter.java | 151 | invoke . in net.bull.javamelody.JspWrapper | 271 | invoke in net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler | 206 | doFilter in net.bull.javamelody.MonitoringFilter | 179 | doFilter in '' | 895 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker | 918 | run in '' ^ 680 | run . . in java.lang.Thread Caused by InvocationTargetException: null ->> 195 | doFilter in PageFragmentCachingFilter.java - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 63 | doFilter in AbstractFilter.java | 151 | invoke . in net.bull.javamelody.JspWrapper | 271 | invoke in net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler | 206 | doFilter in net.bull.javamelody.MonitoringFilter | 179 | doFilter in '' | 895 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker | 918 | run in '' ^ 680 | run . . in java.lang.Thread Caused by NoSuchMethodError: com.lowagie.text.pdf.BaseFont.getCharBBox(C)[I ->> 679 | setMetricDefaults in org.xhtmlrenderer.pdf.ITextFontResolver$FontDescription - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 610 | in '' | 410 | addCourier in org.xhtmlrenderer.pdf.ITextFontResolver | 390 | createInitialFontMap in '' | 52 | . in '' | 115 | in org.xhtmlrenderer.pdf.ITextRenderer | 102 | . in '' | 34 | doRender in PdfRenderingService.groovy | 43 | render . in RenderingService.groovy | 37 | render in '' | 35 | render . in '' | 65 | render in '' | 165 | doCall . in GrailsMelodyGrailsPlugin$_closure4_closure15_closure16 | 59 | doCall in RenderingGrailsPlugin$_closure3 | 366 | getTickets in ShopController.groovy | 195 | doFilter in PageFragmentCachingFilter.java | 63 | doFilter in AbstractFilter.java | 151 | invoke in net.bull.javamelody.JspWrapper | 271 | invoke . in net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler | 206 | doFilter in net.bull.javamelody.MonitoringFilter | 179 | doFilter in '' | 895 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker | 918 | run . . in '' ^ 680 | run in java.lang.Thread
To fix this you have to recompile Flying Saucer R8 against iText 2.1.x and it will work fine. But you don’t have to do it yet, because you can use the library from here. Just place it in your „lib“ folder as „core-renderer-R8.jar“ in your grails project and edit your dependencies.
BuildConfig.groovy:
dependencies { // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. runtime ( 'org.xhtmlrenderer:core-renderer:R8', 'com.lowagie:itext:2.1.7') } plugins { runtime(':rendering:0.4.4') { exclude 'itext' } compile ":grails-melody:1.45" }
Now everything works as expected with the newest iText version (old license tree). I’m able to use the rendering plugin to generate pdf exports and java melody to get application reports.
Hi,
I tried your solution, but it doesn’t work for me. It seems like it doesn’t found some classes from the core-renderer. I have no experiences with grails dependencies, so I can’t figure out how to solve this problem. Could you please direct me in right direction? My stack trace follows:
| Error 2013-10-17 09:23:53,435 [http-bio-8090-exec-4] ERROR datauri.DataUriAwareITextUserAgent – exception creating image from data uri (will use empty image): grails.plugin.rendering.datauri.DataUri@6beaaf10
Message: Could not find matching constructor for: org.xhtmlrenderer.resource.ImageResource(org.xhtmlrenderer.pdf.ITextFSImage)
Line | Method
->> 50 | getImageResource in grails.plugin.rendering.datauri.DataUriAwareITextUserAgent
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
| 57 | createReplacedElement in org.xhtmlrenderer.pdf.ITextReplacedElementFactory
| 1437 | calcMinMaxWidth . . . . . . . in org.xhtmlrenderer.render.BlockBox
| 1582 | calcMinMaxWidthInlineChildren in “
| 1479 | calcMinMaxWidth . . . . . . . in “
| 1357 | calcShrinkToFitWidth in “
| 869 | calcShrinkToFitWidthIfNeeded in “
| 766 | layout in “
| 732 | layout . . . . . . . . . . . in “
| 79 | layoutFloated in org.xhtmlrenderer.layout.LayoutUtil
| 848 | processOutOfFlowContent . . . in org.xhtmlrenderer.layout.InlineBoxing
| 287 | layoutContent in “
| 939 | layoutInlineChildren . . . . in org.xhtmlrenderer.render.BlockBox
| 47 | layout in org.xhtmlrenderer.render.AnonymousBlockBox
| 301 | layoutBlockChild0 . . . . . . in org.xhtmlrenderer.layout.BlockBoxing
| 279 | layoutBlockChild in “
| 89 | layoutContent . . . . . . . . in “
| 923 | layoutChildren in org.xhtmlrenderer.render.BlockBox
| 803 | layout . . . . . . . . . . . in “
| 732 | layout in “
| 301 | layoutBlockChild0 . . . . . . in org.xhtmlrenderer.layout.BlockBoxing
| 279 | layoutBlockChild in “
| 89 | layoutContent . . . . . . . . in “
| 923 | layoutChildren in org.xhtmlrenderer.render.BlockBox
| 803 | layout . . . . . . . . . . . in “
| 732 | layout in “
| 301 | layoutBlockChild0 . . . . . . in org.xhtmlrenderer.layout.BlockBoxing
| 279 | layoutBlockChild in “
| 89 | layoutContent . . . . . . . . in “
| 923 | layoutChildren in org.xhtmlrenderer.render.BlockBox
| 803 | layout . . . . . . . . . . . in “
| 732 | layout in “
| 213 | layout . . . . . . . . . . . in org.xhtmlrenderer.pdf.ITextRenderer
| 37 | doRender in grails.plugin.rendering.pdf.PdfRenderingService
| 43 | render . . . . . . . . . . . in grails.plugin.rendering.RenderingService
| 37 | render in “
| 35 | render . . . . . . . . . . . in “
| 65 | render in “
| 184 | doCall . . . . . . . . . . . in GrailsMelodyGrailsPlugin$_closure4_closure16_closure17
| 59 | doCall in RenderingGrailsPlugin$_closure3
| 287 | getReport . . . . . . . . . . in cz.eyedea.MatchesController
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . . . . . . . . . . in grails.plugin.cache.web.filter.AbstractFilter
| 151 | invoke in net.bull.javamelody.JspWrapper
| 277 | invoke . . . . . . . . . . . in net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler
| 208 | doFilter in net.bull.javamelody.MonitoringFilter
| 181 | doFilter . . . . . . . . . . in “
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 679 | run in java.lang.Thread