??xml version="1.0" encoding="utf-8" standalone="yes"?>伊人成综合网伊人222,av网站在线免费观看,精品国产1区2区http://www.aygfsteel.com/emu/articles/4775.htmlemuemuWed, 18 May 2005 08:19:00 GMThttp://www.aygfsteel.com/emu/articles/4775.htmlhttp://www.aygfsteel.com/emu/comments/4775.htmlhttp://www.aygfsteel.com/emu/articles/4775.html#Feedback2http://www.aygfsteel.com/emu/comments/commentRss/4775.htmlhttp://www.aygfsteel.com/emu/services/trackbacks/4775.html

 
junit不能struts的actionQhttpunit也只能测servlet。用struts作项目的时候无法方便的对action层做单元试一直是我的心头大恨。现在好了,我们有了StrutsTestCase。按照网上的介绍QStrutsTestCase用v来应该是非常单的Q只要下了jar包回来引用到工程里面可以了。实际上可能也差不多Q-如果你运气不象我q么臭的话?/DIV>


在sourceforge上随便挑其中一个镜象的下蝲地址Q?BR>http://aleron.dl.sourceforge.net/sourceforge/strutstestcase/strutstest213-1.2_2.4.zip

flashget回来Q放到jbuilder的userhome里面Q找一个struts action创徏test caseQ创建的时候吧test case的基cL?MockStrutsTestCaseQ测试的Ҏ一个都不用选(因ؓ我们是要针对action的具体每一个逻辑分支试而不是具体的某一个方法)。创建成功后d一个测试:

  public void testSuccessfulRefresh()
  {
    setRequestPathInfo("/RefreshSystemData");
    actionPerform();
    verifyForward("success");
  }

嘿嘿Q我_ֿ挑了一个没有参数的action来实验?/P>

一切看h很顺利。run testQ噩梦开始了Q?/P>

java.lang.NullPointerException
 at servletunit.struts.MockStrutsTestCase.getActionServlet(MockStrutsTestCase.java:331)
 at servletunit.struts.MockStrutsTestCase.tearDown(MockStrutsTestCase.java:130)
 at hospital.tongren.oa.system.action.TestRefreshSystemDataAction.tearDown(TestRefreshSystemDataAction.java:34)
...(Click for full stack trace)...

q好我没有开音箱Q不然又是一大炮轰出来?/P>

看来要调试了Q先d一个地方下了StrutsTestCase原码回来
 http://aleron.dl.sourceforge.net/sourceforge/strutstestcase/strutstest-213-src.zip

加进userhome里面的source。debugq去Q跟到org.apache.struts.action.ActionServlet里面Q出错的地方是:

        InputStream input =
            getServletContext().getResourceAsStream("/WEB-INF/web.xml");

        try {
            digester.parse(input);

        } catch (IOException e) {
....

input 为空指针。不知道Z么ServletContextSimulator在模拟ServletContext的时候没能够正确的找到webmodule的位|。上|搜了好一会儿文档Q在 http://strutstestcase.sourceforge.net/api/servletunit/struts/MockStrutsTestCase.html 中发Cq样一D:

NOTE: By default, the Struts ActionServlet will look for the file WEB-INF/struts-config.xml, so you must place the directory that contains WEB-INF in your CLASSPATH. ...

先照它说的试试把webmodule路径放进classpath中,没有用?BR>往下看Q发Cq个好东东:setContextDirectory。在startup中加一句:

this.setContextDirectory(new File("E:\\projectPath\\webModulePath\\"));

l于把那个空指针l过了。但是报一个新的异常:

junit.framework.AssertionFailedError: received error 400 : Invalid path /RefreshSystemData was requested

 at servletunit.HttpServletResponseSimulator.sendError(HttpServletResponseSimulator.java:463)

 at org.apache.struts.action.RequestProcessor.processMapping(RequestProcessor.java:684)

 at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:242)

 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)

 at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

 at servletunit.struts.MockStrutsTestCase.actionPerform(MockStrutsTestCase.java:394)

 at hospital.tongren.oa.system.action.TestRefreshSystemDataAction.testSuccessfulRefresh(TestRefreshSystemDataAction.java:51)

...(Click for full stack trace)...


找不到strutsconfig里面配置的path。strutsconfig是在web.xml里面配置的,应该q是web.xml没找到造成的,那么指定strutsconfig文g的位|咯Q?BR>    setConfigFile("E:\\......\\struts-config.xml");

l于可以q行h了?/P>

随后发现Q如?nbsp; setServletConfigFile("E:\\....\\WEB-INF\\web.xml");的话MockStrutsTestCase也能够根据web.xml中的配置扑ֈstrutsconfig文g?/P>

最后把上面用到的绝对地址E:\\...全部改ؓ相对地址Q?BR>    setContextDirectory(new File("modulePath\\"));
    setServletConfigFile("modulePath\\WEB-INF\\web.xml");
    //   this.setConfigFile("modulePath\\WEB-INF\\config\\system\\struts-config.xml");

血吐完了,l箋郁闷Qؓ什么别人都不用配置的这么麻烦呢Q到底我做错了什么,q是jbuilder的错Q?/P>

CactusStrutsTestCase也没配vQ好像要加个什么包吧,再看看先?/P>
[点击此处收藏本文]

发表?2005q?1?2?4:04 PM

emu 发表?SPAN>2005-01-22 8:00 PM  
http://jakarta.apache.org/cactus/getting_started.html 中有详细的说明。感觉确实复杂了一炏V现在进展是Q?

org.apache.cactus.util.ChainedRuntimeException: Failed to get the test results at [http://localhost:8083/TongRenOA/ServletRedirector]

at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody0(DefaultHttpClient.java:92)

at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest_aroundBody1$advice(DefaultHttpClient.java:206)

at org.apache.cactus.internal.client.connector.http.DefaultHttpClient.doTest(DefaultHttpClient.java)

at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runWebTest(HttpProtocolHandler.java:159)

at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody0(HttpProtocolHandler.java:80)

at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest_aroundBody1$advice(HttpProtocolHandler.java:206)

at org.apache.cactus.internal.client.connector.http.HttpProtocolHandler.runTest(HttpProtocolHandler.java)

at org.apache.cactus.internal.client.ClientTestCaseCaller.runTest(ClientTestCaseCaller.java:144)

at org.apache.cactus.internal.AbstractCactusTestCase.runBareClient(AbstractCactusTestCase.java:215)

at org.apache.cactus.internal.AbstractCactusTestCase.runBare(AbstractCactusTestCase.java:133)

...(Click for full stack trace)...

下班先?/DIV>



emu 2005-05-18 16:19 发表评论
]]>
Bugzilla 2.19.2 试用手记 http://www.aygfsteel.com/emu/articles/4757.htmlemuemuWed, 18 May 2005 06:18:00 GMThttp://www.aygfsteel.com/emu/articles/4757.htmlhttp://www.aygfsteel.com/emu/comments/4757.htmlhttp://www.aygfsteel.com/emu/articles/4757.html#Feedback0http://www.aygfsteel.com/emu/comments/commentRss/4757.htmlhttp://www.aygfsteel.com/emu/services/trackbacks/4757.html Bugzilla 2.19.2 试用手记

Bugzilla 2.19.2 试用手记

bugzilla 2.19试用版已l发布很久了。但是我们还是l一直在使用2.18Q一是不知道2.19版是否稳定,二是2.18版的已经有wfifi的汉化模板可以用。但是现在公司开始在评估是否购买jira了。于是粗略比较了一下jira和bugzilla?/P>

初看了一下jiraQ和bugzilla各有特色Q比较突出的感觉到的有:
1 jiraL是个IMSQissue management systemQ,也就是说Q它不但可以理bugQ还可以理其他U类的issue比如taskQ而且自己可以创徏新类型的issue。相比之下bugzilla却是个DMSQdefect management systemQ,它的g一切都是bug。虽然最l可以实现的功能没有大的差别Q但是却从概念上让h感觉C们之间的差异?BR>2 jira支持subscribeQ也是订阅指定的bug信息Qbugzilla?.18版还没有发现q样的功能?BR>3 bugzilla支持生成chartQjirag没有q个功能?BR>4 bugzilla现在已经有汉化包Qjira支持的大?U左右的语言里面Q没有发C文。不q作Z个外企,我们不需要一个界面汉化的DMS
5 jira的企业版据说q可以自己定义issue的处理流E,不过好像要改源码呵呵?BR>6 jira的权限系l做得比bugzillal致?BR>7 jira要花money

Z更加公^的比较bugzilla和jiraQ上|吓了最新的bugzilla2.19.2版,比其2.19.1版没有多实现多少Ҏ,但是据说改了些bug。与2.18版比hQ最H出的是增加了一个类似jira的subscribe的功能,叫Whining。此外提供了用户名下拉框Q以后可以不用敲assignee了(其实我早p己实C相同的功能,我的QA其实没怎么敲过assigneeQ,生成报表使用的条件可以反转。还有写环境变量和报表参CcȝҎ看h和我关系不大。不q第一个note没看明白Q?/P>


A higher level of categorization (departments, locations, etc...) is now available for bug reports


q应该是说做report的时候提供了更高U的分类的意思吧Q但是与之关联的bug里面却说Q?/P>


It would be nice if one could group products into categories(departments, groups, organization, etc.)...


q应该是说创建product的时候可以分cȝ意思?/P>

因ؓ原来服务器上已经安装qbugzilla2.18Q安?.19的时候容易的多了。在apache的发布目录下新徏了一个newbugzilla目录Q把下蝲的包解压到里面去。然后进而命令行状态下Qperl checksetup.plQ验证了一下用的包全部争取安装,q且生成了localconfig文g。打开localconfigQ把$db_pass填上Q重新perl checksetup.pl。安装脚本开始升U数据库Q新版本的bugzilla需要用C些新的表或者在旧表里面加些新的字段Q,利通过?/P>

打开览器访问newbugzillaQ除了没有中文界面之外一切如常,q去看assigneeq是文本框,Whining功能也找不着Q奇怪了?BR>q入目录里面搜相关的文gQ在根目录下发现了whine.pl。既然没有链接,q接敲地址讉K它试试?从ie输入它的地址Q出来一个错误页面:no permission?BR>原来新的功能要关联到新的group才有权用。进用户兌把所有的角色都先加给自己先。回C刷C下,果然Q处来了一个whining链接Q点开一看,爽!

用户名下拉框的问题,?.19.1版的release notes上面兌C个bug。过ȝq个bug的说明和附gQ说是要加一D代码在\template\en\default\global下面Q叫userselect.html.tmpl。在本地一找,q个文g已经有了Q可是ؓ什么用h有变成下拉列表呢Q打开userselect.html.tmpl一看:
[% IF Param("usemenuforusers") %]
......
原来要读?STRONG>usemenuforusersq个参数为真的时候才昄Z拉框的。进parameter里面Q找到usemenuforusersq一,改ؓtrueQ回到创建bug面Q用h果然变成下拉框了?/P>

再找?STRONG>A higher level of categorization 在哪里?找了半天没找到categories之类的东西,不过在parameter里面发现了一个新东西Q?STRONG>useclassification。把q个参数打开QonQ之后,菜单多了一?Classifications Q大概就是指的这个东西了。在Classifications 中可以徏立品分c,然后再在产品分类中徏立品,或者把旧的产品兌到创建的分类中(没有兌的品全部属于Unclassifiedc)。这样在创徏bug的时候就要先选分c,再选品,再选组件。对产品U比较复杂的单位Q这L功能q是有点讨好的?BR>




emu 2005-05-18 14:18 发表评论
]]>
在apache下发布了bugzillahttp://www.aygfsteel.com/emu/articles/4756.htmlemuemuWed, 18 May 2005 06:17:00 GMThttp://www.aygfsteel.com/emu/articles/4756.htmlhttp://www.aygfsteel.com/emu/comments/4756.htmlhttp://www.aygfsteel.com/emu/articles/4756.html#Feedback0http://www.aygfsteel.com/emu/comments/commentRss/4756.htmlhttp://www.aygfsteel.com/emu/services/trackbacks/4756.html

l于要到一台新的项目服务器Q把旧的东西一一挪到新服务器上来。在挪bugzilla的时候遇C些问题。原来的服务器上面装的是2.18rc2版,使用的汉化模版却?.18rc3版的Q在老服务器上工作良好,但是在新服务器上中文版的模版无论如何都无法在IIS上发布出来,始终报告一个访问拒l错误。去下了2.18rc3版的bugzillaq来Q仍是相同的问题。本来就看着IIS很不爽了Q试了几ơ不成功Q换apache试试Q结果和IIS抢端口了Q干脆就把IISl卸了?/P>

跟着http://www.bugzilla.org/docs/win32install.html 一步一步来。做到最后发布的时候没有看到发布成功的首页Q却看到了一个错误页面。进Program Files\Apache Group\Apache2\logs下面看error.logQ?/P>

[Tue Mar 15 18:55:04 2005] [notice] Child 4488: Starting 250 worker threads.
[Tue Mar 15 18:55:10 2005] [error] [client 127.0.0.1] (OS 3)pȝ找不到指定的路径?nbsp; : couldn't create child process: 720003: index.cgi
[Tue Mar 15 18:55:10 2005] [error] [client 127.0.0.1] (OS 3)pȝ找不到指定的路径?nbsp; : couldn't spawn child process: C:/bugzilla-2.18/index.cgi
[Tue Mar 15 18:59:05 2005] [notice] Parent: Received shutdown signal -- Shutting down the server.
[Tue Mar 15 18:59:05 2005] [notice] Child 4488: Exit event signaled. Child process is ending.
[Tue Mar 15 18:59:06 2005] [notice] Child 4488: Released the start mutex

couldn't create child process —?原来是无法创建子q程。看来是没有扑ֈperl.exe。在q个问题上,安装指南_

In order for ScriptInterpreterSource Registry-Strict to work, you also need to add an entry to the Registry so Apache will use Perl to execute .cgi files.

Create a key HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command with the default value of the full path of perl.exe with a -T parameter. For example C:\Perl\bin\perl.exe -T

Create a key HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command嘛,所以我创ZHKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI然后在下面加了一个Command的key。不q既然出错了Q不妨试试另一U理解,创徏一个HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command,再在下面的默认key上给了一个C:\Perl\bin\perl.exe -T 。重起apache。果然就ok了。应该这D|档的描述是有问题的?/P>

最后上http://www.glob.com.au/sendmail/ 下蝲了sendmailQ解压到C:\usr\lib下,在sendmail.ini里面修改smtp_server、default_domain、auth_username、auth_passwordQ后面两w认的被用分号注释掉,如果使用的smtp需要n份验证的话就L分号q填上正的用户名密码)Q把服务器防火墙?5端口打开。试试改个bugQ邮件就发出MQ大功告成?/P>


[点击此处收藏本文]
发表?2005q?3?5?7:44 PM

emu 发表?SPAN>2005-04-06 5:18 PM  
今天在http://landfill.bugzilla.org/ppm 上发C二月和三月各有一个文件更斎ͼ

MIME-tools.ppd 03-Feb-2005 20:36 532
MailTools.ppd 31-Mar-2005 21:28 400

应该是新版本的bugzilla正准备用内|的邮g支持了吧。不q?.19的checksetup.plq没有提C安装这两个包,不知如何使用?

此外Q搞定了bugzillaq行在mysql ?4.1以上版本时的w䆾验证问题?
在http://www.bugzilla.org/docs/win32install.html 上提及以下事实:
I've experienced a few issues with MySQL 4.1.x, so i recommend you install 4.0.x. When I have some time I'll investigate the issues (relating to database creation and authentication).

于是跟着提示扑ֈ?http://dev.mysql.com/doc/mysql/en/old-client.html
q里有相信的解释和两个解x法。一是:
mysql> SET PASSWORD FOR
-> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

我试q了Q不知ؓ何更C成功?
二是Q?
mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd')
-> WHERE Host = 'some_host' AND User = 'some_user';
mysql> FLUSH PRIVILEGES;
q样checksetup.plp够正的q接到mysql了?



emu 2005-05-18 14:17 发表评论
]]>
用junitperf做ƈ发测试带来的问题 http://www.aygfsteel.com/emu/articles/4755.htmlemuemuWed, 18 May 2005 06:13:00 GMThttp://www.aygfsteel.com/emu/articles/4755.htmlhttp://www.aygfsteel.com/emu/comments/4755.htmlhttp://www.aygfsteel.com/emu/articles/4755.html#Feedback0http://www.aygfsteel.com/emu/comments/commentRss/4755.htmlhttp://www.aygfsteel.com/emu/services/trackbacks/4755.html

关于junitperf的一点介l?/FONT>

junitperf 是个很小巧的java性能试框架Q可以在http://sourceforge.net/project/showfiles.php?group_id=15278 上下载到。可以很Ҏ的把它结合junit一h试,比如在测试套仉面加q么几行Q?/P>

import com.clarkware.junitperf.TimedTest;
import com.clarkware.junitperf.LoadTest;
.......

    int testTimes = 10;
    int users = 5;

    suite.addTest(new TestUserDAO("test1AddUser")); //基本功能试Q同时初始化环境
  
    suite.addTest(new TimedTest(new TestUserDAO("test1AddUser"), 1000)); //基本性能试:Ҏ应在1U内完成

    suite.addTest(new LoadTest(new TestUserDAO("test1AddUser"), users)); // q发试

  suite.addTest(new LoadTest(new TestUserDAO("test1AddUser"),users,testTimes)); //q发负蝲试

  suite.addTest(new TimedTest(new LoadTest(new TestUserDAO("test1AddUser"),
                                           users,testTimes), 35000)); //q发性能试

如果只需要反复做一个测试而不需要ƈ发测试,可以

suite.addTest(new LoadTest(new TestUserDAO("test1AddUser"),1,testTimes));

当然也可以不用junitperfQjunit.extensions.RepeatedTest是设计来干q个的:

suite.addTest(new RepeatedTest(new TestUserDAO("test1AddUser"), testTimes)); //重复试


用junitperf做ƈ发测试带来的问题


做ƈ发测试的时候junitperf有一个问题。注意看q一行:

new LoadTest(new TestUserDAO("test1AddUser"), users)

我们只传递了一个TestUserDAO实例lLoadTestQ却要求它开启users个线E来试Q这栯users个线E就会只针对同一个TestUserDAO实例q行试。这个时候,我们在TestUserDAO里面׃能存放Q何状态数据了。比如以前我很喜Ƣ这么做Q?/FONT>

public class TestUserDAO extends TestCase{
 private int lastId;
 protected void setUp() throws Exception{
  super.setUp();
  //构造一个测试用的数?BR>  User user = new User("张三");
  //向数据库插入一条记?BR>  userDAO.addUser(user);
  lastId = user.getId();//刚刚插入的记录在数据库中产生的ID;
 }

 public void testUpdateUser() throws DaoException{
  //针对setup中插入的数据q行update操作
  user = userDAO.getUserById(lastId);
  user.setName("李四");
  userDAO.updateUser(user);
 }
 protected void tearDown() throws Exception{
  //删除试数据
  userDAO.deleteUserById(lastId);
  super.tearDown();
 }
q样我是通过一个int变量lastId在各个方法之间传递被试的数据的。如果用junitperf来测试,lastId变量׃被后来的U程覆盖Q导致测试失败?BR>


解决Ҏ


在com.clarkware.junitperf.TestFactory的文档中对这个问题做了说明:

This factory class should be used in cases when a stateful test is intended to be decorated by a <code>LoadTest</code>.  A stateful test is defined as any test that defines test-specific state in its <code>setUp()</code> method.

TestFactory的用方法是q样Q?/P>

import com.clarkware.junitperf.TestFactory;

......

     suite.addTest(new LoadTest(new TestFactory(TestUserDAO.class), users,testTimes)); //q发负蝲试

但是q样只能观察整个试cȝ表现。如果我们要单个的测试测试类中的一个测试,那么可以考虑另一U方法。我们在TestFactory的文档中看到Q?/P>

 This class is dependent on Java 2.  For earlier platforms a  local cache implementation should be changed to use, for example,  a HashMap to track thread-local information.

q个Ҏ同时也适用于我们需要处理的情况Q?/P>

public class TestUserDAO extends TestCase{
 private static final ThreadLocal threadLocal = new ThreadLocal();
 protected void setUp() throws Exception{
  super.setUp();
  //构造一个测试用的数?BR>  User user = new User("张三");
  //向数据库插入一条记?BR>  userDAO.addUser(user);
  //lastId = user.getId();//刚刚插入的记录在数据库中产生的ID;
  threadLocal.set(new Integer(user.getId()));
 }

 public void testUpdateUser() throws DaoException{
  //针对setup中插入的数据q行update操作
  //user = userDAO.getUserById(lastId);
  user = userDAO.getUserById(((Integer)threadLocal.get()).intValue());
  user.setName("李四");
  userDAO.updateUser(user);
 }
 protected void tearDown() throws Exception{
  //删除试数据
  userDAO.deleteUserById(((Integer)threadLocal.get()).intValue());
  super.tearDown();
 }



emu 2005-05-18 14:13 发表评论
]]>
自作聪明的junit.swingui.TestRunner http://www.aygfsteel.com/emu/articles/4754.htmlemuemuWed, 18 May 2005 06:08:00 GMThttp://www.aygfsteel.com/emu/articles/4754.htmlhttp://www.aygfsteel.com/emu/comments/4754.htmlhttp://www.aygfsteel.com/emu/articles/4754.html#Feedback1http://www.aygfsteel.com/emu/comments/commentRss/4754.htmlhttp://www.aygfsteel.com/emu/services/trackbacks/4754.html
自作聪明的junit.swingui.TestRunner

问题
在junit.swingui.TestRunner的时候发现TestRunner启动q程中报错:
log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
同时也发C个^时工作正常的cd使用junit.swingui.TestRunnerq行试的时候报告一个奇怪的 ClassCastExceptionQ明明构造的对象的类是实C指定的接口的Q可是就是无法造型到接口上?BR>q一步研I发玎ͼ即造型回原来的cM不行Q虽然调试的时候显C构造的对象是指定的类Q但是就是无法造型成这个类Q一度认为是妖h作祟或者机子被落了降头?/P>

研究
求得庄老大再次出手Q一下指出指出问题在于不同的c装载器装蝲的类无法怺造型的。于是进去junit.swingui.TestRunner里面Lc装载器Q一L腾之后终于找刎ͼ

junit.runner.BaseTestRunner
           |Q-Q-Q-junit.swingui.TestRunner
           |Q-Q-Q-junit.textui.TestRunner

在BaseTestRunner里面定义了这样一个方法:
    public TestSuiteLoader getLoader() {
        if (useReloadingTestSuiteLoader())
            return new ReloadingTestSuiteLoader();
        return new StandardTestSuiteLoader();
    }
不过注意到junit.textui.TestRunner是不会出上面的错误的Q因为它自己重蝲了getLoader()ҎQ?BR>    /**
     * Always use the StandardTestSuiteLoader. Overridden from
     * BaseTestRunner.
     */
    public TestSuiteLoader getLoader() {
        return new StandardTestSuiteLoader();
    }
但是junit.swingui.TestRunner很自作聪明了,Z避免每次在点“run”按钮的时候装载运行器本nQ就直接使用了基cȝҎ去获取装载器Q,q样基类可以调用自qgetLoaderҎ来决定要启用那个classloaderQ?/P>

    public TestSuiteLoader getLoader() {
        if (useReloadingTestSuiteLoader())
            return new ReloadingTestSuiteLoader();
        return new StandardTestSuiteLoader();
    }

如果我们用sun的jdk的话Q这个方法会q回一个TestCaseClassLoader对象Q而这个对象在装蝲class的时候L调用creatLoaderҎQ?BR>    protected TestCaseClassLoader createLoader() {
        return new TestCaseClassLoader();
    }

q回的其实是TestCaseClassLoader。这样如果被试cM用了log4j的话Q会造成org.apache.log4j.Appenderc被 sun.misc.Launcher$AppClassLoader(也就是sun.misc.Launchercȝ嵌入cAppClassLoader)装蝲一ơ(在启动test的过E中vm自动装蝲被引用到的类Q,然后在运行的时候又被junit.runner.TestCaseClassLoader再装载一ơ。由两个装蝲器装载进来的cM是不是来自同一?class文gQ都会被认ؓ是两个不同的cR因此就造成了上面的错误?BR>同样的,如果你在自己的代码里面这栯载类Q?BR>MyClass myClass = (MyClass)Thread.currentThread().getContextClassLoader().loadClass(mClassName);
也会造成相同的问题ƈ抛出ClassCastException。因为MyClass是在q行试的过E由junit.runner.TestCaseClassLoader装蝲的,而Thread.currentThread().getContextClassLoader()却指向的是sun.misc.Launcher$AppClassLoader?/P>

解决Ҏ
1 java -Dlog4j.ignoreTCL junit.swingui.TestRunner
我猜TCL是ThreadClassLoader的羃写,q个参数的意思大概就是让log4j忽略Thread自己的类装蝲器(sun.misc.Launcher$AppClassLoaderQ,改而用当前Class的装载器Qjunit.runner.TestCaseClassLoaderQ来装蝲。但是这个方法只能解决log4j的错误报告(改变了org.apache.log4j.ConsoleAppender的装载方式)Q但是对我们自己写的代码中的问题却没有作用?/P>

2 在我们自qc里面写上一D静态代码:
  static{
        Thread.currentThread().setContextClassLoader(MyClassFactory.class.getClassLoader());
  }
和方法一cMQ这也是在工厂类中用加蝲了当前lass的装载器QTestCaseClassLoaderQ来代替Thread的初始化装蝲器sun.misc.Launcher$AppClassLoader。这个方法可以解x们自׃码中的问题,q且不会带来影响原来的其他代码。结合第一U方法可以解决上面的两个问题。但是如果你有好几个工厂c,或者你用的其他包里面用了这L装蝲方式……那你还可以试试下面的偏门:

3 注意到BaseTestRunner要进行一个useReloadingTestSuiteLoader()判断才决定返回哪个装载器
public TestSuiteLoader getLoader() {
    if (useReloadingTestSuiteLoader())
        return new ReloadingTestSuiteLoader();
    return new StandardTestSuiteLoader();
}
我们来看看这个判断过E:
protected boolean useReloadingTestSuiteLoader() {
    return getPreference("loading").equals("true") && !inVAJava() && fLoading;
}
嗯,里面有个inVAJava()是什么玩意儿Q?BR>public static boolean inVAJava() {
    try {
        Class.forName("com.ibm.uvm.tools.DebugSupport");
    }
    catch (Exception e) {
        return false;
    }
    return true;
}
原来它是惛_断如果当前用的是ibm的虚拟机׃用默认装载器Q但是判断的条g也忒单了点,很容易就吧它l蒙q去了:
在当前工E下创徏com.ibm.uvm.tools包,在其中创建DebugSupportc:
package com.ibm.uvm.tools;
public class DebugSupport{}
没有错,p个空白的c,q样可以把junit.swingui.TestRunnerl蒙倒。这样做据说的副作用是,每次点run按钮的时候,都要重vgui环境Q但是我没有发现有什么区别。不q要是没有区别,人家又干吗费那么多事呢?不解?/P>

参考资?/P>

http://mail-archives.apache.org/mod_mbox/logging-log4j-user/200301.mbox/%3C3E1F1A31.2000605@attbi.com%3E


[点击此处收藏本文]
发表?2005q?4?9?10:48 AM


maggie 发表?SPAN>2005-04-29 11:43 AM  
果然看不不懂

emu 发表?SPAN>2005-04-29 6:02 PM  
你将来长大了懂了呵?/DIV>

Pingback/Trackback 发表?SPAN>2005-04-29 6:36 PM  
试一?/DIV>

linux_china 发表?SPAN>2005-05-12 8:13 PM  
please modify excluded.properties in junit.jar,and execude some package will be all right.


emu 2005-05-18 14:08 发表评论
]]> վ֩ģ壺 | | | | | ƽ˳| ľ| | Ͼ| | | ݳ| | | | ̶| | | | | ƽ| ϲ| | | | DZ| | ƺ| | ľ| | | ϴ| Т| | | | ˫| ܿ| ϵ| |