Archive for July 2009
今天来自 BsTek 的六人小组来到公司给我们做了个面对面的talk,过程很紧凑不过依然严重超时,他们讲得很起劲,看起来很专业,我很欣赏。他们除了给我们演示那些在 public website 都可以看到的产品演示,还特意突出了新版本 dorado 的一些特性,以及 Marmot framework 的一些诱人特性,分享了好些开发、性能提升方面的经验,当然少不了广告时间。不过时间拖得挺长,一肚子饿就能量下降,有好些问题都来不及问,例如他们产品的OM,编程模型,典型缺陷等等。
从对阵的形势来看,我方人数占优,不过他们专业在于前台展现层,talk show 的主要内容也是这个,于是他们内容占优。显然他们在推举的是一种从最终用户的角度出发来演化的开发模式,他们并不关心数据,而是集中火力关注用户如何操作数据,让用户去实现他们的价值。这和我方的项目设计思路基本对不上号,我听到的最多的是,用户并没有这方面的抱怨(那我再想用户抱怨的最多的到底是什么呢?)。于是我得出一个猜想:要说立马将它投放到项目中的几率不大,我觉得主要不是钱的问题,是风险的问题;但如果公司有足够的想象力的话,估计会将 dorado 作为一个战略资源开始储备起来,不一定只是 dorado,其它同类型的技术也许会有所比较地储备起来,毕竟我们公司不仅仅做 JAVA,还有 .NET。
在下一代 web 标准推出之前,目前所见的应用开发方式应该会持续好一段时间,而且我们的客户一向保守。但什么样的人配用什么样的工具。很难保证哪一天,思潮转变,客户想象力丰富起来了,我们才醒觉昨日可以运行的程序阻碍着今天的生产力发展?

新城饭店
顺便贴张自己认为拍得挺有意思的相片:P

Linux's VISA
如果大陆那家发卡单位发行这类版本的信用卡,必将受到开源社区的大力关注,哪里聚集的正是饱含生产力,而且乐于奉献的消费群体喔。
Linux 对于我,从当初的为了装酷开始玩起,到逐步熟悉使用环境,再到将之作为全功能的开发平台。习惯的难以改变是可怕的,习惯的改变却是充满启发和鼓舞人心的。
五角大楼在年初推出了专门为军方服务的开源代码托管平台Forge.mil,这只是一个开始。
现在美国国防部将和一些开源厂商于8月12日到13日在乔治亚理工大学举行工作组会议,与会者包括了一位驻伊拉克的美国海军陆战队远征军的少校。
参与会议讨论的开源项目有
转自:Solidot
为自己写个工具 Jscombiner,除了帮助自己高效完成任务,可以自娱自乐,还可以开源,和别人分享。
这个工具前一个版本是命令行方式的,一方面技术所限,另一方面是一直坚持认为前台和后台开发是可以而且应该分开进行的。
当然思考的结果是会变的,该分开的还是分开,但有时后台也应该为前台开发提供一些帮助,而单纯的apache httpd提供不了,也有想过用asp, php,但是按照目前的态势,java应该更熟手一点。而且我主要是想和公司的其它同事分享这种开发方式,他们的机器上大多有tomcat而没有apache。
Jscombiner 的基本目标就是减少程序员开发 javascript 项目时所需要投入的管理成本。让 javascript 脚本采取自描述的方式来方便进行管理。因此,开发者可以在开发过程中,随心所欲地更新脚本,而无需担心重构或者脚本规模增长所带来的管理成本。是不是已经有同样的东西存在,我不确定,有是正常的,多个选择,多个竞争,才会有进步的。也许是有开发者像我这样不善推广的。
现在的状况是基本功能以及有了,自己一直在用,我期望的使用感受是感觉不到它的存在。
不过,不是为了做这个东西而做的,还有其它的目标任务,而且只有我一个人在瞎搞,而且主要的更新都是针对自己的实际应用需求的(我相信我所遇到的问题,其它人也会在某个时刻遇到),所以更新会比较慢。
等当前任务完成了,再做一个example出来。不过其实想想也很简单的,mvn archetype:generate一个项目出来,加入依赖,将脚本丢进去,然后mvn jetty:run,立马就可以着手开发了。
关于这个项目的改进计划会在Issue里面发起。目前想到的一个就是先实现前一版本中的一个功能,合并大脚本,这个应该不难,只是怎么提供出来,会更实用,更有趣呢?敬请期待啦!
java · javascript · opensource · tools
他的观点简直超出了我的认知范围,按照他的说法,就是我所认知的进化观点太狭隘了。人类的进化已经不仅仅局限于DNA的随机变异的优势累积,还包括极其巨量的外部信息,如书籍等各种媒体携带的信息,的累积传递。
我对此的理解是,DNA的进化是缓慢的,一个有优势的基因被自然选择出来是需要应该很长很长时间的,通过完善机体功能来完成对人类的影响。相对而言,外部信息的快速的几何增长,虽然有大量都是垃圾信息,但依然有不少信息通过文化,通过实体化来快速的影响着人类的生活。
这个进化阶段被称为自我设计阶段。
我们正身处这个时代……
我们所携带的信息充满了
变革的味道
在一些应用中,可能会有需要知道某一个控件在页面中的位置,在网上比较容易找到下面这个解决方法。
在页面中有一个按钮:
<input id=a type="button"
value="click me to get position"
onclick="getPos(this)"/>
在脚本中响应点击事件的是这个函数:
function getPos(e){
var t=e.offsetTop;
var l=e.offsetLeft;
while(e=e.offsetParent){
t+=e.offsetTop;
l+=e.offsetLeft;
}
alert("top="+t+"\nleft="+l);
}
这个方法的实现相当精炼,意思就是先取得自己的相对位置,再叠加其最近的相对位置容器(offsetParent,它不一定是其父节点)的相对位置,直至顶层位置容器(一般就是body),从而得出该节点的相对位置。
不过,很快就发现这个函数也许并不够用,因为我在页面里有可能使用了一些CSS来使得本来平铺的画面变成一个滚动区域,例如设置了父节点的height为某个值,并且其overflow设为auto或者scroll。这时,上面的方法因为没有计算其滚动偏移,所以所得的值不一定是元素当前的绝对位置,所以我对上面的方法进行了一些小改动,实际上就是加入了对其滚动偏移量的计算。
function getPosition(sender) {
var e=sender,E=e;
var x=e.offsetLeft;
var y=e.offsetTop;
while (e=e.offsetParent) {
var P=e.parentNode;
while (P!=(E=E.parentNode)) {
x-=E.scrollLeft;
y-=E.scrollTop;
}
x+=e.offsetLeft;
y+=e.offsetTop;
E=e;
}
return {"x":x,"y":y};
//alert("top="+y+"\nleft="+x);
}
稍微测试了一下,基本上在IE和FF中都能正常运转。
在运用方面,由于使用到往上遍历,如果节点树结构过于复杂,而且有不会有滚动出现的话,那么还是用第一个方法就足够了。
注:又是炒冷饭 -_-! 原作发表于 2007-09-08
我的目的就是要用archetype来创建一个struts2的blank项目,struts2官网上写的有2.1.6版本
可是我的archetype列表里面只有一个不存在的2.0.9-SNAPSHOT版本,http://people.apache.org/repo/m2-snapshot-repository/目前有2.0.11-SNAPSHOT和2.0.14-SNAPSHOT,这怎么办呢?
最原始的想法就是把包含2.1.6的repo地址(http://www.lenart.org.pl/maven/)加入到settings.xml里面,结果没反应。
手动安装,同样没反应。
这个时候可以想象到maven有一个列表一样的东西来维护这些archetype,很快网上的资料证实了我的想法,于是我尝试手动的更新catalog
mvn archetype:crawl
maven哄哄的扫描完一遍之后,没想到它依然缠绕在2.0.9-SNAPSHOT上面。
心都凉了,突然之间maven在我内心的评价直接跳水,maven的这个插件好傻。
其实这个时候应该换个archetype就好,appfuse有的,不过就是不喜欢它创建出来的东西太杂乱。不换archetype,应该可以换个archetype catalog吧,于是目光聚集在http://maven.apache.org/plugins/maven-archetype-plugin/examples/generate-alternative-catalog.html
mvn archetype:generate \ -DarchetypeCatalog=http://www.lenart.org.pl/maven/
It works.
Pala pala的输入相关信息就创建好了。
不过这种做法的前提是repo有一个叫 archetype-catalog.xml 的文件。
不喜欢选择的话,可以用下面这个拉风得很的命令:
mvn archetype:generate \ -DarchetypeCatalog=http://www.lenart.org.pl/maven/ \ -B \ -DarchetypeGroupId=org.apache.struts \ -DarchetypeArtifactId=struts2-archetype-blank \ -DarchetypeVersion=2.1.6 \ -DgroupId=net.leegorous \ -DartifactId=smui3 \ -Dpackage=war \ -Dversion=1.0-SNAPSHOT
注:-B : 表示批量执行,不提问,个人觉得一问一答也蛮有趣 ![]()
命令换行为了显示方便,使用时请注意在一行完成。
不经意地被一位同事问起在javascript里面如何检测右键事件,并且屏蔽原来的右键菜单,上网查找一翻之后发现一些比较简单的方法。
如设置onmousedown,检查其event.button的值是不是2(代表右键)。
这个方法在FF和IE中都可用,但是在Maxthon中event.button却是0,这让我有点困惑,Maxthon不是IE内核的吗?
我只能设想Maxthon这个壳是做过手脚的。然而如果设置onmouseup,其event.button值就是2了。
所以如果检测右键的话,是设置其onmouseup即可。
document.getElementById("test").onmouseup=function(oEvent) {
if (!oEvent) oEvent=window.event;
if (oEvent.button==2) {
//-- do something for user right click
// alert("Mouse up");
}
}
但是如果还需要屏蔽右键的话,还是用oncontextmenu比较简单,但这时就不是检测右键,而是检测是否弹出上下文菜单。
屏蔽的方法跟屏蔽其他默认行为的方法是一样的,一般来说都是有效的,不过因为某些浏览器有禁止禁止弹出右键菜单的功能,所以如果需要在用户点击右键时做点事情,最好还是不要放在oncontextmenu中,而是放在onmouseup中并检测右键,附加oncontextmenu来屏蔽原来的菜单。
document.getElementById("test").oncontextmenu=function(event) {
//-- do something here
// alert("ContextMenu Popup");
//-- prevent the default behavior
if (document.all) window.event.returnValue = false;// for IE
else event.preventDefault();
};
通过一些简单的测试,可以发现在FF和在IE存在着有趣的区别。
在onmouseup和oncontextmenu事件处理中都使用alert,可以看出来是先执行onmouseup事件再到 oncontextmenu的,在IE中,两者会非常连贯的在一起执行,(均认为是发生在test元素上的事件),而在FF里面则不是(前提是test元素所占区域比较小,当alert弹出时需要移动鼠标才能点击’OK’的情况下),它会先执行onmouseup,alert出来之后,移动鼠标点击 ‘OK’,这时还是会弹出菜单的,但是如果不移开鼠标,而是直接按Enter确认的话,这时它就会认为是在test元素上触发的事件了。可以理解为是IE 和 Firefox中的事件机制的细节区别。当然我们很少会应用到连续事件的,就无须注意到这点区别了,把需要的事件处理完整的写在一个处理方法里面就是最简单有效的解决方案了。
PS: 这post是很久之前(2007-09-06)发布在旧blog里头的,现在拿出来翻炒一下~
最近关注 WebService,尝试CXF的一个 Client 样例(http://svn.apache.org/repos/asf/cxf/trunk/distribution/src/main/release/samples/java_first_jaxws/src/demo/hw/client/Client.java)时,修改一下,运行,总是报这个错:
Caused by: java.net.MalformedURLException: Invalid address. Endpoint address cannot be null.
……
本来想跳过它了,但是很简单的修改,如下
public static final QName SERVIVE_NAME = new QName(
"http://ws.leegorous.net", "Hello");
public static final QName PORT_NAME = new QName(
"http://ws.leegorous.net", "HelloPort");
public static void main(String[] args) {
Service service = Service.create(SERVIVE_NAME);
String endpointAddress = "http://localhost:9000/hello";
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
endpointAddress);
Hello srv = service.getPort(Hello.class);
System.out.println(srv.sayHi("Leegorous"));
}
感觉离真相很近,但怎么都搞不着的感觉真是糟糕~
于是开始调试,调试一下也不错,可以顺便大概了解下过程,但是越挖掘,越觉得奇怪。小说电视里,经常吹嘘当找不到方向时不妨回到原点,这个的原点就是我修改的部分。
很奇怪的发现样例里初始化QName的第一个参数是以”/”结尾的,我想不会吧。
一边质疑着自己,一边加上斜杠,运行测试,居然成功了!
public static final QName SERVIVE_NAME = new QName( "http://ws.leegorous.net/", "Hello"); public static final QName PORT_NAME = new QName( "http://ws.leegorous.net/", "HelloPort");
已经找到步向真相的入口了。或许是QName的问题,也可能是后面使用它的程序有问题,具体还有待解剖报告。
这个问题貌似不太值得一写。不过它使我想起昨晚发现的一起事件,某报文系统已经运行了数年,但居然还有比较低级的解析失败,而且最糟糕就是搜索过分依赖于那个出错的属性。而据我观察,好些系统问题都是有各种各样的“小”而且不太可能发生的失误而造成的,也正是大家都不是仔细收集和分析证据,而是先入为主的否决了其些可能性转而去思考所谓的更大可能性,而浪费了大量的时间。
不过有些先入为主的印象作用是我们不能左右的,就如现在人们在介绍我时依然是用类似于“一个Web界面高手”,甚至是“美工”,除了无奈,还能做什么呢?
难道跳出来大叫
“That’s so 2007”
!##$%^&*()~~
cxf · webservice · 脑电波紊乱
