`
spring-china
  • 浏览: 50627 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

记一次500 Unable to instantiate Action错误(2011-2-27)

阅读更多
    今天周末,但是项目快要进入UAT,所以项目组的几位哥们都自发的去公司加班,因为bug有一堆需要解决,才到公司打开skype,身在旧金山的D哥就发过来一封Email说才部署到客户那边的一个新功能有问题,这个功能我也参与其中,所以便义不容辞的要拿下来了.
    首先简单的介绍一下,项目采用的是Struts2.0.14 + Hibernate 3.2.6 ga + Spring 2.5.6作为各层的实现,表现层大量使用了Extjs.
    从Email上的截图可以看到错误时一个弹出框,根据上面的提示信息搜了一下code,发现是发送一个Ajax请求时对应的action发生错误,但是苦于今天的VPN网络速度实在是太慢,完全登陆不上客户那边进行详细的查看,正好QA说本地也能重现该错误,那OK,在本地起个server来看看.
    但是清晰的记得在上code之前,在本地是做过测试的,不会有这个问题,先暂且看看再说。
    server一起来,拿了一个符合条件的数据进行测试,哎,还真有这错,通过Firebug进行详细的查看,有如下错误信息:
   
Unable to instantiate Action, reportCbxReportAction, defined for 'reportGenCbxReport' in namespace '/'Error creating bean with name 'reportCbxReportAction' defined in file [C:\cvs\project\target\classes\spring\actionContext.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'defaultReportName' threw exception; nested exception is java.lang.ArrayIndexOutOfBoundsException: 1

    是个数组越界的错误,这下我来劲了,应该会比较好定位(提示很明显:这个bean: reportCbxReportAction的这个属性:defaultReportName),呵呵. 
    去到相应的文件actionContext.xml的相关代码处:
   
    <bean id="reportCbxReportAction" scope="prototype"
          class="com.springchina.report.web.cbxReportAction">
        <property name="defaultReportName" value="${cbxReport.defaultReportName}"/>
    </bean>

    defaultReportName这个属性还引用了properties文件中的值,于是再继续追踪properties文件的相关内容
   
cbxReport.defaultReportName=MARKET_PO_SUMMARY_V001-[Curr_Date_YYMMDD],PO_PREPACK_V001-[Curr_Date_YYMMDD],TICKET_PO_V001-[Curr_Date_YYMMDD]

    看来问题就是出在将这个属性值赋值给defaultReportName这个属性时出错了,于是进一步定位到reportCbxReportAction这个bean对应的action类中关于defaultReportName的setter方法来一探究竟
    以下是具体的setter方法:
   
    
      private final Map<String,String> defaultFileNames = new HashMap<String, String>();

       public void setDefaultReportName(final String defaultReportName) {
        this.defaultReportName = defaultReportName;
        if(defaultFileNames.size() == 0){
            final String[] defaultFileNameArray = defaultReportName.split(",");
            for(final String s : defaultFileNameArray){
                final String[] temp = s.split(":");
                this.defaultFileNames.put(temp[0], temp[1]);
            }
        }
    }

    看了看这段代码,看来并不是在设属性defaultReportName的时候出错,而是下面这部分,对拿出来的defaultReportName值进行循环的分割出了错,其实也就是两次分割,第一次是通过','来split,得到了第一个String数组,而第二次则是对这个数组中的每一个String再按照':'来split,得到的String数组的第一,二个元素分别作为key,value被放入defaultFileNames这个Map里面.这个时候再回过头去检查一下properties文件中的cbxReport.defaultReportName这个属性,已经可以看到端倪了,呵呵,我们并没有按照这种首先通过逗号,再通过分号分割的形式来组织数据,在第一次按照逗号分割的情况下,没有问题,都能够顺利分割,但是在第二次按照冒号分割的情况下,每个子String[]由于都不含有':',所以只能整个的被作为一个temp[0],而没有temp[1],这样,在put(temp[0], temp[1])的时候,由于引用了越界下标的数组,就会报异常了.
    基于这样的分析,我改动了一下properties文件中对应的属性值:按照代码的解析规则,加上了按照:分割的部分,如下所示:
   
cbxReport.defaultReportName=PO-SUMMARY:MARKET_PO_SUMMARY_V001-[Curr_Date_YYMMDD],PO-PACK:PO_PREPACK_V001-[Curr_Date_YYMMDD],PO-TICKET:TICKET_PO_V001-[Curr_Date_YYMMDD]

    这样,重新启动服务器,再次进入相关的功能模块进行操作,就没有异常了.但是撇开相应的功能不说,我觉得这种编码方式还可以再提高一点,至少应该把数组越界这种情况考虑在内,这样如果不熟悉规则的program进行配置,就不会再出现类似的异常错误了.至于为什么在我进行单元测试的时候没有发现问题,现在也明白了,肯定是另外一个同事提交了这部分的code,而我在测试的时候并没有应用到这部分最新的code,呵呵,这也是一个应该注意的问题,完成同样功能的几个人,应该相互协调,相互交流,以便有最新的代码的更改时能够及时获悉及时测试,避免不必要的错误发生.
    哈哈,最后其实我还有一个不明白的问题,我在查看log信息的时候,发现在spring容器启动的时候,就已经调用了这段setter代码对相关的defaultReportName属性进行了设置,但是为什么在那个时候没有出现exception信息导致容器不能启动呢?而是在用户请求这个action的bean的时候才出现数组越界的exception?这个问题还没有想明白,第一次在这里发帖,也望各位能够指点一二,谢谢 
    先睡觉,明天继续备战UAT,哈哈.

   
   
   
分享到:
评论

相关推荐

    解决Hive启动失败Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

    FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient 通过控制台的...

    SSH登录无实例化例子

    SSH(Secure Shell)是一种网络协议,用于在不安全的网络环境中提供安全的远程登录和其他服务。在SSH中,“无实例化”通常指的是不通过创建一个完整的SSH连接对象(即实例化一个SSH客户端类)来执行命令,而是直接...

    Axis2WebService与Spring的整合

    在IT行业中,Web服务是应用程序之间进行通信的一种标准方式,而Axis2是Apache软件基金会开发的一个流行的Java Web服务框架。Spring框架则是Java企业级应用的事实标准,提供了强大的依赖注入、AOP(面向切面编程)等...

    WebService大讲堂之Axis2,多个实例

    Axis2是一个高效、模块化的Web服务引擎,用于构建和部署Web服务和客户端。Axis2不仅支持SOAP协议,还支持REST风格的服务,同时还整合了Spring框架和JSON等其他流行技术。本系列教程将涵盖从基础到高级的Axis2使用,...

    BroadcasReceivert的两种注册模式

    在Android系统中,BroadcastReceiver(广播接收者)是一种重要的组件,用于监听系统或应用程序发出的各种广播事件,并在接收到广播时执行相应的操作。标题提到的“BroadcasReceivert的两种注册模式”指的是...

    yii2-deep-instantiate

    Yii 2深度实例化 该软件包提供了Yii 2依赖注入器容器,该容器能够自动解决嵌套的构造函数接口类型的依赖项。 要求 Yii 2.0.39.3+ PHP 7.0以上 安装 composer require bizley/deep-instantiate:^1.0 用法 直接-只需...

    fabric网络踩坑记录

    我的版本 unbuntu 64位(2) fabship2 runApp.sh buildchannel.sh ... cause:instantiate proposal resulted in an error :: Error: 2 UNKNOWN: chaincode error (status: 500, message: is not a valid endorseme

    Unity3D教程:Prefabs与Instantiate1

    它可以被置入多个场景中,又或者能够在一个场景中被多次置入。当你在一个场景中增加一个 Prefabs,你就实例化了一个 Prefabs。所有 Prefabs 实例都是 Prefab 的克隆,只要 Prefabs 原型发生改变,所有的 Prefabs ...

    instantiate-blocks.rar_threads

    "Instantiate-blocks.c"文件可能涉及到了Objective-C的Block对象在多线程环境下的实例化和使用。Blocks是Objective-C的一个特性,类似于匿名函数,允许代码块作为第一类对象进行传递和存储。在多线程环境中,创建和...

    unity液体系统Obi Fluid 3.2.zip

    - Simulation state gets serialized -&gt; save your fluids mid-simulation-&gt;instantiate them already warm-started. - Supports Box, Sphere, Capsule, Mesh, Character and Terrain colliders. - Automatic ...

    Obi Fluid 3.2

    - Simulation state gets serialized -&gt; save your fluids mid-simulation-&gt;instantiate them already warm-started. - Supports Box, Sphere, Capsule, Mesh, Character and Terrain colliders. - Automatic ...

    rgb2dvi.rar

    -- "MMCM" or "PLL" to instantiate, if kGenerateSerialClk true kClkRange : natural := 1; -- MULT_F = kClkRange*5 (choose &gt;=120MHz=1, &gt;=60MHz=2, &gt;=40MHz=3) kRstActiveHigh : boolean := true); --...

    Unity3D入门 :Prefabs(预设)与 Instantiate(实例化)

    在Unity3D游戏开发中,Prefabs(预设)和Instantiate(实例化)是两个非常重要的概念,它们是构建游戏对象和动态管理游戏世界的基石。本文将深入探讨这两个概念,帮助初学者理解并掌握它们在实际项目中的应用。 ...

    java二进制补码源码-instantiate-two-instances-of-same-class:Java初学者基础练习

    Java程序的基本结构练习:创建同一个类的多个对象 请在中创建指定类的多个对象并修改其成员。在提交Pull Request之前,你应当在本地确保所有代码已经编译通过,并且通过了测试(mvn clean verify) 注意!我们只允许你...

    ar.com.tadp.xml.rinzo

    3. **错误检测与高亮**:在编写过程中,插件会实时检查语法错误,并用醒目的方式标注出来,方便开发者及时修正。 4. **XSD/DTD支持**:支持XML Schema Definition (XSD) 和 Document Type Definition (DTD),能对XML...

    android常见错误

    **问题描述**:此错误发生在尝试编译一个项目时,编译器无法识别目标API版本`android-2`。通常是因为默认的API版本配置与实际可用的版本不匹配。 **解决方案**: - 检查项目的`default.properties`文件中的`target`...

    JAF 1.0.2 下载

    discover the operations available on it, and to instantiate the appropriate bean to perform said operation(s). For example, if a browser obtained a JPEG image, this framework would enable the browser...

    yamaha-yxc-nodejs:适用于MusicCast的Yamaha扩展控制NodeJS库

    Yamaha-YXC-nodejs 一个节点模块,用于控制Yamaha MusicCast设备(受yamaha-nodejs启发)。 该模块使用Yamaha扩展控制协议。 应该可以控制扬声器,条形音箱等。经过WX-010和YSP-1600测试。安装npm安装yamaha-yxc-...

    Java Mime Magic Library-开源

    Java Mime Magic Library,通常被称为 jMimeMagic,是一款在Java平台上用于识别文件或输入流MIME类型的开源库。MIME(Multipurpose Internet Mail Extensions)类型是互联网标准,用于标识不同类型的二进制或文本...

    C++简单练习.cpp

    Instantiate two different objects of class SavingsAccount, saver1 and saver2, with balances of $2000.00 and $3000.00, respectively. Set the annualInterestRate to 3 percent. Then calculate the monthly...

Global site tag (gtag.js) - Google Analytics