站点终于恢复了

非常感谢redphp.net,这家host不错。虽然源于国内无耻的严打,经过一点折腾,终于回到正常。我一个小小blog就这么麻烦,真不知道国内那些网站怎么过来的。

希望国内互联网环境能恢复理性健康。

用jconsole来管理WebSphere AppServer的MBean

最近需要在WebSphere中做点魔术,所以要使用WAS(WebSphere Application Server)中的管理能力。JMX是WAS的管理的核心,苦于WAS Mbean文档并不是那么详细,这个时候就可以使用jconsole了。jconsole是一个JDK自带的JMX兼容的JVM管理工具,可以用它来可视化的查看和操作Mbean。

在启动jconsole时需要一些WAS的jar,所以我这样来做:

1.创建一个文件夹,例如:C:\programs\jconsole

2.将一些需要的jar 拷贝进入到这个文件夹的libs中:

  • com.ibm.ws.admin.client_6.1.0.jar   (在<WAS_HOME>/runtimes)
  • ibmorbapi.jar  (在<WAS_HOME>/java/jre/lib)
  • ibmorb.jar (在<WAS_HOME>/java/jre/lib)
  • ibmcfw.jar (在<WAS_HOME>/java/jre/lib)

3.编写一个bat文件

set JAVA_HOME="C:\Program Files\Java\jdk1.6.0_16"
set WAS6.1_JARS=C:\programs\jconsole\libs
 
set BOOTJARS=%WAS6.1_JARS%\ibmorbapi.jar
set BOOTJARS=%BOOTJARS%;%WAS6.1_JARS%\ibmorb.jar
set BOOTJARS=%BOOTJARS%;%WAS6.1_JARS%\ibmcfw.jar
 
set CLASSPATH=%WAS6.1_JARS%\com.ibm.ws.admin.client_6.1.0.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\tools.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\jconsole.jar
 
%JAVA_HOME%\bin\jconsole  -J-Xbootclasspath/p:%BOOTJARS% -J-Djava.class.path=%CLASSPATH%

4.使用如下URL来远程连接WAS中的JMX server

service:jmx:iiop://localhost:2809/jndi/JMXConnector

其中这个端口号是RMI Connector的端口号,可以在启动的logs发现。

ADMC0026I:The RMI Connector is available at port  2809

或者到admin console中查看
Application servers > server1 > Administration Services > JMX connectors

好,这样就可以了。

一直在写

刚和同学聊天时,问我blog怎么好长时间都没有更新了。看了看上篇文章的日期,离现在也有两个月有余了,有些惭愧。最近在做一些有意思的技术调研,倒是会在接下来的文章中分享一些。其实这段日子也在写一些东西,不过不在自己的blog上面了罢了。

时间总是匆匆,让我们继续前行…

读《PPK on JavaScript》

PPK也是在JavaScript世界中的风云人物了,这位老兄对于浏览器端的技术以及各种浏览器的兼容性有极其丰富的经验。在这本书中,他谈了很多关于可访问性(Accessibility)和可用性(Usability)的一些问题,非常有趣。比如他说“不同的开发者以不同的方式诠释了JavaScript的目的。简单而形象地说就是:深受CSS革命影响的传统Web开发者们,创建的是瘦的、可访问性很强、乱糟糟的JavaScript代码;而来至服务器端开发的‘资深程序员们’用完美的面向对象代码、创建的是胖的、可访问性很差的Ajax客户端”。显然,ppk同学应该属于写乱糟糟但可访问性很好的人,而现在我做的大量事情却是后者。他更多相信现在的Ajax只是一种泡沫,当这个泡沫破灭并且大量‘资深服务器程序员’消失时,JS的开发者会更加注重可访问性。 可能体会不到ppk经历浏览器各种痛苦的经历,但是总体来说浏览器都在坚定地遵循Web标准,JavaScript的支持也会成为浏览器必备要求。anyway,事情总在发展,好戏在后头。分享一下我觉得这本书中几个有趣的地方。

可访问性和可用性

可访问性(Accessibility)是指你的网页对于任何人、在任何环境下都是可持续访问的。特别是指某些用户,比如弱视、浏览器不支持JavaScript或者另外一些情况,比如用户使用Mobile使用你的网页等等。而可用性(Usability)是指使用或者浏览你的网页的容易程度(这里我们只谈web页面),通常它指我们能更有效率地使用、更容易地学习以及更加满意地使用它。举个例子来说,你让你的web页面支持IE6,或者支持mobile都是在提高它的可访问性;而是用CSS来改善布局让用户更容易阅读、使用JavaScript做一些对用户有帮助的互动都是在提高它的可用性。

Web页面都是由下面三个层组成的,通过它们我们可以了解到它们之间的关系以及它们和可访问性和可用性之间的关系。

  • HTML结构层
  • CSS表现层
  • JavaScript行为层

web3layers

Web页面的三个层,HTML结构层是必需的基础,CSS表现层和JavaScript行为层建于它之上。所以在客户端代码中不得不关注的话题就是这三个层的关注点分离。具体探讨一下这三个的分离:

表现与结构的分离(CSS与HTML)

这个分离很好理解,基本思想就是确保HTML来定义结构,而所有的表现都定义在另外单独的CSS文件中。HTML不应该出现<font>标签和用于表现的表格。如果想定义字体和布局,都应该在CSS中处理。

大部分情况下面我们知道达到某个效果是修改表现或者结构是清楚的。但是有些情况下当更改HTML和修改CSS都可以时,你需要慎重地思考到底哪种是合理的。比如一个节点,你希望它不显示,那么你可以在HTML上面删除该节点或者使用CSS来“display:none”。当这种情况是,需要自己分析所需要的效果属于哪种情况,然后修改合理的层。

行为与结构的分离(JavaScript与HTML)

这个也比较好理解,就是不要把任何的JavaScript代码写到你的HTML页面中。应该把所有JavaScript代码放到一个独立的js文件中,然后将它链入到所有需要它的HTML页面中。

关于这个有一个有趣的话题就是:无侵入脚本编程(unobtrusive scripting).简单来说它就是通过HTML和JavaScript的分离以达到页面的可访问性和可用性的最大化。既JavaScript失效了,页面还是可阅读和理解的;而通过引入脚本和JavaScript的hook,就可以让脚本运行,增强可用性。

行为与表现的分离(JavaScript与CSS)

这个的分离是非常复杂的,而且并没有总结出什么特别系统的规则。CSS和JavaScript是有重合的灰色地带的,有时候完全不能确切地把某个效果归为表现还是行为。比如是使用CSS中的hover还是JavaScript的mouseover/mouseout。基本来说你自己得根据具体情况做合理的选择吧。

事件捕捉模型

在HTML的事件模型中有一个有趣的话题。这个简单的问题就是:如果一个节点和它的父亲节点都有对同一个事件的处理,那么到底哪个事件会被先执行呢?这就是关于事件的冒泡和捕获。事件冒泡是说事件从它的目标元素开始,沿着文档树依次向上冒泡,并触发相应的事件处理函数。而事件的捕捉是刚好相反的,它从文档的第一级开始,然后沿着文档树向下游,知道事件目标为止。

在W3C模型中,捕获和冒泡都会发生。当一个事件触发时,它先被文档捕获,到了事件目标后,再冒泡到文档顶层。而传统模型和微软模型只支持事件冒泡,而不支持事件捕获。所以最好是限制使用事件冒泡。其实在我们的实际编程中,很少关心这个话题,是因为大部分情况我们都只使用了事件冒泡。

更加具体的可以查看ppk的文章:http://www.quirksmode.org/js/events_order.html

小记

应该来说PPK所谈的JavaScript是一个更加全面的浏览器编程的世界,让人可以全面来了解这个世界包含的东西。其实大部分的内容在PPK的网站上都有,值得读读。http://www.quirksmode.org/js/contents.html

一些UX的电子书

最近找到了一系列的Ueser Experience方面的书籍,分享出来(点击图标下载)。自己还没有看了,希望能多看几本吧。有特别喜欢的书记得推荐一下.:)。

User Interface Design

User Interface Design

Understanding Your Users

Understanding Your Users

The Human  Interface

The Human Interface

Observing The User Experience

Observing The User Experience

Information Architecture For The World Wide Web

Information Architecture For The World Wide Web

Emotional Design

Emotional Design

Don't Make Me Think

Don't Make Me Think

Designing Web Navigation

Designing Web Navigation

Designing the obvious

Designing the obvious

Design of Everyday Things

Design of Everyday Things

About Face 3.0

About Face 3.0

About Face 2.0

About Face 2.0

蓝色的血液

我是一名pure blue,从在IBM实习到开始工作到现在,在这样的一家百年老店工作,虽然有太多让人抱怨的地方,但是你会喜欢这里的人(虽然不是全部),并且从心里慢慢接受它的文化和价值观。这样的一个公司的价值观是令人敬佩的,足以指导你做人做事。特别不喜欢一些人张口闭口说这不如人那不爽,只怕自己没有自信罢了。不足就努力去改变它,你真受不了了就quit,what’s the big deal?一个人在外人面前骂娘(自己老娘)的时候,是不可能得到尊重的,只是哗众取宠罢了。当你流淌着蓝色的血液时,你是自豪的。

今早一聊天之不爽,故有此文。下面摘除一些从《品味蓝色》上句子。我很喜欢。

任何一名优秀的IBM人,当你问他成功之道的时候,他也许无法教会你具体的流程和方法,但他一定会告诉你,没有什么,不过是秉承诚信负责之道好好做人、好好做事罢了,因为在IBM,机会永远青睐于那些有好的工作表现和正直诚实的人。 — 周伟焜

学会尊重别人,同时赢得别人尊重,这很重要。尊重别人身上的优点,你会变得更宽容。执着、专业、深入是赢得他人尊重的根本。谁都有缺点,包括我们的公司。但是要学会用宽容的心来对待周围的一切。得到尊重,你每天都会快乐。 — 郭希文

所谓分享成功其实就是看你怎样Increase your influence,这并不是仅指依靠手中的权力发号施令,而是指能够提供给别人有价值的意见或见地。同时,在团队合作中,“诚信(integrity)”则是最重要的原则。无论对公司,还是对在公司团队中工作的个体,诚信都是立足之本,信任之基。对一个科学家来说,诚信就更重要,科学是不容半点虚假成分的,谁想投机取巧,违背科学规律,只能是搬起石头砸自己的脚。– 叶天正

认真积极地工作,让我在事业上可以不断进步;以尊重、信任的态度与家人、同事沟通,让我得到了家人的支持,同事的尊敬,从而拥有了和谐美满的家庭和成功的事业。面对这一切,我最深的感受就是四个字——“知福惜福”。 –于雪莉

sMash Stakeholder Meeting

上周进行了sMash的stakeholder meeting,在这个会上我介绍了Flow的新的特性,并且进行Demo的演示。我们的演示大概从5分钟开始,之前是产品开发经理的一些介绍。本人英文口语比较烂,不知道他们到底听懂了没有。详细的信息可以看projectzero 的blog。Vido在Viddler上,至于为什么在viddler上,我想可能是为了照顾中国用户无法访问YouTube的原因吧,呵呵。

http://www.viddler.com/explore/projectzero/videos/4/

Dojo widget的析构过程

了解dojo widget(或者说dijit)的析构过程,不仅让你更加了解整个dijit的生命周期,同样也能帮助我们在自己定制化的dijit中如何正确地释放资源。(这里讨论的dojo应该是在0.9或者以上版本的)

下面是dijit的析构过程:

                        destroyRecursive
                    /                      \
                destroy                   destroyDescendants
        /        |        \
uninitialize  disconnect() destroyRendering

一些常见的错误是如下:

  • 使用destroy()去销毁一个dijit。我们应该使用destroyRecursive()去销毁一个dijit,从上面的过程可以看出,destroyRecursive()会销毁其孩子widgets。
  • 使用destory()去销毁定制dijit中的资源。更可怕的是有的代码可能是直接覆盖destroy,而根本不调用_Widget中的destory。uninitialize()才是dijit暴露出来给定制化widget进行析构的stub function。

结论

使用destroyRecursive()去销毁dijit,使用uninitialize()在定制化的dijit来释放自己的资源。destroyDescendants,destroyRendering基本上用不到,也不要去覆盖它们。

为什么Firefox 3不能加载本地的JavaScript文件了?

一段时间来一直受这样的困扰,就是我的Firefox无法运行本地的dojo的测试文件。一直以为是我的firefox或者机器出了什么问题,就只好去使用IE或者Chrome去运行这些测试例子,可惜不能用firebug的确让人很不爽。

今天在firebug查看了一些错误情况,报错居然是“Access to restricted URI denied”。这个明显是跨域访问的错误,但是本地文件怎么报这样的错呢?在Firefox的about:config搜索了一下policy,居然找到了原因所在,原来Firefox对于本地文件也进行了同源访问的安全设置,配置参数是:security.fileuri.strict_origin_policy。这个新的设置只是在firefox 3才被加入,并且默认是开启的。不过你也可以将这个关掉,这样就可以如同以前那样运行本地的dojo测试用例,或者其它你想本地加载的JavaScript文件。

local-file-p-origin-policy

继续在google了一下,找了这个”feature”的由来,https://bugzilla.mozilla.org/show_bug.cgi?id=230606,大概是说本地的文件如果没有这样的限制,可以访问本机的其他文件,这样会造成安全隐患。John Resig(Father of  jQuery) 也有一个blog关于这个问题,http://ejohn.org/blog/tightened-local-file-security/,下面的评论也挺值得看看的。

More Links:

JavaScript中==等同运算符的类型转换

这周在给一些新员工讲JavaScript的时候,谈了==和===的区别,本质来说,===是严格的等同运算符,要求两者类型相同并且值相同;而==运算符在做比较时,会做一定的类型转换。我们在使用过程中应该使用===而不是==,因为这种类型转换后的比较往往都不是你想要的。当时列出了corckfork最喜欢一些例子:

	'' == '0'          // false
	0 == ''            // true
	0 == '0'           // true
	false == 'false'   // false
	false == '0'       // true
	false == undefined // false
	false == null      // false
	null == undefined  // true
	' \t\r\n ' == 0    // true

转换规则

当时有人就问了,那么在做类型转换的时候倒是等式的左边向右边转,还是反过来呢?其实这些都是不对的,我们去看看ECMAScript的规范,会发现它有对于等同运算符做类型转换很明确的比较算法,下面我将其翻译如下:
对于比较x==y,

1.如果x和y类型不同,那么到14步;
//
//2-13步,为类型相同的比较
//
14.如果x是null,y是undefined,返回true;
15.如果x是undefined,y是null,返回true;
16.如果x是Number,y是String,将y转化成Number,然后再比较;
17.如果x是String,y是Number,将x转化成Number,然后再比较;
18.如果x是Boolean,那么将x转化成Number,然后再比较;
19.如果y是Boolean,那么将y转化成Number,然后再比较;
20。如果x是String或者Number,y是Object,那么将y转化成基本类型,再进行比较;
21.如果x是Object,y是String或者Number,将x转化成基本类型,再进行比较;
22.其他情况均返回false;

ECMA这帮人写的算法过程比较啰嗦,简单一句话来概括就是,对于基本类型Boolean,Number,String,三者之间做比较时,总是向Number进行类型转换,然后再比较;如果有Object,那么将Object转化成这三者,再进行比较;对于null和undefined,只有x,y分别是它们时才相同,其他都为false。

另外,对于转化到Number的算法,细节可以来看ECMAScript的规范,但是基本上下面这个几个表可以覆盖大部分的内容:

type-convert to number (+col) : String Values.
“”
(empty
string)
“-1.6″ “0″ “1″ “1.6″ “8″ “16″ “16.8″
+col 0 -1.6 0 1 1.6 8 16 16.8
type-convert to number (+col) : String Values.
“123e-2″ “010″
(Octal)
“0×10″
(Hex)
“0xFF”
(Hex)
“-010″ “-0×10″ “xx”
+col 1.23 10 16 255 -10 NaN NaN
type-convert to number (+col) : Other Values.
undefined null true false new Object() function(){
return;
}
+col NaN 0 1 0 NaN NaN

再回头来看看corkford给出的例子,然后使用上面的规则去判断;

 '' == '0'          // false
//类型相同,毫无疑问,值不同,所以结果为false
 
0 == ''            // true
//String要像Number转化,''是空String,根据上面的表,转成0,所以结果是true
 
0 == '0'           // true
//String要像Number转化,根据上面的转化Number表,'0'转成0,所以结果是true
 
false == 'false'   // false
//有Boolean,转化成Number,所以第一步转化后为0=='false';
//然后'false'向Number转,结果是NaN,最后变成比较0==NaN,那么肯定是false。
//(NaN和任何相比都是false,就算是自己也是false, NaN==NaN //false)
 
false == '0'       // true
//有Boolean,转化成Number,经过第一次转化就成了0=='0';
//就变成了上面的第3个例子,所以是true
 
false == undefined // false
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是false
 
false == null      // false
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是false
 
null == undefined  // true
//对于undefined和null,只有两边分别是两者才是true,其他都是false;所以是true
 
' \t\r\n ' == 0    // true
//对于String,先转成Number,对于空String,都将转成0,所以转化后成为0==0,结果为true
//(注意,空字符不仅仅是只是空格,还包括\t\r\n等等,更多可以见ECMAScript spec的9.3.1)

总结

虽然我们了解了==这个坏东西的本质,但是在我们的实际JavaScript编程中是要避免使用==,而是去使用===这个严格的比较运算符。