zhengl's profile淡定而从容PhotosBlogLists Tools Help
Photo 1 of 3
No list items have been added yet.

zhengl hu

Occupation

淡定而从容

October 10

具有远程调试的JAVA调试框架(JPDA)简介

JPDA是一个多层的调试框架,包括 JVMDIJDWPJDI 三个层次。JAVA 虚拟机提供了JPDA的实现。其开发工具作为调试客户端,可以方便的与虚拟机通讯,进行调试

  • JVMDI定义了虚拟机需要实现的本地接口
  • JDWP 定义了JVM与调试客户端之间的通讯协议
  • JDI 则是一组JAVA接口
    如果是一个 JAVA 的调试客户端,只要实现 JDI 接口,利用JDWP协议,与虚拟机通讯,就可以调用JVMDI

JSR-45规范
JSR-45(Debugging Support for Other Languages)
为那些非 JAVA 语言写成,却需要编译成 JAVA 代码,运行在 JVM 中的程序,提供了一个进行调试的标准机制。也许字面的意思有点不好理解,什么算是非 JAVA 语言呢?其实 JSP 就是一个再好不过的例子,JSR-45 的样例就是一个 JSP

JSP的调试一直依赖于具体应用服务器的实现,没有一个统一的模式,JSR-45 针对这种情况,提供了一个标准的模式。我们知道,JAVA 的调试中,主要根据行号作为标志,进行定位。但是 JSP 被编译为 JAVA 代码之后,JAVA 行号与 JSP 行号无法一一对应,怎样解决呢?

JSR-45 是这样规定的:JSP 被编译成 JAVA 代码时,同时生成一份 JSP 文件名和行号与 JAVA 行号之间的对应表(SMAP)JVM 在接受到调试客户端请求后,可以根据这个对应表(SMAP),从 JSP 的行号转换到 JAVA 代码的行号;JVM 发出事件通知前, 也根据对应表(SMAP)进行转化,直接将 JSP 的文件名和行号通知调试客户端。

参考:http://www-128.ibm.com/developerworks/cn/opensource/os-jspdebug/

现在大部分的IDE环境都有远程调试功能,如JBuilderEclipseIDEA等等

步骤:

1、修改服务器JVM参数,添加对JPDA支持,启动Java虚拟机时绑定远程调试功能监视端口

   JRun为例,jrun使用JDPA稍显麻烦,因为所有的服务都共享同样JVM参数,第二个服务启动后会报端口已被使用的错误

   启动JRun前,修改jrun/binjvm.config,修改JVM参数

java.args=-Xmx128M -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=2005

   监听端口2005

   启动JRun后,恢复jvm.config文件JVM参数

2、找到IDE环境远程调试选项,添上服务器主机地址和JPDA监听端口2005

3、在需要调试的程序中添加调试断点,测试IDE就会通知服务器的JVM,某个程序某一行有断点

4、运行程序,调试开始

 

需要注意的是,被调试的程序编译时必须使用-g,使得编译后的class文件包含调试信息

 

但是由于JRun并不完全符合JSR-45规范,所以还没有找到jsp的调试方法,但是对于Tomcat5Resin3.0都可以进行jsp断点调试

July 22

javascript动态改变相关select内容选项,不刷新页面

web上经常有这样的需求,一个select B内容是根据另一个select A对应的值查询而来的。每次A 选的值变化的话,都需要重新查询数据库。但是要求不能刷新页面。实现
显示页面
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
</HEAD>
<BODY>
虚拟社区核心数据webservice<br>
<SELECT NAME="sel" id="sel" onChange="getNewText.src='test.js'">
<option value=1>1</option>
<option value=2>2</option>
<option value=3>3</option>
<option value=4>4</option>
</SELECT>
<span id="span">123213</span>
<script id="getNewText"></script>
</BODY>
</HTML>
 
test.js代码(不一定非得是js,可以是jsp,asp都一样,但内容必须是javascript)
document.getElementById("span").innerHTML="<select><option>aaaa</option><option>234234</option></select>";
 
原理就是定义一个javascript脚本对象,但其内容都是每次到服务器上取得。
完美解决!
July 07

linux下ChartDirector中文字不显示或乱码问题的解决

在网上看了很多关于ChartDirector中文问题的解决办法,那我也说一个吧
在windows上只要设置一下字体就可以了
   Chart.setDefaultFonts("Simsun","Simsun","Simsun"),三个参数分别是默认字,粗体字和斜体字的字体
在Linux上同样也要设置字体,并且设置Linux默认字符集为GB18030,否则可能有乱码问题哦(没试过,如果有乱码就需要转码了)。
还有个很重要的地方就是设置服务器的启动参数(这一点绝对是原创)-Djava.awt.headless=true
根据Sun网站上的意思是因为linux服务器大部分是字符型界面,不需要UI的支持,这时的java虚拟机省略了UI的功能,所以生成图片时调用打印文字的api会有问题。加上这个参数就OK了。
June 25

推荐Java图形报表工具

在网上发现两个很好的图形报表工具,有兴趣的可以研究一下阔,说不定什么时候会用到哦。

JFreeChart:开源免费,效果一般般,重要优点--免费

ChartDirecto:非常棒的东东,做出的图形很漂亮。不过需要$。
  可能有些人会破解,哎,人家辛辛苦苦做出的东西,又不是很富有。破解它,忍心吗?这种人有点龌龊哦。我就不会做这样的事

我会用破解好的,哈哈哈哈。。。。(周星星的笑声响起)

June 24

java动态代理对于Exception的处理,OK

呵呵,网上好多对动态处理介绍时的异常处理都有问题。关键是拦截类在调用实际接口实现类时的处理:
try{
            return method.invoke(target,args);
        }catch(InvocationTargetException e){
            if(e.getTargetException() != null)
                throw e.getTargetException();
            else
                throw e;
        }
找到实际的异常,并抛出。
谢谢帮忙的邵琪妹妹

java动态代理对于Exception的处理,不明白

java动态代理机制对于实现AOP编程思想是个非常好的技术手段,但性能上可能有一定影响,会比普通的直接调用速度降低一倍。如果性能上要求非常严的话,可以像JDO一样使用欲编译,改变字节码。呵呵,这不是今天要讨论的问题。

在测试动态代理机制是发现一个严重的问题,不知道大家是怎么解决的,还是我写的代码是错的。
拦截类:
public class LogHandle implements InvocationHandler {
    private Object target; //被拦截的对象
    public LogHandle(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     
        Object result = method.invoke(target,args);
        System.out.println("-- invocation Handler end");
        return result;
    }
}

接口定义:
public interface ITest {
    public void setName(String name)throws TestException ;
}

接口实现:
public class TestImpl implements ITest{
    private String name;
    public void setName(String name)throws TestException {
        this.name = name;
        System.out.println("setName()");
        //如果name为null,则抛出TestException异常
        if(name == null)throw new TestException("name can't be null");
    }
}

拦截代码:
public static ITest getTest(){
        TestImpl testImpl = new TestImpl();
        LogHandle handle = new LogHandle(testImpl);
        ITest test = null;
        test = (ITest) Proxy.newProxyInstance(testImpl.getClass().getClassLoader(),
                TestImpl.class.getInterfaces(),
                handle);
        return test;
    }
           
public void test(){
        try{
            getTest().setName(null);
        }catch(TestException e){
            System.out.println("TestException = " + e.getMessage());
            e.printStackTrace();
        }   
    }

从代码上看没问题,关键是红字的部分,运行时捕获不到TestException,因为抛出的是
java.lang.reflect.UndeclaredThrowableException

如果用工厂类返回专门产生ITest接口时,调用代码在处理时就会不知所措。因为它不知道返回的ITest接口是动态代理产生的的,还是TestImpl 返回的接口。运行时捕获不到TestException,程序肯定会出问题。

不知道实际运用动态代理时,是如何处理此问题的。

学习webwork2

struts已经用了很长时间了,感觉没什么新意了,老生常谈。现在网上关于webwork2的介绍比较多,想有空研究一下。