Sunday, November 30, 2008

RCP Plugin eclipse classloader 研究笔记2
RCP Plugin eclipse classloader 研究笔记
Eclipse插件开发中对于Jar包和类文件引用的处理(彻底解决插件开发中的NoClassDefFoundError问题)(转载)
目的Eclipse插件开发中,经常要引用第三方包或者是引用其他插件中的类,由于插件开发环境引用类路径的设置和运行平台引用类路径的设置不同,经常导致开发过程OK,一旦运行则出现NoClassDefFoundError的问题。本文的目的是全面分析各种情况下类路径的设置,以避免这个问题的出现。

说明Jar包和类路径实际上是一个概念,比如类com.bbebfe.Test.class打包为test.jar包,添加类引用就直接添加test.jar包。而如果是添加类文件路径,则添加包目录的上级目录,比如lib/com/bbebfe/Test.class,则添加lib文件夹,而不是com文件夹。在此后的例子中都只说明Jar包的形式。


分析Eclipse插件开发对于Jar包的引用主要有三种原因:

1. 插件引用第三方包(普通的jar包或者类文件,不是插件)。

a) 开发环境引用配置,在prject -> properties -> Java build path中设置。

b) 运行环境引用配置,在plugin manifest编辑器的Runtime选项卡下的classpath中添加tset.jar包的引用(在MANIFEST.MF中表现为Bundle-ClassPath: lib/test.jar, plugin.xml表现为<runtime>节下的引用

i. 类文件在lib目录下,如下的设置导出lib目录下所有目录:

<runtime>

<library name="lib/">

<export name="*"/>

</library>

</runtime>

ii. test.jarlib目录下:

<runtime>

<library name="lib/test.jar">

<export name="*"/>

</library>

</runtime>

iii. 实际上上面的设置可以简化为:

<runtime>

<library name="lib/"/>


</runtime>

或者

<runtime>

<library name="lib/test.jar"/>

</runtime>


默认即导出lib目录下的所有包和jar下的所有包


实际上,执行b)项设置后,会自动执行a)项设置,使开发环境和运行环境同时有效。

2. 插件B引用插件工程A(非Eclipse插件,而是自己另外一个插件项目中的类)

a) 首先必须将A中的B需要的类暴露(export)出来

i. 如果有MANIFEST.MF文件,则表现为plugin manifest编辑器中runtime节的exported packages,通过这里添加需要export的包。在manifest.mf文件中是Export-Package: com.bbebfe

ii. 如果只有plugin.xml,则表现为plugin manifest编辑器中runtime节的library visibilityplugin.xml文件中表现为

<runtime>

<library>

<export name=”com.bbebfe.*”/>

...

b) B插件工程的plugin manifest编辑器中的dependencies选项卡中添加对A插件的引用(这要求运行对话框中的plugins列表的workspace plugins中必须包含A插件)。

c) 如果B工程是一个RCP工程,则必须在product编辑器的configuration选项卡中包含A插件工程。

3. 插件B引用Eclipse插件A的类。

a) Eclipse插件中的类都是Exported,因此这步省略。

b) B插件工程的plugin manifest编辑器中的dependencies选项卡中添加对A插件的引用(这要求preferences -> plugin development -> target目标平台必须包含A插件,且运行对话框的plugins列表中的target platform中必须选中A插件)。

总结:如果B插件引用的A也是一个插件,则A必须出现在B插件的plugin dependencies引用中,而不是其他地方,否则肯定会出现运行时NoClassDefFoundError问题(因此必须在plugin manifest编辑器的dependencies选项卡下进行设置)。而且只需要在这里设置的设置对开发环境和运行环境同时有效)


举例

开发一个SQL的编辑器插件,扩展名为sql,但运行后,用file -> open file...打开test.sql文件,Activator能够构造,但编辑器打不开,添加调试信息,发现ZSqlEditor类根本没有构造。也没有任何错误信息提示。因此判断错误发生在系统加载插件类的过程中(EclipseJava反射从磁盘动态加载插件的类文件)。

打开runtime workbench下的.log文件,发现Eclipse在加载插件时出现NoClassDefFoundError,如下:

java.lang.NoClassDefFoundError: org/eclipse/jface/text/source/ISourceViewer

但是开发过程中并没有提示错误,打开目标平台设置,org.eclipse.jface.text插件也在列表中选中。

经过检查发现,开发过程中在project->properties中对org.eclipse.jface.text_3.2.2.r322_v20070104.jar(插件)的引用是定位到磁盘的硬引用。而不是出现在plugin dependencies中,造成了运行时找不到类的错误。解决方法如下:

a) 将这个硬引用删除。

b) 使用plugin manifest编辑器下的dependencies选项卡添加对org.eclipse.jface.text插件的引用。问题解决。(或者在plugin.xml节中或者在MANIFEST.MFrequire-bundle节中添加对org.eclipse.jface.text插件的引用也可)

Friday, November 21, 2008

需要把以下的jar包包含到buid path里面来,才能顺利的运行JFace的程序。eclipse的版本是3.2以上

\eclipse\plugins\org.eclipse.text_3.4.0.v20080605-1800.jar
\eclipse\plugins\org.eclipse.jface.text_3.4.1.r341_v20080827-1100.jar
\eclipse\plugins\org.eclipse.jface_3.4.1.M20080827-2000.jar
\eclipse\plugins\org.eclipse.swt_3.4.1.v3449c.jar
\eclipse\plugins\org.eclipse.core.commands_3.4.0.I20080509-2000.jar
\eclipse\plugins\org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
\eclipse\plugins\org.eclipse.swt.win32.win32.x86_3.4.1.v3449c.jar

Tuesday, November 18, 2008

Ajax radio button bug

在一个项目里需要用JavaScript动态建立radio buttons,然后替换span element下的内容,在IE里能显示出来,可就是无法做选择,郁闷了半天,后来查网上资料发现是IE的BUG,说是 "IE doesn’t allow the name attribute to be changed after the element is created“,可我试了下Checkbox就不存在此问题。

原代码:
Java代码
  1. function createCxtjRadioButtons(data,cxtjId,cxtjTagId){
  2. var tagCxtj = document.getElementById(cxtjTagId);
  3. tagCxtj.removeChild(tagCxtj.childNodes[0]);
  4. for (var key in data) {
  5. var val = data[key];
  6. var input = document.createElement("input");
  7. input.setAttribute("name",cxtjId);
  8. input.setAttribute("type","radio");
  9. input.setAttribute("value",key);
  10. tagCxtj.appendChild(input);
  11. var label = document.createElement("label");
  12. label.setAttribute("for",input_id);
  13. label.appendChild(document.createTextNode(val));
  14. tagCxtj.appendChild(label);
  15. }
  16. }

解决后:
Java代码
  1. function createCxtjRadioButtons(data,cxtjId,cxtjTagId){
  2. var tagCxtj = document.getElementById(cxtjTagId);
  3. tagCxtj.removeChild(tagCxtj.childNodes[0]);
  4. for (var key in data) {
  5. var val = data[key];
  6. var input = createElement("input", cxtjId);
  7. input.setAttribute("type","radio");
  8. input.setAttribute("value",key);
  9. tagCxtj.appendChild(input);
  10. var label = document.createElement("label");
  11. label.setAttribute("for",input_id);
  12. label.appendChild(document.createTextNode(val));
  13. tagCxtj.appendChild(label);
  14. }
  15. }

  16. function createElement(type, name) {
  17. var element = null;

  18. try {
  19. // First try the IE way; if this fails then use the standard way
  20. element = document.createElement('<'+type+' name="'+name+'">');
  21. } catch (e) {
  22. // Probably failed because we’re not running on IE
  23. }
  24. if (!element) {
  25. element = document.createElement(type);
  26. element.name = name;
  27. }
  28. return element;
  29. }

参考:
1、http://www.thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/
2、http://alt-tag.com/blog/archives/2006/02/ie-dom-bugs/

Friday, November 14, 2008

ajax html

ajax 时
request.open("GET", url, true);
request.send(null);
request.onreadystatechange = addrOper; //-->这个函数不能有参数,对于有传参数的,可以function(){addroper(id);}来写

js删除节点n.parentNode.removeChild(n)
document.getElementById("")返回的不是 集合

js中跳出确定对话框
if(confirm("Are you sure to delete this address forever?")){
}
}else{
}

childNodes—返回节点到子节点的节点列表
firstChild—返回节点的首个子节点。
lastChild—返回节点的最后一个子节点。
nextSibling—返回节点之后紧跟的同级节点。
nodeName—返回节点的名字,根据其类型。
nodeType—返回节点的类型。
nodeValue—设置或返回节点的值,根据其类型。
ownerDocument—返回节点的根元素(document对象)。
parentNode—返回节点的父节点。
previousSibling—返回节点之前紧跟的同级节点。
text—返回节点及其后代的文本(IE独有)。
xml—返回节点及其后代的XML(IE独有)。

xampp apache tomcat

使用Apache服务器整合TomcatPHP5讲 述了整合jsp和php服务的方法,但是,在应用中发现,php和mysql连接始终服务解决,总是提示:无法载入 mysql 扩展。于是,无奈下希望使用php和mysql整合更方便的apache friend的xampp套件,然后再整合tomcat达到目的。整合过程如下:

1 安装好xampp,测试PHP运行正常,安装tomcat(这里我用6.0)。下载【使用Apache服务器整合Tomcat和PHP5】附件中的apache和tomcat连接模块mod_jk-1.2.26-httpd-2.2.4.so,放到xampp\apache\modules中。

2 修改xampp\apache\conf中的配置文件httpd.conf,添加下列内容:
复制内容到剪贴板
代码:


AllowOverride None
Options FollowSymLinks
Order allow,deny
allow from all
复制内容到剪贴板
代码:
######################################################################
# jink2005 08-08-01
# http://hi.baidu.com/80love81/blog/item/2c22d643ee0d191172f05d64.html
#设置Apache与Tomcat之间的连接,让Apache遇到jsp文件时,在后台将其交由Tomcat去处理
LoadModule jk_module modules/mod_jk-1.2.26-httpd-2.2.4.so
#此处mod_jk的文件为你下载的文件
JkWorkersFile "D:/Program Files/Apache Software Foundation/Tomcat 6.0/conf/workers.properties"
#指定tomcat监听配置文件地址
JkLogFile "D:/Program Files/Apache Software Foundation/Tomcat 6.0/logs/mod_jk2.log"
#指定日志存放位置
JkLogLevel info
#----------------------------------------------------------
JkMount /servlet/* ajp13
#让Apache支持对servlet传送,用以Tomcat解析
JkMount /*.jsp ajp13
#让Apache支持对jsp传送,用以Tomcat解析
JkMount /*.do ajp13
#让Apache支持对.do传送,用以Tomcat解析
######################################################################
3 添加index.jsp
复制内容到剪贴板
代码:

DirectoryIndex index.jsp index.php index.php4 index.php3 index.cgi index.pl index.html index.htm index.shtml index.phtml
至此,使用http://localhost/index.jsp,就可访问E:/AIWEB/WebContent/index.jsp了。虚拟主机的配置方法见【使用Apache服务器整合Tomcat和PHP5】,此不再讲述。

Wednesday, November 12, 2008

usb3.0

在WinHEC2008上,USB开发者论坛主席Jeff Ravencraft透露,新的USB 3.0详细计划书将在11月17日的超速USB开发者大会上公布。USB 3.0也称为SuperSpeed USB,它的传输速度能达到5Gbps.提供高达600MB/S的带宽,并且可以向下兼容1.0版和2.0版。

微软称他们至少要在Vista实现对USB3.0的支持,从微软在WinHEC 2008上的演示数据看来,USB 3.0的速度已经大有提高,拷贝25GB的高清电影仅需70秒: