Bason: A BSON Serialization Code Generator

Bason is a code generator for object to bson serialization and deserialization. Different from tranditional reflection way, bason uses an annotation processor to generate serialization manager at compile time. You just add Bason as compilation dependency and drop it in the runtime. To use Bason, you simply add annotation to JavaBeans: /**  *  */ package [...]

Posted in: 广告 by Sunng No Comments , ,

RPC, Serialization and Schema

The post is brought to you by lekhonee v0.7 糖果项目的后端用Java编写,我负责service gateway的开发(暂且叫sergent),服务以Java接口+Annotation的形式声明,与Spring集成使用,Java对象被序列化为JSON和XML(通过jackson和castor)与外部系统交互。专门的JSON Schema和XML Schema是可选的,系统交互通过简明的文档和人工确认。 RPC框架是跨进程、跨系统交互的重要工具,RPC框架中又包括远程调用、网络传输和序列化反序列化等等部分。流行的工具包括Facebook的thrift,Google的Protobuf和原先Hadoop项目下的avro。其中thrift包含远程调用、反序列化、网络等等全部的功能。Protobuf本身是一个序列化反序列化库,另有很多第三方RPC实现,avro目前除了序列化和反序列化的功能,也包含了ipc的HTTP Server和SocketServer等实现。在序列化的格式方面,Thrift支持JSON和二进制协议,Protobuf本身仅有二进制支持,但已经存在第三方的其他格式实现。 avro原生支持二进制和JSON格式。 从效率上来说,二进制方式的序列化要比文本方式的快。Google Code上(最近迁往了github)有一个tpc项目(thrift-protobuf-compare),根据这个项目的最新的比较结果(与原先不同): protobuf成为了三者中耗时最少的框架,之后是thrift和avro,这次avro的耗时甚至超过了文本方式的jackson(主要在反序列化上)。 但是二进制协议通常都需要定义Schema,thrift / protobuf / avro三者各自定义了Schema的格式,没有类似XSD和Json Schema的统一标准,也就是说,当你需要传输一个对象,就要为它编写一个Schema文件。按照通常的习惯,都是先编写Schema,然后通过命令行工具或者自动构建工具来生成Java source。对于新系统还好说,对旧系统这个改造就比较麻烦了。另外,二进制协议不便于调试,所以各个thrift/protobuf/avro先后也都有JSON的实现,在文本的序列化格式上,JSON对XML的优势是全方位的。 所以综合起来,很难说有一种完美的解决方案。二进制协议的效率高,但是改造、编写Schema的代价并不小,还要面对核心Model被绑架到具体框架的风险。文本协议开发简便,不需要Schema,直接POJO就可以序列化和反序列化,但是在时间和空间上都不如二进制的方式。 补充 从tpc项目的结果上看,kryo在时间、空间上都击败了所有对手,而且,kryo的API非常简洁,不需要Schema文件就可以序列化POJO,听起来太完美了,看来以后sergent要借鉴一下的。 补充 2010-06-14 发现avro现在也有ReflectDatumReader和ReflectDatumWriter,可以通过反射内部自动映射生成Schema,可以尝试一下。

Posted in: 手艺 by Sunng 8 Comments , ,

ibatis infinite loop when getFirstResultSet

前几天上线后老大发现几台负载非常高,dump线程状态后发现多个线程死循环在同一处,于是发现了ibatis的这个bug: https://issues.apache.org/jira/browse/IBATIS-384 https://issues.apache.org/jira/browse/IBATIS-587 在mysql数据库上,没有结果集时,stmt.getUpdateCount()会返回0,而非-1. ibatis 2.4.3   private ResultSet getFirstResultSet(StatementScope scope, Statement stmt) throws SQLException {     ResultSet rs = null;     boolean hasMoreResults = true;     while (hasMoreResults) {       rs = stmt.getResultSet();       if (rs != null) {         break;       [...]

Posted in: 手艺 by Sunng 4 Comments ,

Maven recipe #1: Test Java code with groovy

问题: 受够了,不想写Java了,写个含有数据的map还要new出来一个一个put进去,想用groovy解决单元测试 解决: gmaven+groovy eclipse插件可以解决这个需求 在pom.xml中添加gmaven的依赖,注意,仅用来测试。老大不让生产代码里有不可靠的东西。 …         <dependency>             <groupId>org.codehaus.groovy.maven.runtime</groupId>             <artifactId>gmaven-runtime-default</artifactId>             <version>1.0-rc-3</version>             <scope>test</scope>         </dependency> …             <plugin>     [...]

Posted in: 把戏 by Sunng No Comments , ,

Maven recipe #0

问题: 多个root pom的dependencyManagement有重复的内容,希望统一管理。 解决: 新建一个空pom.xml,在dependencyManagement中指定这些依赖,如 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>info.sunng</groupId>     <artifactId>root</artifactId>     <packaging>pom</packaging>     <version>0.0.1-SNAPSHOT</version>     <dependencyManagement>         <dependencies>             <dependency>                 <groupId>info.sunng</groupId>         [...]

Posted in: 手艺 by Sunng 7 Comments , ,

My First Hello World Web App Using Compojure

Compojure是一个用Clojure写成的类似Sinatra的Web框架。Leiningen是一个新的Clojure构建工具,它用Maven来处理依赖管理,而通过封装Lancet(基于Ant)来实现build-in的task。 以上是背景介绍。以下是HelloWorld。 创建一个目录作为工程目录 mkdir compojure-app cd compojure-app 像创建build.xml和pom.xml一样创建project.clj (defproject info.sunng/compojure-app "0.0.1"         :description "A demo app running on compojure framework"         :dependencies [[org.clojure/clojure "1.1.0"]                         [org.clojure/clojure-contrib "1.1.0"]                       [...]

Posted in: 把戏 by Sunng 2 Comments , , ,

We are using Hudson for continuous integration

经历了持续两周的人肉集成,今天上午抢得一台Linux机器,终于尝试用hudson来替代人肉构建。 Hudson的安装和配置远比想象的简单,只要下载发布的war包,在相应的目录执行 nohup java -jar hudson.war > hudson.log 2>&1 & 即可启动到后台 hudson的web图形界面可以胜任几乎全部工作。我们主要使用maven来构建项目,hudson提供了非常强大的功能:邮件提醒(通过插件支持twitter/jabber/irc提醒);自动构建,除了基本的定时构建以外,hudson还会自动解析其管理的项目之间的依赖关系,从而实现级联的构建,这个功能非常震撼。 刚刚上手以后我还安装了两个插件。一个是build-timeout插件,可以之间一次构建的超时时间:我们的项目中有老大写的交互式的maven配置插件,一旦这个插件在自动构建时运行会阻塞构建的流程。另一个是scp发布插件,可以自动scp一个文件到远程服务器上,我用这个插件来把构建版本发布到运行环境中,只要在适当的时候重启一下运行环境的服务器就可以实现部署了。不过scp插件由于上游依赖的问题貌似不支持putty生成的privatekey,这是暂时的美中不足。 配置了整整一天,终于有了CI工具,我就彻底解放出来可以做其他事了。

Posted in: 装备 by Sunng 3 Comments , , , , , ,

Update

太忙了,真的太忙了,每天重复无数遍 mvn clean install -Dmaven.test.skip, 一不小心再遇上”cidaemon.exe”锁死文件无法删除,或者SVN报点Tree conflict,无法见证奇迹就只剩下悲剧了。都是重复的工作,但是在Windows下想做automation还是一筹莫展,比如要构建多个maven项目,也不知道怎么自动化地判断maven构建成功还是失败;再者在Windows里也不知道怎么自动化的scp文件到服务器上去,还要ssh执行重启服务的命令;手足无措啊。 最严重的问题是每天忙的要命,但是并没有感觉有应有的收获或者长进什么的,折腾了半天做的事情还是自己熟悉的小方面,只是做得相对变态而已。每天新的情况让你根本来不及重构,而且严重的问题是,重构好了又有什么用呢,谁能想到后面又有什么变化把你自己引以为豪的设计通通推翻。程序员要考虑的事情太多了,常常要揣摩一些需求方的心思,偷偷摸摸地提前做一些准备。 我现在已经有了一个annotation driven的自动暴露Java接口的框架。之前在CRL实习时,在Jazz上开发也是用一个类似的机制,当时是使用接口的命名规范来确定暴露,比如说有以get和post开头的接口都暴露为HTTP服务,就有很多类似postUpdate、postAdd之类的名字,昨天同事说这个名字太诡异。后来参考了淘宝Open平台的实现,通通的XML描述接口,服务名、方法名、参数名、约束通通写XML配置,我懒,也放弃这个方案了。最后选择用annotation,通过反射解析Java接口,实现的效果和前两者差不多,自认为相对名称的约定要灵活一些,相对无数XML描述符要简洁一些。 后来还为方法的每一步调用都加上监听器,每一个环节都可以注册外部自定义的监听器,所有的核心功能之外的需求都放到自定义的监听器里处理,和框架核心剥离。 再者,框架原本直接序列化接口返回的对象,后来需求有变,要加各种各样的包装。OK,弄一个WrapperFacotry的接口出去,想怎么搞也放到框架核心之外了。Spring的@Authwire(required=false)真是解决了许多问题,在实现InitializingBean初始化一个默认实现就可以了,这样在applicationContext里可以轻松控制外部功能。 还有的发现,序列化的框架分别用的是castor和jackson,结果做profile的时候一比吓一跳,jackson序列话的时间占整个调用的20%,castor的就占到50%了,太可怕了,恐怕要试试其他实现了。 细节扯多了,其实框架的核心都是一天写成的,后面加各种各样的功能花了很大精力。 最近升级到UBuntu10.04已经可以见证奇迹了,眼看着Bug越来越少,之前启动打在tty1上的ureadahead错误日志现在也隐藏了。一切趋于完美,新indicator菜单很好用。 清明回家,下午的火车。因为回家周一不能加班了,少了3倍的工资,悲凉啊。

Posted in: 自话 by Sunng 6 Comments , ,

New features in JTS 1.11

JTS最近发布了1.11版本,新增了: 对Delaunay三角网、Voronoi多边形的支持; 把Geometry对象转换为AWT的Shape对象的功能 对几何对象进行densify的操作(增加结点); 计算Hausdorff相似度和Area相似度的支持 计算Delaunay三角网和Voronoi多边形: import java.util.ArrayList; import java.util.Collection; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.triangulate.DelaunayTriangulationBuilder; import com.vividsolutions.jts.triangulate.VoronoiDiagramBuilder; /**  *  * @author Sun Ning/SNDA  * @since 2010-3-3  */ public class DelaunayAndVoronoiApp {     /**      * create some predefined sites      * @return      */     [...]

Posted in: 装备 by Sunng No Comments ,

Suppressing simple-xml's class attribute

Simple-xml is an object-xml serialization and de-serialization framework. It’s featured by annotation-driven, light-weight and self-contained. In simple-xml, pojos that will be serialized are annotated with @Root, @Element, @Attribute or @Text. The problem is, when handling with inheritance, if the actual type is different from declared type, simple-xml will add a “class” attribute for de-serialization consideration. [...]

Posted in: 手艺 by Sunng 4 Comments ,