spring - Grails:验证域对象时出现 'methodInvocation'错误代码

标签 spring grails gorm

两个星期以来,出现了一个大问题!
它仅在生产中出现(不在开发,集成,预生产模式中),并且在几个小时后才出现。

症状:一旦发生“某事”,用户将无法注册。经过数天的调查,我不知道该如何复制这两个问题。
目前,我们有丑陋的解决方法来重新启动tomcat实例,但这非常丑陋。

有关信息,两个交付之间的差异与注册过程无关。

我认为这是相关的:

域:

class UserAccount implements Serializable {
    static transients = ['tokenLogin']
    String email
    String pwd
    Date creationDate = new Date()
    String tokenLogin


    //[skip] dozen of other attributes

    static constraints = {
        email(matches:EmailRegexp,blank:false)
        pwd(blank:false)
        tokenLogin(editable:false)
    }

    public void setEmail(String email) {
        this.email = email
        authId = authenticationChannel.getUsername(email)
        // We must recalculate token login
        this.tokenLogin = generateTokenLogin(email, creationDate, pwd)
    }

    public void setPwd(String pwd) {
        this.pwd = pwd
        // We must recalculate token login
        this.tokenLogin = generateTokenLogin(email, creationDate, pwd)
    }

    public static String generateTokenLogin(String email, Date creationDate, String pwd) {
        // work well
        // even tested when return null or with NPE in it and does not produce the same log
        generated = // work with MessageDigest, MD5, salt, etc. (not disclosed, because we are currently under security audit)
        return generated;
    }
}

Controller :
def saveAccount = {
    def user = new UserAccount(email: params.email?.trim(), pwd: params.pwd) // More parameters, but here what is relevant
    user.validate()
    if(user.hasErrors()) log.info("${user.errors}") // added since the issue appears
    // Other verification (unicity, clear password verification, etc.)
    // Password encryption
    // user.save()
}

输出日志:
2013-06-03 15:37:32,165 [TP-Processor46] INFO  controller.UserAccountController  - org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'domain.UserAccount' on field 'pwd': rejected value [foobar]; codes [methodInvocation.domain.UserAccount.pwd,methodInvocation.pwd,methodInvocation.java.lang.String,methodInvocation]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [domain.UserAccount.pwd,pwd]; arguments []; default message [pwd]]; default message [Property 'pwd' threw exception; nested exception is java.lang.NullPointerException]

问题:
  • 此输出如何显示?我们看到此输出用于pwdemail字段,而从未用于其他输出。
  • “me​​thodInvocation”代码的含义是什么? (我在 Spring 上下文中已经看到,当MethodInvocationException捕获异常时会抛出BeanWrapperImpl.setPropertyValue)
  • 如何获取更多信息? (现在,我们运行一个修补的spring-context.jar,在BeanWrapperImpl中显示StackTrace,但直到现在我们都无法重现)

  • 信息:
  • Grails 1.3.7 => Spring 3.0.5-GA
  • Mysql jdbc
  • Tomcat 6

  • start.sh中(tomcat选项)
    JAVA_OPTS="-Dapp=prod -Xms1024m -Xmx1024m -XX:MaxPermSize=256m \
    -Dfile.encoding=UTF-8 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC \
    -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled \
    -XX:+HeapDumpOnOutOfMemoryError \
    -Xloggc:/path/to/gc.log"
    

    编辑:
    我们更改并编译spring-context.jar以便能够看到StackTrace。我们得到这个:
    org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessException details (1) are:
    PropertyAccessException 1:
    org.springframework.beans.MethodInvocationException: Property 'pwd' threw exception; nested exception is java.lang.NullPointerException
            at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1127)
            at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:900)
            at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
            at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:673)
            at org.springframework.validation.DataBinder.doBind(DataBinder.java:569)
            at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:191)
    [snip]
    Caused by: java.lang.NullPointerException
            at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.checkCall(PojoMetaClassSite.java:54)
            at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:42)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
            at domain.UserAccount.generateTokenLogin(UserAccount.groovy:369)
            at domain.UserAccount$generateTokenLogin.callStatic(Unknown Source)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:48)
            at domain.UserAccount$generateTokenLogin.callStatic(Unknown Source)
            at domain.UserAccount.setPwd(UserAccount.groovy:184)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:597)
            at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1114)
    

    根本原因是存在一个creationDate,在某些奇怪的情况下可能是null。我猜想解决方案不是在setter中(仅在getter中)调用generateTokenLogin()

    我无法解释为什么我们以前没有这个问题(最近没有升级等)

    最佳答案

    听起来好像一旦发生这种情况,就必须重新启动才能解决。我会看看您的应用程序的permgen大小。如果它在每种环境下都能正常生产,则可能是内存问题。

    测试的简单方法是添加200兆个左右开始。

    关于spring - Grails:验证域对象时出现 'methodInvocation'错误代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16984613/

    相关文章:

    grails - Grails Spring Security密码输入错误

    grails - Grails findBy用外键查询

    hibernate - Grails 3 beforeInsert()没有停止关联的插入?

    java - 并发环境下的Ehcache ReentrantReadWriteLock

    java - 自动为 transient 属性赋值

    java - Controller /Servlet 在 ServiceAPI 上抛出 NoClassDefFoundError

    java - JPA 示例 Spring Boot 应用程序抛出 BeanCreationException

    grails - 结合使用IntelliJ和JBoss来创建Grails应用

    grails - 在 Grails 中,如何根据 LDAP 身份验证创建和/或更新用户,然后登录?

    grails - 最佳实践-通过静态字段获取域对象吗?