• 看到这个题目吓了一跳,竟然有这种事,记在这里,敲个警钟。

    HashMap.get() can cause an infinite loop!

  • 最近可能要做一个网络相关的应用,这种应用少不了NIO的支持.

    这几天一直在努力准备相关的技术,把以前学过用过的东西想捡回来.

    今天晚上在网上看有关Reactor和Procator方面的资料,回忆起来一些,,不怎么就跑到Apache MINA上面去了.
    看了一个PPT,发现它竟然源自NETTY2,NETTY2是Trustin Lee(韩国人)开发的NIO框架.记得是在2004年的时候,我所在的公司就用它开发IVR方面的应用.那段时间学了很多东西,在开发学习的过程中也发现了一个NETTY2在高并发时的bug,后来我的经理写了一个邮件提交给了作者,最后他也采用了我们的建议,呵呵 ,这是我第一次对开源做"贡献",当时看到作者把我们提交的BUG确认后并修复后,很兴奋. 

    一晃好几年过去了,没想到NETTY2已经发展到如此地步了,最近需要严重关注一下,可能的话就用MINA作为我们新应用的开发框架,有一种老友重逢的感觉.

  • epoll selector

    2008-01-18

    The epoll SelectorProvider will be included in 5.0 update 9. 

    晚上在网上找一些关于epoll的资料,结果搜索到了自己的blog上,这是去年写的,后来就把这事儿忘记了。 

    最近一直在用jdk6,顺便做了一下测试,想看一下在jdk6中,epoll selector 是否已经设为默认了.

    $uname -a

    Linux dong-desktop 2.6.24-4-generic #1 SMP Mon Jan 14 17:30:39 UTC 2008 i686 GNU/Linux $ java -version

    java version "1.6.0_04"

    Java(TM) SE Runtime Environment (build 1.6.0_04-b12) Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)

    $cat test.groovy

    pintln(java.nio.channels.spi.SelectorProvider.provider())

    $groovy test.groovy

    sun.nio.ch.EPollSelectorProvider@186c6b2

    从结果可以看得出,EPollSelectorProvider在JDK6中,Linux 2.6以上,已经成为默认设置了,这对于基于JAVA的网络编程太有诱惑了。

    而在jdk5中,Linux下默认应该是sun.nio.ch.PollSelectorProvider,也可能是sun.nio.ch.DevPollSelectorProvider。

    JDK6带给我们的惊喜真不少,有待继续挖掘。

  • 在我们的项目中,RMI应用比较多,RMI远程调用也比较多,我挺喜欢RMI这种RPC方式:)

    前几天在做项目的升级改造,测试的时候在RMI Server报出类似以下的异常:

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    .....
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)

    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)

    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)

    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)

    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)

    at java.lang.Thread.run(Thread.java:619)
    ......
    at javaapplication3.RmiHelloClient.main(RmiHelloClient.java:28)

    当时很奇怪怎么会有 java.util.concurrent这个包中的类被用到,想了一下认为在JDK6中应该是用到了线程池,不过没有确认。

    今天和同事讨论了一会儿RMI方面的问题,弄得我对这个问题很好奇,想弄明白 了

     下载了jdk6和jdk5的源代码中,在6中使用了concurrent中的线程池来执行请求,而jdk5中还是每个请求由一个新的线程来完成请求。

    jdk6的RMI在这方面做得比jdk5要好,不过要是能支持“长连接“就更好了,我看源代码中的实现好像没有实现长连接,留待今后再学习。

     

  • A hash set puzzler - [转载]

    2007-12-24

    周末在家里看到A hash set puzzler ,我想了一下,用反射,但又感觉不靠谱 :(

    可天杀的作者一直在卖关子,我这两天时不时的看一下有没有更新,快点公布答案吧。

    或者有高手可以告诉我一下,我将非常感.

    2007-12-25 更新:

     作者给出了一个最好的答案:

    final Object[] foo = new Object[]{null};

    set.contains(new Object() {

    public int hashCode() {

    return bar.hashCode();

    }

    public boolean equals(Object other) {

    return bar.equals(foo[0]=other));

    }

    });
    foo[0];

     这个办法太棒了,超赞。

    我的解法也有人用,就是使用反射,作者对这个法子的评价是:

    "The next popular variant was to use reflection to call package-protected method on the HashMap holded by the HashSet instance (it would work, but it is not as elegant as above version)."

     不够优雅 :(

    什么叫Beautiful Code,这就是。 :) 

    安心睡觉了。 

     

  • 想用Netbean做点东西,启动不了,不知道什么原因。

    最简单的办法就是重装了,不过我 运行netbeans-6.0-javaee-linux.sh  的时候,总是提示已经安装好了,不需要再安装了。

    我想修复一下都不行,反复折腾了几回,还是不让装。

    试了一下:netbeans-6.0-javaee-linux.sh --verbose,在终端里有这么几行: 

    initializing local product cache directory 
    [2007-12-23 16:38:55.942]:         ... /home/dong/.nbi/product-cache 
     [2007-12-23 16:38:55.942]:        initializing local product registry file 
     [2007-12-23 16:38:55.942]:             ... /home/dong/.nbi/registry.xml 
     [2007-12-23 16:38:55.942]:             initializing local product registry stub uri  
    [2007-12-23 16:38:55.943]:             ... resource:org/netbeans/installer/product/default-registry.xml 
     [2007-12-23 16:38:55.943]:             initializing bundled product registry uri  
    [2007-12-23 16:38:55.943]:             ... resource:data/registry.xml  
    [2007-12-23 16:38:55.965]:             initializing product registry schema uri 
     [2007-12-23 16:38:55.965]:             ... resource:org/netbeans/installer/product/registry.xsd
     [2007-12-23 16:38:55.965]:             initializing remote product registries uris 
     [2007-12-23 16:38:55.965]:             initializing state file schema uri  
    [2007-12-23 16:38:55.966]:             ... resource:org/netbeans/installer/product/state-file.xsd
     [2007-12-23 16:38:55.966]:             initializing default state file uri  
    [2007-12-23 16:38:55.966]:             ... resource:org/netbeans/installer/product/default-state-file.xml 
     [2007-12-23 16:38:55.966]:             initializing target platform  
    [2007-12-23 16:38:56.005]:             ... linux-x86  

    这是netbean的注册表?删除/home/dong/.nib这个目录,再安装就齐了。如果不想这么暴力,可以在安装的根目录下找到并执行uninstall.sh,再安装。

    netbean在使用scim的时候,偶尔也会发生冲突,以前都是重启这些IDE,现在发现重启scim也可以解决这个问题了至少scim的启动时间要比netbean或eclipse要少很多,呵呵

  • Did escape analysis escape from Java 6?

     晚上我的笔记本突然崩溃了,xp启动不了了,修复的过程中看到了上面这个文章。

    文章的大意是说escape analysis在jdk6中的实现并不好,有些优化还没有实现。

    我依照他提供的测试代码,也做了些测试。

    不同的地方是我把整个测试提取到单独的方法里,在main里运行了20次,

    java -server -XX:+DoEscapeAnalysis -XX:+EliminateLocks -XX:-UseBiasedLocking LockTest

    测试结果如下:

    StringBuffer: 3681 ms.

    StringBuilder: 3409 ms.

    Thread safety overhead of StringBuffer: 7%



    StringBuffer: 3507 ms.

    StringBuilder: 3384 ms.

    Thread safety overhead of StringBuffer: 3%



    StringBuffer: 3488 ms.

    StringBuilder: 3517 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3521 ms.

    StringBuilder: 3510 ms.

    Thread safety overhead of StringBuffer: 0%



    StringBuffer: 3494 ms.

    StringBuilder: 3506 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3507 ms.

    StringBuilder: 3548 ms.

    Thread safety overhead of StringBuffer: -2%



    StringBuffer: 3489 ms.

    StringBuilder: 3497 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3505 ms.

    StringBuilder: 3503 ms.

    Thread safety overhead of StringBuffer: 0%



    StringBuffer: 3494 ms.

    StringBuilder: 3505 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3488 ms.

    StringBuilder: 3513 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3495 ms.

    StringBuilder: 3507 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3500 ms.

    StringBuilder: 3515 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3493 ms.

    StringBuilder: 3525 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3508 ms.

    StringBuilder: 3561 ms.

    Thread safety overhead of StringBuffer: -2%



    StringBuffer: 3499 ms.

    StringBuilder: 3517 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3526 ms.

    StringBuilder: 3516 ms.

    Thread safety overhead of StringBuffer: 0%



    StringBuffer: 3511 ms.

    StringBuilder: 3512 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3524 ms.

    StringBuilder: 3533 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3517 ms.

    StringBuilder: 3520 ms.

    Thread safety overhead of StringBuffer: -1%



    StringBuffer: 3538 ms.

    StringBuilder: 3526 ms.

    Thread safety overhead of StringBuffer: 0%

     

    从结果看,StringBuffer在多数情况下的性能反而要比StringBuilder要好一点点,或者是持平。

    不能说原作者的结论不对,因为我对这几个参数的研究很浅。

    但是从另一个方面说,对java做性能测试,影响测试结果的因素很多,如果作者看到这个结果那又该下什么结论呢?

    现在的jvm越来越智能了,同样的程序在不同的环境下运行 ,它可能选择它认为最好的优化方式进行优化,进而就可能导致不同的结果,有待深入学习研究。

    写完这个Blog,xp终于恢复了,没把老婆的数据给弄掉了,万幸。 

     

  • 今天快下班的时候,同事问我一个问题:

    如何在Resin中实现类似在Apache中禁止某个目录中文件的执行权限,主要是为了防止用户在上传目录中上传了恶意的jsp文件,一起google了一下,发现了一个叫做plugin_ignore的东西,看起来很像我们要找的,把下面的代码加到resin.conf中一试,很神奇,jsp的源文件显示出来了,还不影响用户的正常下载 

    <servlet-mapping url-pattern='/upload/*' servlet-name='plugin_ignore'/>

    plugin_ignore是用来告诉resin的apache module,这符合这种路径规则的不再归resin管了,呵呵。

     昨天开始用kde4,除了任务条出不来,偶尔桌面崩溃外,也没什么大毛病了。

     从性能上看,比kde3要好一些,至少我在用“星际译王”时,翻译单词的时候提示窗口弹出的很流畅。

    而且使用scim输入汉字的时间,提示框也很有动感的出现,比较新奇。

    kde4的桌面特效要比gnome稳定,速度快,至少在我的机器上对比能很明显的感觉到。

     

  • java.lang.Package - [自写]

    2007-12-12

    今天在看DZone 的时候,看了一篇Java: automatically increment build number 的文章,主要介绍了如何生成jar文件的版本号。

    这里主要是利用JAR文件规范中的MANIFEST.MF中的Implementation-Version属性,就可以为自己的jar文件定制版本号了,而Implementation-Version这个属性会由ClassLoader在加载类的时候解析,并生成相应的Package对象。

    如果要在运行时获取这个信息,可以通过class.getPackage().getImplementationVersion()得到。

    这时我才明白java.lang.Package的用途,以前一直以为这个类没什么用,也一直没有认真研究过,很惭愧。

    “Package objects contain version information about the implementation and specification of a Java package. This versioning information is retrieved and made available by the ClassLoader instance that loaded the class(es). Typically, it is stored in the manifest that is distributed with the classes.”

    或许以后可以用上这个技术。

  • JAXB2.0 - [自写]

    2007-11-21

    在Java应用中,使用XML作为配置文件是很普遍,以前的写法通常是用dom4j,或者DOM来解析XML,取得数据后再构造一个对应的JAVA对象。

    每当有一个新的配置,XM的解析就是一个问题。

    今天想起了JAXB,以前看过的JAXB也可以完成xml和java的相互转换,不过要写一个schema,不喜欢这种风格,一直没有用。

    JAXB2.0支持使用Annotation在java代码中说明各种属性的XML风格,相当的方便。

    我的做法是先定义一个类,再加上用JAXB2.0的注释,写一个测试,生成XML,如此反复,直到生成的XML与当初期望的一致。

    等XML的的格式确定之后,这个生成的XML就可以当做新配置的模板,这个工作就完成了。

    使用JAXB2.0可以不用不再手工的解析XML,工作的主要内容变为定义Java对象各属性的XML Annotation以及测试,非常简洁。

    JDK6已经内置了对JAXB2.0的支持,不用再下载特定的XML解析包了,JAXB同时支持Java->XML的序列化和XML->Java的反序列化,工作起来很方便。