`
white_crucifix
  • 浏览: 96752 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

在使用StrtusSpringTestCase时调用getActionProxy时抛nullpointer的原因

阅读更多
给我这孱弱的博客添一篇文章吧……
=========================================================================

最近没事想玩一下Struts2的单元测试,然后查了下一般可以用StrutsSpringTestCase来做,这个类继承自StrutsTestCase。在网上搜了下简单的例子。

因为struts测试库是模拟出request等web环境,所以不需要跑在tomcat里,可以直接run junit。模拟action的第一步就是调用getActionProxy()方法。如:
ActionProxy proxy = getActionProxy("/login.action");


然后一跑就给我报错。
Unable to instantiate Action, personAction,  defined for 'login' in namespace '/'personAction
.
.
.
.
Caused by: java.lang.ClassNotFoundException: personAction
.
.
.	


这个错一般都是由于spring配置错误或位置存放错误导致了没有帮UserAction创建之类的。然后反复检查了applicationContext.xml, web.xml甚至是struts.xml,没发现什么问题。最重要的是项目在tomcat里运行完全正常。总觉得配置文件应该不会有问题。于是就纳闷了,开始满世界的网上搜。但是结果不理想。无论是国内还是国外的资料似乎都不能帮我解决问题。难得在国外的论坛上找到和我一样问题的人,结果没有人解答。国内的搜索,事后回想其实还是有正确解答的。只不过感觉没说清楚。

于是没办法,只能开始debug源码,希望能有点进展。最后通过调试struts spring源码终于找到问题所在了。 当我绕了一大圈debug到StrutsSpringTestCase类里,看到第一行写了:
static final String DEFAULT_CONTEXT_LOCATION ="classpath*:applicationContext.xml" 

一瞬间蛋都碎了……

classpath*:applicationContext.xml

spring默认读取/WEB-INF下的app...xml,居然TestCase默认读取classpath下…… 而我的app...xml放在了默认的/WEB-INF/下。那当然创建不了自己定义的bean了。此时我试了一下,将app...xml搬到了类路径下,果然就成功了。

本来这样就想算了,后来想想,能不能把StrutsSpringTestCase配置成读取我自定义的路径。

 protected void setupBeforeInitDispatcher() throws Exception {
        // only load beans from spring once
        if (applicationContext == null) {
            GenericXmlContextLoader xmlContextLoader = new GenericXmlContextLoader();
            applicationContext = xmlContextLoader.loadContext(getContextLocations());
        }

        ........
}
protected String[] getContextLocations() {
        return new String[] {DEFAULT_CONTEXT_LOCATION};
    }


这里加载上下文的方法loadContext直接读取了那个默认的静态变量DEFAULT_CONTEXT_LOCATION,也就是"classpath*:applicationContext.xml"。而loadContext方法的实现不断深入,关于路径变量locations都是一些其他的判断和字符上的改变,没有我预想中的如果判断为空,再怎么怎么。换句话说,loadContext方法处已经将最终的路径给定死了。而且似乎没有去读web.xml中的内容(这毕竟不是真的web容器),所以我即使在web.xml中配置了路径也没有生效。


其实最后两点我还是对自己有点怀疑。觉得这struts测试lib也不能hardcode成这样,默认是好事。。也得可配,至少读一下web.xml吧
分享到:
评论

相关推荐

    Null Pointer;

    在提供的文件名列表中,我们看到有`nullpointer.ttf`,这很可能是一个TrueType字体文件。TrueType是一种广泛使用的字体格式,常用于Windows和Mac操作系统。如果在代码中尝试使用这个字体文件而文件实际不存在或者...

    MFC使用WebBrowser控件调用百度地图API案例

    在本文中,我们将深入探讨如何使用MFC(Microsoft Foundation Class)中的WebBrowser控件来调用百度地图API,实现地图功能的集成。首先,我们理解MFC是一个C++库,它为Windows应用程序开发提供了一套丰富的类库,...

    C#中在一个窗体里调用另一个窗体的方法

    当需要在一个窗体中调用另一个窗体时,可以通过实例化目标窗体的方式来实现。例如,在`FormReportList`中创建`FormPubs`对象: ```csharp public FormPubs fp; public FormReportList(FormPubs f) { fp = f; ...

    vb6.0调用webservice详解

    由于VB.NET的普及,很多开发者更倾向于使用.NET框架,但考虑到VB6的广泛使用和某些特定场景的需求,仍然需要了解如何在VB6环境中调用Web服务。 首先,VB6.0调用Web服务有两种主要方法:一是通过SOAP(简单对象访问...

    java 调用webservice使用HttpClient和XFire两种方式

    本文将详细介绍如何使用HttpClient和XFire这两种不同的库来调用Web Service,特别是针对短信接口的调用。 首先,让我们了解Web Service的基本概念。Web Service是一种基于互联网的、平台无关的交互方式,它允许不同...

    C++ 调用带参数EXE

    在选择调用EXE的方法时,通常会根据项目的需求来决定。如果只是简单执行一个无参数的程序,`system`可能是最简单的选择。而如果需要更复杂的控制,如传递参数、控制窗口显示或等待子进程结束,那么`CreateProcess`或...

    在子窗口中调用父窗口的成员函数的实例

    在子窗口中调用父窗口的成员函数的方法 1、用FindWindow("类名(可以是派生类)","窗口标题")或GetParent(),二者均能返回父窗口句柄,并能直接使用其成员函数。但是此法只能调用CWnd类里的成员函数,而不能调用自己...

    C# 调用C++DLL(函数参数包含指针)

    本篇文章将深入探讨如何在C#中调用一个C++DLL,特别是当DLL函数参数中包含指针时的处理方法。 首先,理解C#与C++之间的互操作性是关键。.NET框架提供了一个名为P/Invoke(Platform Invoke)的机制,允许C#代码调用...

    c++如何采用com组件的方法直接调用动态库

    COM 组件可以是动态链接库(DLL),在 C++ 中调用 COM 组件可以使用智能指针来简化操作。 在 C++ 中调用 COM 组件的方法有多种,下面我们将详细介绍三种常用的方法: 方法一:使用 #import 导入类型库 使用 #...

    java调用json参数的webservice

    在探讨Java调用带有JSON参数的WebService之前,我们首先需要了解几个关键的技术概念:Java、JSON以及WebService。 Java是一种广泛使用的编程语言,它具有面向对象、跨平台、多线程以及健壮性等特点。Java在企业级...

    最简单的C++动态调用DLL

    在C++编程中,动态链接库(DLL)是一种可共享的代码库,它可以在运行时被多个程序调用,以实现代码复用和模块化。本篇将详细讲解如何进行C++动态调用DLL,主要基于提供的资源链接,并结合"CallDLLDynamic"压缩包中的...

    VC++2008调用大漠插件方法!

    ### 如何在VC++2008中调用大漠插件 对于许多从事游戏辅助开发工作的程序员来说,能够熟练地使用外部插件是提高工作效率的关键之一。大漠插件(DM.DLL)因其强大的功能和灵活性而在这一领域内广受好评。本文将详细...

    C#调用大漠插件

    本例子是一个C#类库,可以发布为DLL文件给其他项目调用;...使用完毕后需调用:dm.close();释放大漠对象,否则资源会占用过多 注意: 需要.net FrameWork4.5环境 开发工具为:visual studio 2013

    Qt on Android调用Jar包

    在Qt on Android的上下文中,我们可以使用JNI来调用Java代码,这些代码可能封装在.jar文件中,如第三方库。 步骤1:准备Java层 创建一个Java类,该类将作为与.jar包交互的桥梁。这个类需要继承自`java.lang.Object`...

    动态调用WebService(C#)

    在C#编程中,动态调用WebService是一种高级技巧,它允许你在运行时根据需要调用不同的Web服务,而不需要在编译时就确定具体的URL或方法。这种灵活性尤其有用,当你需要处理Web服务URL变动或者需要动态选择服务时。...

    PB调用C#写的dll文件

    标题中的“PB调用C#写的dll文件”指的是在PowerBuilder(PB)应用程序中使用C#编译的动态链接库(DLL)文件。这通常涉及到跨语言互操作性,允许不同编程语言之间的通信和功能共享。 C#是一种现代、面向对象的编程...

    JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单

    使用C/C++编译器(如GCC或Visual C++)编译源代码,并链接到Java运行时库。创建DLL文件,例如`myDll.dll`。 6. **运行Java程序** 在Java程序中,通过`System.loadLibrary`加载生成的DLL,然后就可以调用C/C++实现...

    C#调用java类、jar包方法

    在跨平台开发中,有时需要将不同编程语言的组件整合在一起,例如在C#应用中调用Java类或使用Java的jar包。本篇将详细阐述如何在C#环境中实现对Java类的调用以及使用Java的jar包。 首先,要理解C#与Java之间的互操作...

    携程外部接口调用试例

    在IT行业中,外部接口调用是系统间交互的重要方式,特别是在构建分布式系统和服务化架构时。本示例聚焦于“携程外部接口调用试例”,它揭示了如何与携程这样的大型在线旅行平台进行数据交互。这里我们将深入探讨相关...

    VC中打印当前调用堆栈信息实例

    在Microsoft Visual C++ (VC) 开发环境中,打印当前调用堆栈信息是一个非常有用的调试技巧,它可以帮助开发者追踪程序执行流程,理解函数调用顺序,尤其是在遇到异常或错误时。下面将详细介绍如何在VC中实现这个功能...

Global site tag (gtag.js) - Google Analytics