vulcan

低头做事,抬头看路

   :: 首页 :: 联系 :: 聚合  :: 管理
  41 Posts :: 7 Stories :: 28 Comments :: 0 Trackbacks

#

上个星期升级了Eclipse,升级之后,使用了几天,发现报错和crash的几率很小了,它的error log view里面也清静了不少.
前一段时间,Netbeans6的正式版出来,使用了一下,感觉不错,而当时Eclipse Europa老是出错崩溃掉,让我非常的恼火,所以很想转用Netbeans,有一个项目,是Java GUI程序,在初始阶段,用Netbeans构建Java Swing界面,那叫一个爽啊.不过后面程序,出现了一些问题,比如内存泄漏,莫名奇妙的CPU占用100%啊.用Netbeans做profile也挺不错的.但是到了追踪问题的时候,用Netbeans的debug老是感觉不爽.哪个调试器没有Eclipse好用,Eclipse可以实时的看每个活跃线程的变量,并且变量的输出看起来很舒服,而netbeans却感觉怪怪的,所以后来这个已经构建好GUI的项目又转成了Eclipse的工程.还有就是Netbeans不能运行库中的classes,而给library绑定源代码的方式也怪怪的,没有像Eclipse那么方便,直接给一个jar包指定源码就可以了.另外代码编辑器,Eclipse比Netbeans还是舒服些.也许是对Netbeans不熟悉吧,也不想花时间去仔细学一个新的IDE,所以呢,以后还是坚持用Eclipse好了.对于Netbeans,就用用它的GUI Builder好了.要是Eclipse也有那么好的GUIbuilder该多好啊.可是那个VE的项目总是进度不怎么样,并且以前用过,感觉太慢.从网上知道MyEclipse移植了Netbeans的GUI Builder,不过MyEclipse是要卖钱的啊.另外还有一个好用点的Designer,也是商业的.说真的,我感觉做纯粹的Swing GUI,而不是RCP,SWT, netbeans的GUI Builder是我觉得最好的.

posted @ 2008-03-31 14:34 vulcan 阅读(676) | 评论 (2)编辑 收藏

需要这个功能,但是却发现gnu提供的,还是sun的ResourceBundle都不是怎么好用,所以根据需要在resourceBundle的基础上封装了一下。
package com.csair.hunan.common;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * gettext支持类
 * 主要功能:可以自动获取调用者信息,从而自动的根据local寻找resource
 * (1) 查找和类名相同的properties文件
 * (2) 如果(1)失败,则默认查找调用者包中的message.properties文件
 * 如果找不到相应的key,不抛出异常,而是返回msgId
 * 另外它支持msgId带空格,但是在properties文件中,必须把空格全部替换成下划线
 * 
@author Alva
 * 
 
*/
public class I18NUtils {
    
/* A static instance holding the message */
    
//multi-thread safety?
    public static final ThreadLocal resPool = new ThreadLocal();
    
public static final ThreadLocal callerPool = new ThreadLocal();

    @SuppressWarnings(
"unchecked")
    
public static String _(String s) {
        
//get the direct caller class - FIXME how to deal with extend?
        Class caller = sun.reflect.Reflection.getCallerClass(2);
        ResourceBundle resourceBundle 
= (ResourceBundle)resPool.get();
        
//if no resourcebundle or the caller changed
        
//initial a new resource bundle
        if(resourceBundle == null || !caller.equals(callerPool.get())) {
            
try {
                
// first try the property file who with the same name with the caller class
                resourceBundle = ResourceBundle.getBundle(caller.getCanonicalName());
            } 
catch(MissingResourceException missingresourceexception) {
                
try {
                    
//find the default: package
                    resourceBundle = ResourceBundle.getBundle(caller.getPackage().getName() + ".message");
                } 
catch (MissingResourceException e) {
                    
//do nothing, just suppress the exception, omit the missed resource
                }

            }
            resPool.set(resourceBundle);
            
//record the new caller
            callerPool.set(caller);
        }
        
try
        {
            
// replace key's blank
            String s1 = (String)resourceBundle.getObject(s.trim().replaceAll("\\p{Blank}+""_"));
            
if(s1 != null)
                
return s1;
        }
        
catch(MissingResourceException missingresourceexception) { }
        
return s;
    }
}
使用起来很方便,在需要使用的类中
import static com.csair.hunan.common.I18NUtils._;
//
System.out.println(_("msgId"));
不过还欠缺一点功能:对于翻译文本中数字参数等的支持,需要加强
posted @ 2008-03-21 18:13 vulcan 阅读(965) | 评论 (0)编辑 收藏

去年的一个问题,后来项目时间紧就搁下了,采用了替代方案,但是总觉得不那么完美,今年升级开发,想解决了,然后才有了这个想法。之前也知道SpringSide,但是没有想过取看,今天因为一个问题搜google,居然发现我之前对于java web开发的一些想法居然和SpringSide一样!又多了解了一下,发现这个项目的贡献者都是国内jee开发领域的高手,所以呢,肯定比我的那些实现完美得多。暂时放下自己的代码,好好看看SpringSide源代码,因为想法有些一致,那么看起来肯定会很愉快的,如果全部和我的胃口,那么就转到SpringSide了,如果不完全合我胃口,那么就把我关心的一些代码搞明白后,选择性吸收进项目了。
下面是读代码的一些感受:
(1) DAO的实现挺对我胃口的,比较喜欢。我的范型DAO是从Hibernate网站上取下来改进的。主要增加了一个可以接收List<Criterion>的重载方法还有分页的功能。List类型的Criterion,方便了在上层灵活的利用添加条件,而不用每次都去转成数组,传给原本只接受可变参数的方法;分页和Order的支持操作比我的实现优雅得多。不过却希望可以给范型DAO的主键也增加一个范型参数,因为对于复合主键的参数传入,如果有一个类型安全检查可能要好一些。
(2) 先有鸡还是先有蛋的问题,这个问题可能是我理解得不清楚还是Struts2的机制变了。看到SpringSide2中core.web包中有一个Struts的支持类,支持了基本的CRUD操作,这个问题,我却之前没有想过,导致有好多很简单的,但是又不得不写代码和配置的webwork Action。于是我就想着给webwork也写了这样一个支持类。正好springside3中有对Struts2的一个支持类,参考了一下,struts2和webwork的关系想必大家都知道。应该有可以借鉴的东西。不过借鉴过来之后,发现行不通有问题,后来居然是一个先有蛋还是先有鸡的问题:因为拦截器的配置顺序。在springside3的struts2支持类中,实体的根据id从数据库载入或者新建放在了prepare方法中,而这个prepare是使用了一个要求子类重载的getId方法,毫无疑问,在我们通常的使用中,getId肯定是从表单参数中获取的,所以也就意味着webwork的param拦截器必须在prepare拦截器之前,由于使用了prepare来准备entity,那么model-driven拦截器必须在prepare拦截器之后,不过webwork model driven要能正常工作,实际上,model-driven又必须是在param拦截器之前,在使用ognl进行参数注入之前,必须先通过model-driven拦截器把实体准备好!这就形成了一个先有蛋还是先有鸡的问题了。不知道是不是我理解webwork还不够深入,这个问题如果是采用prepare来做这个工作,那么这个问题是无解的。最终,我还是按照自己的理解做了一个,提供一个getId()默认实现,并且在getId()方法中,不依赖于param拦截器,而是直接从ActionContext中获取提交的表单Id参数,如下的代码:
    /**
     * for the webwork ognl injection of parameter
     * 默认情况下,将把传递过来的参数转换成Integer类型,
     * 如果不是这种情况,则需要在子类中重载该方法
     * 
@param id
     
*/

    @SuppressWarnings(
"unchecked")
    
public void setId(Serializable id) {
        
//如果范型ID的定义不是Array类型,但是却取到了Array类型的值
        
//那么可以断定这是由于页面传递过来的被webwork认成了Array类型了
        
//这个时候,需要把Array类型的参数值取出来
        
//这种情况仅仅在这个范型父类中存在,在具体类中不存在这种情况
        
//而是参数类型可以被webwork自动转换到相应的类型
        
//一般没有ID取值为Array的情况
        if(id instanceof String[]) {
            String[] idArray 
= (String[])id;
            
if (idArray.length > 0{
                
//从List类型的参数中取出具体类型的Id
                id = Integer.valueOf(idArray[0]);
            }

        }

        
//ID should never be ZERO - 
        
//cope with default value of the primitive types
        if(id instanceof Integer && !new Integer(0).equals(id)) {
            
this.id = id;
        }

    }

    
/**
     * getId of the entity, if this.id is null, try get from
     * action context first
     * 
@return
     
*/

    
protected Serializable getId() {
        
if(this.id == null{
            
//try to get parameter from the actioncontext
            ActionContext context = ActionContext.getContext();
            Map params 
= context.getParameters();
            Object id 
= params.get(this.idParamName);
            
if(id != null{
                
//if the parameter is not null,
                
//set Id parameter
                setId((Serializable)id);
            }

        }

        
return this.id;
    }


并且还需要提供一个setIdParamName()方法,这样就可以在webwork配置中注入idParamName了。
当然还可以这样做:
把springside3中struts支持类中prepare做的工作分散到几个crud操作方法中。首先在:input方法中,根据id是否有值,新建或者从数据库中load一个entity,这是在插入或者更新一个entity之前的操作;而getModel方法中直接放了一个创建一个entity instance的方法,因为model-driven主要是拿来做表单参数接收的,所以是否从数据库中load一个entity其实是无所谓的,反正会被表单参数全部覆盖。不过要是可以在getModel()方法之前知道是对哪个entity进行的操作,然后load该对象,就可以在表单中只传递部分属性值了。按照model-driven必须在param拦截器之前的原则,除非把要编辑的entityId放在session而不是页面参数中,然后在getModel方法中预先判断是否是该Action的编辑操作,而load该entity。
posted @ 2008-03-18 10:40 vulcan 阅读(360) | 评论 (0)编辑 收藏

多背一公斤网做个宣传,其实很早就有种想去支边教育的想法,但是学生时代有假却没钱去边区;工作了,能供自己出行了,却没有了时间.好好利用假期吧,公司组织的旅游一年一次,公休假也有七天,如果能看到那些天真的笑脸该是多么快乐的事情啊.去年去了凤凰古城,但是商业化的味道太浓,下次让朋友带我到一些没有开发的湘西苗寨去.
posted @ 2008-02-04 13:00 vulcan 阅读(203) | 评论 (0)编辑 收藏

由于项目中需要把汉字转成拼音,并且是涉及到姓名的转换,因此不能排除有生僻字的可能.我先是查了一下汉字编码的知识,汉字编码知识如下:
http://www.knowsky.com/resource/gb2312tbm.htm;这里说的是区位码,实际上区位码和汉字GBK码就是同一个东西,在区位码的区号和位号上分别加上0xA0就得到了GB2312编码了,但是一看编码规律,只有第一次汉字和读音挂钩,第二级汉字是按照部首进行编排的,所以应该是没有什么绝对的关系的。于是又在网上找其他的资料,用java实现的,网上流传广泛的有两种方法:但是就我来看都不怎么的,第一种是把汉字读音和相应区的汉字对照;但是只是涉及了常用的汉字,遇到生僻字是不能转换的;第二种号称完整版的方法,居然把汉字码表的基本对应关系放到了java类中,并且还说什么为了防止函数字符超过65535长度的限制,用了100多个init函数.我实在是不能理解.其实我想得很简单:找一个汉字拼音对照表,然后初始化时读入到HashMap中,用汉字为Key,用拼音作为value,然后就可以获取了.不过也考虑过,GBK码表的长度有27954个汉字,从来没有用HashMap处理过如此长度得东西,不知道会不会有什么限制,不过随便想了一下应该不可能:第一java HashMap的长度不受此限制;第而,查找汉字时,在HashMap中肯定时用二分法或者更好得算法来取Value,那么最坏的情况也不过时lg2(27954),这是很快的.很快实现了,试了一下性能还不错,在我的机器上:init的时间200ms,查找一个汉字的平均时间为8ms.其实之前我还想过加快速度的更好的方法:把这个汉字编码表自己先处理一遍,先利用冒泡排序法,把编码对应在数据文件里排好,给每个读音汉字对照分配固定的足够长的字符宽度,对于编码中没有汉字的区域,用空白代替;这样汉字的拼音编码关系就和汉字本身的编码建立了联系,减去第一个汉字的编码值,就可以得到汉字拼音在数据文件中绝对位置了,然后就可以根据汉字本身的编码然后用文件随机读取的方法,取到拼音值,不知道这样是不是会比用hashMap的方法要快一点?不过既然HashMap的方案可行了.那么就暂时不取测试了.
相关的资料:
(1) GBK汉字全拼音单字源码表
(2) 单字多音码表

posted @ 2008-01-24 10:50 vulcan 阅读(2155) | 评论 (6)编辑 收藏

要删掉n个目录里面的小文件,如果用手删,肯定要删掉手软,突然想到用find结合rm来删,顺手就用unix管道来做,居然不行,google了一下发现要这么写:
find ./ -iname '_xxxx' | xargs rm -rf
以前没有看过xargs,于是man了一下:
xargs - build and execute command lines from standard input
man里面有用find删除的例子。并且通过google得到的只是,对于删除大量文件,还非得用这种方法不行,因为rm有一个最大删除数量<20000,
结合find命令的一些特性,那么这个组合简直是无所不能了。
posted @ 2008-01-15 10:51 vulcan 阅读(140) | 评论 (0)编辑 收藏

今天进入系统,发现KDE提示升级了,仔细看了一下,以为KDE4在ubuntu发布了。于是想进去看看新的KDE是什么样子的:)。前段时间感受了一下KDE,感觉还不错,但是存在一个问题,一直都没有花时间去解决。就是在KDE,QT程序下面的中文输入问题。原来是想在KDE下qt程序就用Fcitx程序算了,但是在KDE下用gtk程序时,scim还是自动被调入了。于是想在网上查一下解决办法。看了许多帖子,问题都集中在使用scim-bridge上,需要安装scim-bridge还要改动一些xinput的设置到使用scim-bridge取代scim.我看了一下新立得里面的软件介绍,发现那个scrim-bridge是一个transition package for the scim-bridge-client-qt,再往下看,发现一个带了ubuntu标识的软件包,scim-qtimm,它的介绍如下:

This package brings functionality similar to the immodule for
GTK+ to the Qt library. The main goal is to extend and enhance
the input method support in the Qt library, in order to provide
a modern and powerful multi-language input system.

看了一下它的依赖关系,并不依赖于scim-bridge等软件包,而且通常我都更愿意使用有ubuntu标识的软件包。简单安装了scim-qtimm,不用改任何配置,重新启动x-windows,在qt程序就可以正常输入中文了。在我这里,我觉得KDE程序比Gnome要快一些,我的ubuntu版本7.10,并且华丽而稳定,完全不是传言的慢,华而不实。不过blogjava用konqueror登录不了哦,按钮不响应。
posted @ 2008-01-15 09:50 vulcan 阅读(270) | 评论 (0)编辑 收藏

Ubuntu7.10软件库里默认的Eclipse是3.2版本的。没有WTP。在windows上的Eclipse都升级到了Europa了,并且是直接下载的JEE版本,也就省去了配置插件的麻烦(其实也不麻烦,并且可以自己通过plugins目录管理插件,还好些),今天尝试在Ubuntu上使用新的Eclipse3.3 Europa。
首先用错了版本,我的Ubuntu是AMD64的,但是却用了之前机器上有的Europa for Linux x86的版本,尝试n次之后,发现还是不能启动。到了Eclipse官方下载点上,提示我下x86_64版本的,才意识到可能用错版本了。于是下了64位的版本,版本号是3.3.1.1,终于可以启动了。不过都打不开Java源文件,总是莫名其妙的Crash掉,log报PermGen Space, google搜索之后,发现3.3.1有memory leak的问题,但是在3.3.1.1修正了,但是我明明是下载的3.3.1.1版本,还是总是莫名其妙的报PermGen错误,貌似对于x86_64的Linux版本,该问题没有被修正。
看到3.4的MileStone出来了,想尝试一下,随着别人的链接下载了M1版本,启动没有问题,但是发现居然还是Europa,一看版本号,发现是个3.3.0版本!到Eclipse站点上一看,原来已经出到M4了,下载下来看看,这个才是对的3.4版本。试用了一下,还不错。而下载了几个Europa的jee版本都总是出现Permgen space的错误。看来逼得我要用testing版本了。


posted @ 2008-01-08 17:05 vulcan 阅读(514) | 评论 (2)编辑 收藏

放在外网的机器,比较怕的是ssh的暴力破解,因此记录登录失败日志,并且借用一些攻击,比如sshguard等,或者写个脚本自动的把日志中尝试登录次数过多的IP加入到hosts.deny中比较明智。不过新装的Gentoo居然没有发现/var/log/auth.log这个日志文件?用Ubuntu和Redhat的时候都发现有的。查了一下网络,才发现是syslog-ng的配置问题。Gentoo默认的syslog-ng的配置中并没有配置些auth log的项,可以加上一下三行:
filter f_authpriv { facility(auth, authpriv); };
destination authlog { file(
"/var/log/auth.log"); };
log { source(src); filter(f_authpriv); destination(authlog); };
这样登录失败的尝试就可以被记录了。syslog-ng很好,有空还要好好学一下详细使用。
对于配置了iptables的用户,用sshguard的解决方案比较好,它自动的处理登录失败的尝试,并且在iptables拒绝尝试过多的IP,挺好的,不过他在gentoo上还是被hardened profile mask的。

posted @ 2007-12-29 12:40 vulcan 阅读(393) | 评论 (0)编辑 收藏

今天更新完成之后,机器忽然非常慢。意识到有点不对,遂重启。启动之后,强制检查磁盘,并且失败,再重启两次之后,还是自动检查磁盘通不过。第三次重启之后,进入到shell, fsck居然通过,自动修复完成,重启,好了。真的很担心,担心又要装机器。不知道为什么,用了联想的这个启天M6800之后(Intel Pentium D 945, sata硬盘)之后,不管系统是用windows还是Linux程序出问题的频率很高,特别是在windows下,不过重启之后问题又消失了。而且集中体现在Java程序如Eclipse,Netbeans,还有DotNet的程序,比如VS,SQL Server 2005 Studio Express等等阿,有时会出现无法启动的情况。或者是我基本只用这几个程序,所以问题显得多一点?
posted @ 2007-12-29 09:50 vulcan 阅读(103) | 评论 (0)编辑 收藏

仅列出标题
共5页: 上一页 1 2 3 4 5 下一页