tcnative
Jun 04
咿咿呀呀 apache, java, tomcat No Comments
what the heck is going on
Jun 04
咿咿呀呀 apache, java, tomcat No Comments
May 17
技术文章 google, gwt, java, javascript 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 : google, gwt, java, javascript
May 09
技术文章 filesystem, java, os 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 : jnotify
May 03
补充两句 ejb, java, jee No Comments
Java EE 5规范(JSR 244)和EJB 3.0规范(JCP 220)据说都通过了投票,新的Java服务器端纪元款款走来。无论如何,JCP还是太慢了,开源社区都快把Java 5的新特性玩遍了。
May 01
技术文章 java, spring, xml 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提供的配置,完成这个事情,最终效果就像这样:
这对我来说不太容易。虽然我对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 : spring, springframework
Apr 28
咿咿呀呀 apache, java, tomcat No Comments
Tomcat 5.5.17发布,挺快啊~
看了眼CHANGELOG,越来越坚信,CHANGELOG这东西对我来说除了意味着阅读时的兴奋,也意味着恶心:如果不马上更新,手下正跑着的那个版本竟然有这么多bug和不足:^
Apr 27
Mar 31
Oct 17
技术文章 java, spring, struts No Comments
Get a Better Handle on Struts Actions, with Spring. by George Franciscus (george.franciscus@nexcel.ca)
早就想这么干了:-) 随着Spring在项目里占的比重越来越大,看到散落在各处的孤零零的Struts Action早就觉得有股味道了,而且由于没有IoC控制它们,代码看起来也不是很舒服。这篇dW的文章写得很细致,技术方面倒是没什么首创性,只是抛砖引玉罢了,因为都是Spring已经提供好了的东西。
总而言之有三种方法:
ActionSupport类集成Struts;DelegatingRequestProcessor作为Struts的RequestProcessor; Action。解决方法虽然简单,但总比不做要好。
Recent Comments