tcnative

No Comments

Apache Tomcat从5.5.x开始可以借由tcnative来wrap起APR来。很多同事都很惊讶于tc 5.5.x退出时报告的找不到APR库的问题,好在我对APR早就有所了解,还像模像样的做了些Hello World级别的小练习,所以对这个没啥感觉,只是在想,tc开始用APR了么?抱歉我很少看tc的release notes,以后要注意…
后来转悠到tc 5.5的文档中关于APR的一章,也没仔细看,粗略的浏览了一下。这几天在tomcat-users邮件列表中,有个话题是讨论不用apache httpd做前端而完全用tc做web服务器的问题,看看大家对tc+tcnative+apr+OpenSSL报以如此高的期望,于是回到tc 5.5的文档中一看,可以说比较费机器的事情tcnative都考虑了,比如传输大文件,更好的处理Keep-Alive,SSL等等。不过即使如此,我觉得也许大家都是javaer所以对全Java的解决方案天生容易接受,而且Java应用的处理速度今年来是与日俱增,有的情况下已经比较接近甚至超过C了,但是吃内存仍然是天性,很难有什么好转吧,但tcnative这下给我留下了比较深刻的印象,赫赫,回头要实践一下。apache+mod_jk+tomcat是有些过时了,而且有些影响响应速度,基本上估计不会在将来的实践中考虑了,没有应付多编程语言web应用时应该不会考虑了。我还是觉得即使有了tcnative+apr,处理静态资源的事情还是应该apache httpd来接管。

Google发布Google Web Toolkit(GWT)

No Comments

今天GoogleBlog放出这条消息:Making AJAX development easier,刚开始还以为是普通的PR文章,读过才发现原来是Google发布了新的toolkit,而这次不是使用Google那些产品和服务的toolkit,而是一个简化AJAX开发的toolkit。

GWT可以从这里下载,更好的消息是这个东西包含server端库,嗯,而且是Java的。代码还没有仔细看,不过这种做法比较类似DWR=) License很宽松,大致看了看,除了不让用户重发布GWT本身以外,一般的开发用起来是没什么问题的。

AWT、SWT过后,又来了GWT,呃,当然GWT是瞄准web的。

Technorati : , , ,

jnotify,文件,目录,及其他

No Comments

前天混迹于freenode ##java的时候听到omry提及jnotify,一个使用JNI通过本地库来监视文件系统变化的实用库,支持win32系统和Linux(需要INotify),而这位omry也正是jnotify项目的admin。我觉得这样一个库很有用,因为平时能做的就是创建线程来监视,而通过JNI借由操作系统的支持,就方便的多,而且性能也稍微好一些。

jnotify的api简单到不能再简单了,一般只要一个类的两个静态方法再实现一个接口就可以了,然而也正是这样一种让人感觉不像Java而像是C风格的使用方式让我和omry争论了半天,我还是希望一些更”现代”的方式,也更容易让我整合进Spring里面。

另外就是我希望能够在jnotify这个层次上区分开普通文件目录,而不是让客户代码自己来判断。这一说法立刻引来若干人的指教:目录也是文件。也许他们觉得我是被Windows养大的孩子吧,哈哈。这年头如果有开发人员不知道目录也是文件,我还是会意料之中的惊讶一下。无论从学术概念还是绝大部分的文件系统实现来看,目录确实也被抽象为文件了,但是在实际使用过程中,我的经验–实在是谈不上是经验的经验–是普通文件目录大部分时间内还是被区别对待的,比如我们从来不会打开一个目录去加载目录的内容,而会加载一个XML文件的配置内容。开发人员通过创建一个File对象自然可以判断一个文件是普通文件还是目录,但是一是也许会创建很多临时对象,二是因为大部分时间里普通文件目录是区别对待的,所以不得不用if-else来分开两种迥异的操作,如果懂得extract method还好,否则可能会有大段的if-else块,影响代码阅读,如果可以在实现接口时借由参数得知这个文件到底是普通文件还是目录,甚至处理普通文件目录的方法根本就是被分开的,那至少我的感觉会好一些,当然,同时接口和接口里的方法数量也会增加很多,这也许是omry这样的从业10余年的老黑客看不习惯的吧:^) 结果,我把我wrap过的jnotify(根本没改动jnotify的代码,只是在外面增加一层)的代码发给了omry,他说,nice code,但是暂时还不会把它们加到jnotify里。DIANG~

测试0.7版的时候发现一个bug,会导致JVM退出时的核心线程DestroyJavaVM停止响应,我猜测应该是JNI本地代码的问题,那个时候main thread的exit()都执行完事儿了。不知道omry怎么解决的,0.8版jnotify瞬间release,我还没测试…

这个故事告诉我们,不知道目录也是文件还好说,但是如果在表达”目录”这个概念时说出了”文件夹“、”folder“之类的词,那是值得被一而再再而三地猛烈鄙视的。

Technorati :

Java EE 5, EJB 3.0

No Comments

Java EE 5规范(JSR 244)和EJB 3.0规范(JCP 220)据说都通过了投票,新的Java服务器端纪元款款走来。无论如何,JCP还是太慢了,开源社区都快把Java 5的新特性玩遍了。

Technorati : ,

Spring::NamespaceHandler

No Comments

Spring 2.0带来的一个比较便利的好处就是更加灵活的XML配置方案。由于Annotation在设计方面的特殊地位,决定了它不会完全取代XML配置文件,所以我认为很长一段时间内,Java的server端框架不会把宝都押在Annotation上。Spring 2.0也是这样,解析XML配置文件这一工作不仅没有随着Annotation的加入而停滞,反而添加了更加灵活的配置方案–自定义namespace。

当然,自定义namespace远非说起来那么简单,又得有合适的XML Schema,还要自己实现Spring中的比较核心的接口和抽象类。下午才和Leon抱怨过,因为我无法像使用python的tuple和字典类型一样方便的访问java.util.List和java.util.Map的对象里面的数据,比如aList[12]或者aMap['name'],这些东西虽然通过其他方法也能解决,但毕竟不太舒服。这个问题的起因比较简单:我把一些JDBC相关的配置写在了一个db.properties文件里面,用Spring 1.2.x的时候,我习惯的做法是用一个org.springframework.beans.factory.config.PropertyPlaceholderConfigurer来把几个.properties文件解析,然后使用${name}的方法来访问某个属性所对应的值,当然这还是不够方便,我这破记性让我经常取了一些重复的属性名,非debug而不能得也。今天翻Spring 2.0 M4得文档,发现了<util:properties/>这么个好东西,可以从location指定的资源读取符合属性文件格式的配置信息,以一个PropertiesFactoryBean使框架在引用这个bean的时候可以访问到解析了的Properties对象。这个让我比较高兴,因为可以不用像以前那样把一些没什么关系的.properties文件用同一个PropertyPlaceholderConfigurer装载了,.properties文件的关系得以区分,我也不怕再取一些重复的名字了。问题又来了,就是那个比较无聊的问题:如果我想访问一个.properties文件中某个键名对应的属性值该怎么办?再联想开来,很多动态语言都提供的用键名做下标引用键值的方法,以及类似tuple这样的类型,Spring好像并没有为这种引用方法提供方便,放在Spring 1.x的时候,恐怕也得自己实现一些FactoryBean,然后在配置文件中设置一些property才能完成,很冗长。

所以我就想能不能通过自己解析一个namespace提供的配置,完成这个事情,最终效果就像这样:

<util:properties id=“dbConf” location=“/WEB-INF/db.properties”/>
<my:map-accessor id=“jdbc.url” eval=“dbConf['jdbcUrl']“/>

这对我来说不太容易。虽然我对Spring 1.2.x还比较熟悉,但对Spring 2.0来说只有不到10天的经验(要是按照8小时一天计算,那也就3、4天吧…),而且Spring 2.0还在milestone,文档也不完全,我兴冲冲翻到3.2.2. Extensible XML support这章,结果只看到一个TODO,而TODO中涉及到的”Write your own namespace handler”也是没找到踪影。

不知从何入手,无聊的时候在eclipse里面从Spring 2.0 M4的代码里搜util这个namespace对应的URI:http://www.springframework.org/schema/util,结果在src/META-INF/下的spring.handlers和spring.schemas找到了线索(你也可以看到,实际上搜这个URI是搜不到的,我后来搜索的字符串是 springframework.org/schema/util),util这个namespace是由org.springframework.beans.factory.xml.UtilNamespaceHandler这个类完成的,从这个类就可以找到抽象类NamespaceHandlerSupport和接口NamespaceHandler,这样一来总算由了头绪:^)

NamespaceHandler这个接口很简单,只有两个方法,分别是通过XML元素来查找BeanDefinitionParser以及BeanDefinitionDecorator,而NamespaceHandlerSupport则提供了用于在类内部注册这两种parser的机制,使得子类可以将XML元素的本地名和一个BeanDefinitionParser以及BeanDefinitionDecorator关联起来,这样DefaultXmlBeanDefinitionParser在解析XML配置文件时遇到某个namespace时就可以通过对应的NamespaceHandler实现类最终返回BeanDefinition和BeanDefinitionHolder,完成bean的生成和注册。这个过程和Spring 1.2.x中的对应过程相差不是很多,只是一些类和方法有了改变,方便了开发者实现自己的NamespaceHandler。

具体实现自己的NamespaceHandler的时候–图省事我还是用了NamespaceHandlerSupport,涉及到的类很多,除了上面提到的BeanDefinitionParser和BeanDefinitionDecorator,还有ParserContext、BeanDefinitionRegistry、BeanDefinitionBuilder以及FactoryBean/AbstractFactoryBean,当然,也许还包括org.w3c.dom.Element :^)

具体的实现就不再赘述了,以免有浪费大家带宽的嫌疑。我在做这个NamespaceHandler时,因为Spring提供的一些FactoryBean不太适用,所以自己实现了几个FactoryBean,折腾了一会儿,如果很熟悉Spring的bean注册过程的话,这些工作根本不算什么。一般来说,如果org.springframework.beans.factory.config里面的一些FactoryBean实现不够用的话,十有八九是得自己去实现了,当然,其他一些包里面也有一些FactoryBean实现,不过一般都是和Spring的某个方面结合很紧,比如AOP和事务,很少见需要自己处理–实际上如果觉得有必要添加一些特性时,更好的方法应该是向Spring开发团队提交这部分的代码:^)

NamespaceHandler也完成了,然后就是要编写一份XML Schema了。好在我做的东西比较简单,我所具备的XML Schema手艺还能让我完成这样一份简单的schema,如果稍微困难一些只好去啃那些XML大部头了–我一向对W3C很景仰,因为那里总是诞生出十分庞大的规范,可能使用了几年之后还是会被一些自己一直没有注意到的特性吓到,当然,W3C的规范的扩展性总是很强,这点不得不Orz一下。

都完成了,最后的事情就是让Spring在遇到我的namespace时知道去调用我实现的NamespaceHandler,这个让我比较郁闷,因为默认的DefaultXmlBeanDefinitionParser是用DefaultNamespaceHandlerResolver来接管namespace和NamespaceHandler的对应关系,而不指定资源文件路径作为参数构造出的DefaultNamespaceHandlerResolver只知道从”META-INF/spring.handlers”来读取配置,我暂时还没找到自定义这个配置的方法,不过最后还是通过ClassLoader.getResources()然后通过URL.openConnection去完成读取和加载的工作,也许可以做一些trick…谁知道,太晚了,回头再说了。

多种namespace和自定义NamespaceHandler的方式无疑为Spring的XML配置文件增加了更大的威力,Spring 2.0也已经把aop、transaction/tx、jndi和Web MVC等等配置放入单独的namespace中(从spring.jar!/META-INF/spring.handlers中就能找到)。老式的bean定义虽然可以适合绝大部分的配置工作,但是在一些特殊领域难免显得冗长拖沓,这些领域往往有自己的领域定义,继续沿用老式的bean定义除了会把人搞晕以外倒也没有其他恶行,这种情景之下,使用自己的namespace然后通过自定义的NamespaceHandler去注册bean可以使得编写XML配置的时候更加符合特定领域的语义要求,增强XML文件的可读性。

很想建立一个比如Spring Namespace Handler Repository的项目,使得Spring更能适用于不同领域。

Technorati : ,

apache.projects["Tomcat"].doRealse(tomcat_5.5.17);

No Comments

Tomcat 5.5.17发布,挺快啊~

看了眼CHANGELOG,越来越坚信,CHANGELOG这东西对我来说除了意味着阅读时的兴奋,也意味着恶心:如果不马上更新,手下正跑着的那个版本竟然有这么多bug和不足:^

Technorati :

λprobe|Tomcat绝配

No Comments

λprobe是一个用来监控和管理Apache Tomcat的工具,以war文件发布,可以很方便的部署到Tomcat上面。用了不到一个月,感觉十分不错,没出过问题,Apache Tomcat的那个/manager基本可以不用了,如果不是非用Tomcat Admin来操作JNDI资源以及Tomcat用户等等的话,这个/admin也可以不用了
极力推荐。虽然没有BEA WebLogic、SUN AppServer以及IBM WebSphere Application Server的原味管理应用来得全面,但单就Tomcat平台来说,也是一个难得的选择了。Enjoy!

伪typedef?

No Comments

http://www-128.ibm.com/developerworks/cn/java/j-jtp02216.html
名次乱解:伪typedef,有的老兄因为Java里没有typedef就转而使用extends来实现类似typedef的方法,没错,您猜对了,public class MyFile extends java.io.File,而MyFile这个类里面是空白一片。
实际上这种伪typedef很常见,而在我看来这种typedef大部分时间里应该是用来让开发人员专注于某个领域内的概念,这种情况在团队好不容易完成了对某个领域的建模后比较常见,大家好不容易闹明白了某个自己不太熟悉的业务领域,急于建模并落实到代码里,这时,忽然发现某个某个概念折腾来折腾去也无非就是个装了String的List,于是public class StringList extends ArrayList,负责一些的也许会自己加一些专门的方法,而不负责的就只好维持一片空白了。
不过有的时候我也怀疑这种为了让人专注于领域而进行的伪typedef:因为一个好奇心比较强的人完全可以一路顺着继承树追上去,然后发现也无非就是某某Java核心类,在这以后,我就不敢肯定是否还会专注于这个领域的概念、模型了,也许他会一直隐约觉得这就是某某类,而且父类留存的方法也会留下隐患,造成一些比较隐蔽的误区。这种情况下可能composite模式还稍微好用一些——实际上大部分时间里也就是个delegate。
由于Java 5里又出现了泛型,伪typedef的不利影响也要与时俱进一些,具体的还是看最上面的dW里Brian Goetz的这篇文章吧,很有启发。

读书计划:Java Performance Tuning

No Comments

刚从公司的小图书馆借来,又是我最喜欢的性能话题,虽然是影印版的,争取尽量短的时间内完成吧。536 pages。

使用Spring来管理Struts Actions

No Comments

Get a Better Handle on Struts Actions, with Spring. by George Franciscus (george.franciscus@nexcel.ca)

早就想这么干了:-) 随着Spring在项目里占的比重越来越大,看到散落在各处的孤零零的Struts Action早就觉得有股味道了,而且由于没有IoC控制它们,代码看起来也不是很舒服。这篇dW的文章写得很细致,技术方面倒是没什么首创性,只是抛砖引玉罢了,因为都是Spring已经提供好了的东西。

总而言之有三种方法:

  • 用Spring的ActionSupport类集成Struts;
  • 用Spring的DelegatingRequestProcessor作为Struts的RequestProcessor;
  • 用Spring管理Struts Action

解决方法虽然简单,但总比不做要好。

Older Entries Newer Entries