使用jasperreports4.0制作动态报表,生成jrxml文件后编译时,在普通app中通过,写进servlet时却报一些莫名其妙的错误,搞了好久,很郁闷,搞出来了那个内牛满面啊。。。。一定要写出来,以让后人少走弯路。
解决过程中遇到的错误主要有两个:
java.lang.IllegalArgumentException: When using array of Objects as the value of SCHEMA_SOURCE property , no two Schemas should share the same targetNamespace.
at org.apache.xerces.impl.xs.XMLSchemaLoader.processJAXPSchemaSource(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaLoader.loadSchema(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.findSchemaGrammar(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.commons.digester.Digester.parse(Digester.java:1647)
at net.sf.jasperreports.engine.xml.JRXmlLoader.loadXML(JRXmlLoader.java:241)
at net.sf.jasperreports.engine.xml.JRXmlLoader.loadXML(JRXmlLoader.java:228)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:216)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:170)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:154)
at net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(JasperCompileManager.java:85)
-------------------------------------------------------------------------------------------------------------------------------------------------
java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredElementImpl.getTextContent()Ljava/lang/String;
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamily(SimpleFontExtensionHelper.java:233)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamilies(SimpleFontExtensionHelper.java:204)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:173)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:142)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory.createRegistry(SimpleFontExtensionsRegistryFactory.java:63)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.instantiateRegistry(DefaultExtensionsRegistry.java:238)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.loadRegistries(DefaultExtensionsRegistry.java:213)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.loadRegistries(DefaultExtensionsRegistry.java:162)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getRegistries(DefaultExtensionsRegistry.java:132)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getExtensions(DefaultExtensionsRegistry.java:104)
at net.sf.jasperreports.engine.component.ComponentsEnvironment.findComponentBundles(ComponentsEnvironment.java:90)
at net.sf.jasperreports.engine.component.ComponentsEnvironment.getCachedComponentBundles(ComponentsEnvironment.java:78)
at net.sf.jasperreports.engine.component.ComponentsEnvironment.getComponentBundles(ComponentsEnvironment.java:66)
at net.sf.jasperreports.engine.xml.JRReportSaxParserFactory.getSchemaLocations(JRReportSaxParserFactory.java:157)
at net.sf.jasperreports.engine.xml.JRReportSaxParserFactory.configureParser(JRReportSaxParserFactory.java:138)
at net.sf.jasperreports.engine.xml.JRReportSaxParserFactory.createParser(JRReportSaxParserFactory.java:103)
at net.sf.jasperreports.engine.xml.JRXmlDigesterFactory.createParser(JRXmlDigesterFactory.java:1332)
at net.sf.jasperreports.engine.xml.JRXmlDigesterFactory.createDigester(JRXmlDigesterFactory.java:1307)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:205)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:170)
at net.sf.jasperreports.engine.xml.JRXmlLoader.load(JRXmlLoader.java:154)
at net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(JasperCompileManager.java:85)
由于与运行时有关,所以肯定是jar包冲突或者jar包版本问题,在网上找了一下,说是xml解析器类型问题,主要与系统运行时初始化解析器构造工厂SAXParserFactory的类型有关,SAXParserFactory主要有:
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl:SUN JDK自带的XML解析器
org.apache.xerces.jaxp.SAXParserFactoryImpl:xerces.jar包封装的XML解析器
如何在系统运行时指定XML解析器?
方法一、系统运行时可以通过调用:System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
或:
System.setProperty("javax.xml.parsers.SAXParserFactory","org.apache.xerces.jaxp.SAXParserFactoryImpl");
来设定相应的XML解析器;
方法二、生成jaxp.properties文件,在其中加入如下内容
javax.xml.parsers.SAXParserFactory = com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
或:
javax.xml.parsers.SAXParserFactory = org.apache.xerces.jaxp.SAXParserFactoryImpl
把它放到JAVA_HOME/lib下。
另外这次得到一个惨痛的教训,在调试jar冲突问题时,如果用的IDE是Eclipse,千万不要把怀疑有冲突的jar包放到WEB-INFO/lib下,eclipse不像Myeclipse,只要jar包放到该目录下即会自动引入classpath,而且在环境中根本看不到这些已经导入的资源。所以不把这些jar包移出WEB-INFO/lib目录,根本就是白忙活。