最近要在项目中添加报表功能,选用了eclipse的开源插件:BIRT.
BIRT即Business Intelligence and Reporting Tools商业智能报表工具
http://www.eclipse.org/birt/phoenix/官网提供了比较全的入门资料.
MyEclipse 2013中已经集成了BIRT,通过IDE创建了一个Reprot Project,并设计了一张简单的报表,报表显示一切正常.之后按Report Project的目录结构,把所有相关的文件都拷贝到web项目中,结果访问报表时,总出现:
org.eclipse.birt.report.engine.api.EngineException: Invalid Javascript expression: dataSetRow["type"].
Invalid Javascript expression: dataSetRow["type"].
刚开始以为自己搭建的BIRT环境有问题,可是把从官网上下载下来的test.rptdesign这个纯文本报表放到项目中访问时一切正常.就觉得很奇怪,想不明白是什么问题.
经过在网上一番查询,幸运的让我找着一个与这问题相同的http://www.blogjava.net/vcok/archive/2009/08/27/292744.html
原来是jar包冲突,可这上面说的是JS_1.6R2.jar 和 js.jar冲突,都是关于org.mozilla.javascript.xxxx的字节码文件,BIRT中用的是js.jar,把JS_1.6R2.jar删了就OK了,我就去查看自己项目中的lib,没找着JS_1.6R2.jar,之后就在MyEclipse中通过查找类:
Ctrl + Shift + T,或者是[Navigate]--->[Open Type],
输入org.mozilla.javascript
还真发现一个叫batik-js.jar的jar包中也有同样的字节码文件,果断删掉它,再试一切OK.
当然后续就要解决缺少batik-js.jar包所产生的问题了……
附上一个检测指定目录下jar包中冲突的类文件的程序
import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * 查找项目lib目录下有冲突的jar文件 * * @author Administrator * */ public class FindConflictJar { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { String lib = "D:\\Program Files (x86)\\apache-tomcat-6.0.16\\webapps\\bocloud-server\\WEB-INF\\lib"; find(lib); } public static void find(String libPath) throws IOException { // 指定要检测的lib路径 File file = new File(libPath); /* * 声明一个容器来存放lib下的jar文件信息 * Map中的key为class文件的完整名称,如:java.lang.String.Class * Map中的Value为HashSet<String>,用来存放class文件所在jar文件的名称 * 最终通过判断HashSet的大小来判定有冲突的Jar文件 */ Map<String, HashSet<String>> jarMap = new HashMap<String, HashSet<String>>(); // 指定的目录存在 if (null != file && file.exists() && file.isDirectory()) { // 文件清单 File[] jarFile = file.listFiles(); // 依次遍历每个文件 for (File f : jarFile) { // 只对jar文件进行操作 if (f.isFile() && f.getName().endsWith(".jar")) { // 获取jar文件对象 JarFile jar = new JarFile(f); // 获取jar包中的元素 Enumeration<JarEntry> enumJar1 = jar.entries(); // 统计jar包中class文件的数量 int classCount = 0; while (enumJar1.hasMoreElements()) { JarEntry je = enumJar1.nextElement(); if (je.getName().endsWith(".class")) { classCount++; } } // 以class文件的完整名为key,进行统计 Enumeration<JarEntry> enumJar2 = jar.entries(); while (enumJar2.hasMoreElements()) { JarEntry je = enumJar2.nextElement(); // 只对class文件进行操作 if (je.getName().endsWith(".class")) { // 如果Map容器中已经有了该class文件,就将该jar文件名称存入HashSet中 if (jarMap.containsKey(je.getName())) { jarMap.get(je.getName()).add(f.getName() + "("+ classCount +")"); } else { HashSet<String> set = new HashSet<String>(); set.add(f.getName() + "("+ classCount +")"); jarMap.put(je.getName(), set); } } } } } } // 查找有冲突的class文件及其所在jar文件 Set<String> keys = jarMap.keySet(); // 声明一个容器保存有相同类文件的jar信息 List<String> list = new ArrayList<String>(); for (String s : keys) { if(jarMap.get(s).size() > 1) { HashSet<String> hsfile = jarMap.get(s); String sfiles = ""; for(String sf : hsfile) { sfiles = sfiles + sf + "\t"; } String temp = sfiles + "有重复类:" + s; list.add(temp); } } // 对jar信息进行排序以方便查看 Collections.sort(list); // 将信息写入D:\1.txt中 File f = new File("D:\\1.txt"); FileWriter write = new FileWriter(f); for (String sss : list) { write.append(sss + "\r"); } write.flush(); write.close(); } }