最近要在项目中添加报表功能,选用了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();
}
}