[Java] JasperReports et XML

J’ai un problème avec la bibliothèque JasperReports, j’ai envoyé un message à la mailing-list du projet mais celui-ci est en cours de validation (j’ai reçu un mail ce matin) et je n’ai rien trouvé sur le forum.

En gros, cette bibliothèque permet grâce à un fichier source au format XML de créer des rapport que l’on peut visualiser, imprimer, exporter en PDF, en HTML, en CVS, en XLS, …
J’ai un soucis avec un classe de cette bibliothèque JRPrintXmlLoader, celle qui charge un fichier XML et qui produit un JasperPrint utilisable pour imprimer, exporter en PDF, …

Voici le haut de l’exeption lorsque je tente d’apeller la méthode statique JRPrintXmlLoader.load(String sourceFile) :

java.lang.NoSuchMethodException: No such accessible method: addElement() on object: net.sf.jasperreports.engine.xml.JRPrintXmlLoader at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:248) at org.apache.commons.digester.SetNextRule.end(SetNextRule.java:260) at org.apache.commons.digester.Digester.endElement(Digester.java:1036) at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source) at org.apache.xerces.impl.dtd.XMLDTDValidator.endNamespaceScope(Unknown Source) at org.apache.xerces.impl.dtd.XMLDTDValidator.handleEndElement(Unknown Source) at org.apache.xerces.impl.dtd.XMLDTDValidator.endElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)

Vous pouvez voir qu’il s’agit bien d’un problème avec XML, le soucis c’est que j’ai bien toutes les bibliothèques requises dans le classpath, y a-t-il une autre option à fournir à la JVM pour l’utilisation de Xerces ? Est-ce que j’ai raté quelque chose ?

Bien sur, rien n’est marqué dans leur FAQ, on trouve ce bref Howto qui ne marche pas avec la même exception :

[quote]4. Viewing a report design
  Reports designs can be viewed using the net.sf.jasperreports.view.JasperDesignViewer application.
  In its main() method, it receives the name of the file which contains the report design to view.
  This can be the XML file itself, or the compiled report design.[/quote]

Voici la commande :

java -classpath dist\jasperreports-0.6.8.jar;lib\commons-beanutils-1.5.jar; lib\commons-collections-2.1.jar;lib\commons-digester-1.3.jar; lib\commons-logging-1.0.2.jar;lib\commons-logging-api-1.0.2.jar; lib\hsqldb-1.61.jar;lib\itext-1.01.jar;lib\jdt-compiler.jar; lib\poi-2.0-final-20040126.jar;lib\servlet.jar;lib\xalan.jar;lib\xercesImpl.jar; lib\xmlParserAPIs.jar net.sf.jasperreports.view.JasperViewer -Fd:\test.jrxml -XML

Ce genre d’erreur indique que la JVM a vu un appel à une méthode (en l’occurrence addElement()) mais qu’elle n’a pas trouvé la méthode dans la classe en question. JRPrintXmlLoader semble donc ne pas avoir cette méthode.

Or, à en juger la Javadoc de la méthode (API version 0.6.8 sur le net), cette méthode n’est pas présente. Du coup, je pencherais plutôt pour un bug (un mauvais appel de la méthode), dans la mesure où il ne semble pas que la dernière version de cette classe contienne cette méthode (si tel avait été le cas, on aurait pu pencher pour un problème de version entre librairies).

A mon avis, il faut attendre la réponse à ton mail sur la mailing list…

J’ai testé aussi avec la 0.6.7 et c’est la même chose, je n’ai pas eu le courage d’aller plus loin, ca me semble louche quand même.

Je fais des tests pour créer des JasperReport avec cette manière :

InputStream reportStream = Session session = HibernateUtil.currentSession();  JasperDesign jasperDesign = (JasperDesign)JRXmlLoader.load("d:\\basic.xml");  JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);    Map parameters = new HashMap();  parameters.put("title", "The Cats List");  List cats = session.find("select client from TClient as client");    JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(cats);  JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,    parameters, ds);    JasperViewer.viewReport(jasperPrint);

Je n’ai pas encore réussi à faire marcher cet exemple mais la fonction JasperDesign JRXmlLoader.load(“d:\basic.xml”); ne plante pas.

Edit:

Voilà, ca marche, J’ai réussi à adapter l’exemple ci-dessus.