srhaque Posted November 23, 2018 Share Posted November 23, 2018 I am new to Jaspersoft, but an experienced programmer. I have some data in a main report field which is in the form of a string-encoded JSON. In Java, the data looks like this:jshell> datadata ==> "{"A": {"GP": ...}, "C": {"GP": "8333.33", ...}}"[/code]For clarity, the the corresponding JSON is:{"A": {"GP": ..., "LEL-YTD": ...}, "C": {"GP": ..., "LEL-YTD": ...}}"[/code]For reporting, I need to flatten keys ("A" and "C" here) into the child dicts, and convert this into an array (one entry for each of A and C) like this:[{"Letter": "A", "GP": ..., "LEL-YTD": ...}, {"Letter": "C", "GP": ..., "LEL-YTD": ...}]"[/code]So, I defined a datasource to fetch the "parent_json" field, and map the content into the array-of-maps form using the following Java 10 code...<import value="java.util.HashMap"/><import value="com.fasterxml.jackson.core.type.TypeReference"/><import value="com.fasterxml.jackson.databind.ObjectMapper"/><import value="net.sf.jasperreports.engine.*"/><import value="net.sf.jasperreports.engine.data.*"/>...<dataSourceExpression><![CDATA[ new JRMapArrayDataSource( new HashMap<String, Map<String,String>>( new ObjectMapper().readValue($F{parent_json}.getBytes("UTF-8"), new TypeReference<Object>(){}) ). entrySet(). stream(). map(x -> x.getValue().put("Letter", x.getKey()) == "" ? x : x). map(x -> x.getValue()).toArray() )]]></dataSourceExpression>[/code]which seems like it ought to work, except that when looked at in the Java debugger, the dataset field names are:Incomplete; the original map had 9 keys and the transformed map therefore has 10, whereas the debugger shows only 8 fields.Sometimes wrong. Of the 8 fields, 4 of them have recognisable names such as "LEL-YTD" and "Ee-YTD" wheras the other 4 are called "A_key", "M_key", "Z_key" and "J_key".Outside the debugger, I've confirmed the names of the fields in Jaspersoft using <textFieldExpression><![CDATA["$F{A_key}"]]></textFieldExpression> and so on. Also, in jshell, the transformed data has the 10 fields I expect:jshell> new HashMap<String, Map<String,String>>(new ObjectMapper().readValue(data.getBytes(), new TypeReference<Object>(){})).entrySet().stream().map(x->x.getValue().put("Letter",x.getKey())==""?x:x).map(x->x.getValue()).iterator().next().keySet()$35 ==> [GP, Er, Ee, GP-YTD, Ee-YTD, Er-YTD, LEL-YTD, LEL-PT-YTD, PT-UEL-YTD, Letter][/code]Any thoughts as to what I might be doing wrong?Thanks, ShaheedP.S. I should add, when trying to use this datasource, even with one of the keys the Java debugger shows, I do get an error on the main P60 report like this:Exception in thread "main" java.lang.NoClassDefFoundError: P60_1542977708345_445958$1 (wrong name: P60_1542977708345_445958) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) at net.sf.jasperreports.engine.util.JRClassLoader.loadClass(JRClassLoader.java:355) at net.sf.jasperreports.engine.util.JRClassLoader.loadClassFromBytes(JRClassLoader.java:279) at net.sf.jasperreports.engine.design.JRAbstractJavaCompiler.loadEvaluator(JRAbstractJavaCompiler.java:105) at net.sf.jasperreports.engine.design.JRAbstractCompiler.loadEvaluator(JRAbstractCompiler.java:351) at net.sf.jasperreports.engine.JasperCompileManager.getEvaluator(JasperCompileManager.java:381) at net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(JRFillDataset.java:487) at net.sf.jasperreports.engine.fill.BaseReportFiller.<init>(BaseReportFiller.java:168) at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:273) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:79) at net.sf.jasperreports.engine.fill.JRFiller.createBandReportFiller(JRFiller.java:251) at net.sf.jasperreports.engine.fill.JRFiller.createReportFiller(JRFiller.java:272) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:156) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:145) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:758) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:1074) at de.cenote.jasperstarter.Report.fillInternal(Report.java:312) at de.cenote.jasperstarter.Report.fill(Report.java:272) at de.cenote.jasperstarter.App.processReport(App.java:224) at de.cenote.jasperstarter.App.main(App.java:109)but I assume that this is metrely a consequence of the datasource not working as expected. Link to comment Share on other sites More sharing options...
srhaque Posted November 25, 2018 Author Share Posted November 25, 2018 OK, I finally figured out that the field names were actually in the .jrxml I had inhierited (and not introspected from the sub dataset as I had guessed). So, I fixed them. However, now I am getting an exception similar to the one in the epilogue of my original post. The main difference is that I get multiple instances of this error on a preview run:java.lang.NoClassDefFoundError: P60_1543155161004_307909 (wrong name: P60_1543155161004_307909$2) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at net.sf.jasperreports.engine.util.JRClassLoader.loadClass(JRClassLoader.java:338) at net.sf.jasperreports.engine.util.JRClassLoader.loadClassFromBytes(JRClassLoader.java:262) at net.sf.jasperreports.engine.design.JRAbstractJavaCompiler.loadEvaluator(JRAbstractJavaCompiler.java:105) at net.sf.jasperreports.engine.design.JRAbstractCompiler.loadEvaluator(JRAbstractCompiler.java:351) at net.sf.jasperreports.engine.JasperCompileManager.getEvaluator(JasperCompileManager.java:381) at net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(JRFillDataset.java:487) at net.sf.jasperreports.engine.fill.JRFillDataset.createCalculator(JRFillDataset.java:477) at net.sf.jasperreports.engine.fill.JRParameterDefaultValuesEvaluator.evaluateParameterDefaultValues(JRParameterDefaultValuesEvaluator.java:82) at com.jaspersoft.studio.utils.ExpressionUtil.initBuiltInParameters(ExpressionUtil.java:399) at com.jaspersoft.studio.editor.preview.view.control.ReportController$1.run(ReportController.java:381) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56)[/code]I'd appreciate any insights on offer (and am happy to provide the .jrxml and .json data files as needed). Link to comment Share on other sites More sharing options...
srhaque Posted November 25, 2018 Author Share Posted November 25, 2018 OK, from what I can see in the debugger, I *think* Jaspersoft is getting confused between the loaded bytecode for the main and child datasets. The first clue for this is actually in the exception message: note how the error message refers to "name$2" and "name": IIRC, this is typically used for nested classes. The second clue is that in the debugger, when I step into JRClassLoader.loadClass for the main dataset, the byte array containing the class code, when viewed as text looks like this:���� 4 P60_1543161222131_631751$1 -com/fasterxml/jackson/core/type/TypeReference this$0 LP60_1543161222131_631751; <init> (LP60_1543161222131_631751;)V Code ()V LineNumberTableSourceFile P60_1543161222131_631751 Signature �Lcom/fasterxml/jackson/core/type/TypeReference<Ljava/util/HashMap<Ljava/lang/String;Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;>;>; EnclosingMethod evaluate (I)Ljava/lang/Object; InnerClasses &Note the reference to "HashMap<Ljava/lang/String;Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;>;>". This is part of the definition for the sub dataset, NOT the main dataset. Of course this is just a guess on my part, but I am really beyond my rusty knowledge of Java... 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