簡體   English   中英

ArrayIndexOutOfBoundsException:在Grails域類的this()中為0

[英]ArrayIndexOutOfBoundsException: 0 in this() of Grails Domain Class

我正在研究一個拆分的Grails-Project,請參見此處: grails3,它使用域類插件,特別是spring security User / Role

基本上,我試圖將我的域類放入一個可以在多個其他項目中使用的插件。

嘗試啟動服務器時出現此異常:

ERROR org.springframework.boot.SpringApplication - Application startup failed
java.lang.ArrayIndexOutOfBoundsException: 0
        at wcommon.WebsiteRole.<init>(WebsiteRole.groovy:15)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1075)
        at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
        at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at BootStrap$_closure1.doCall(BootStrap.groovy:9)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
        at org.codehaus.groovy.ron.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1086)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021)
        at groovy.lang.Closure.call(Closure.java:426)
        at groovy.lang.Closure.call(Closure.java:420)
        at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:437)
        at grails.util.Environment.executeForEnvironment(Environment.java:430)
        at grails.util.Environment.executeForCurrentEnvironment(Environment.java:406)
        at org.grails.web.servlet.boostrap.DefaultGrailsBootstrapClass.callInit(DefaultGrailsBootstrapClass.java:62)
        at org.grails.web.servlet.context.GrailsConfigUtils.executeGrailsBootstraps(GrailsConfigUtils.java:65)
        at org.grails.plugins.web.servlet.context.BootStrapClassRunner.onStartup(BootStrapClassRunner.groovy:53)
        at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:240)
        at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:381)
        at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:335)
        at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:855)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:140)
        at org.spmework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
        at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:55)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:365)
        at grails.boot.GrailsApp.run(GrailsApp.groovy:354)
        at grails.boot.GrailsApp$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
        at webp.Application.main(Application.groovy:8)
:WebP:bootRun FAILED

我完全不知道為什么會這樣。 有問題的行是對this()的調用,為什么會拋出這樣的異常? 我最初的反應是刪除this()並向該類添加一個空的默認構造函數,但這顯然破壞了依賴注入,這導致了我上面喜歡的問題中描述的問題。

我這邊涉及的代碼是:

package wcommon

import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes='authority')
@ToString(includes='authority', includeNames=true, includePackage=false)
class WebsiteRole implements Serializable {

    private static final long serialVersionUID = 1

    String authority

    WebsiteRole(String authority) {
        **this();** // line 15
        this.authority = authority
    }

    static constraints = {
        authority blank: false, unique: true
    }

    static mapping = {
        cache true
    }
}


import grails.core.GrailsApplication
import wcommon.WebsiteUserWebsiteRole;

class BootStrap {

    GrailsApplication grailsApplication

    def init = { servletContext ->
        **WebsiteUserWebsiteRole.initDefaults(grailsApplication)** //line 9
    }
    def destroy = {
    }
}

initDefaults函數如下所示:

**static def initDefaults(GrailsApplication grailsApplication) {
    def patientRole = new WebsiteRole("ROLE_PATIENT").save();
    def adminRole = new WebsiteRole("ROLE_ADMIN").save()
    def doctorRole = new WebsiteRole("ROLE_DOCTOR").save()
    def nurseRole = new WebsiteRole("ROLE_NURSE").save()
    def serverRole = new WebsiteRole("ROLE_SERVER").save()

    def user1 = new WebsiteUser("admin", "password").save()
    WebsiteUserWebsiteRole.create user1, adminRole, true

    def user2 = new WebsiteUser("doctor", "password").save()
    WebsiteUserWebsiteRole.create user2, doctorRole, true

    def user3 = new WebsiteUser("nurse", "password").save()
    WebsiteUserWebsiteRole.create user3, nurseRole, true


}**

編輯:使用Grails 3.1.1版

java -version是1.7.0_79

春季安全性插件是“ org.grails.plugins:spring-security-core:3.0.3”

我不太確定我使用的是哪個數據庫版本,默認情況下,我只是使用包括的h2,依賴項只是說:運行時“ com.h2database:h2”

通常,項目設置是我的Domain類在一個項目中,這是一個插件項目。 有問題的項目在依賴項中包括通過編譯項目(':WebCommon')的Domain類。 編譯正常。

編輯2:因此,如果我刪除this()並添加一個默認構造函數,它不會引發異常,但是在此類中,Spring Security服務的依賴項注入不起作用:

package wcommon

import grails.plugin.springsecurity.SpringSecurityService;
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString

@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class WebsiteUser implements Serializable {

    private static final long serialVersionUID = 1

    public SpringSecurityService springSecurityService

    String username
    String password
    boolean enabled = true
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    WebsiteUser() {

    }

    WebsiteUser(String username, String password) {
        this.username = username
        this.password = password
    }

    Set<WebsiteRole> getAuthorities() {
        WebsiteUserWebsiteRole.findAllByWebsiteUser(this)*.websiteRole
    }

    def beforeInsert() {
        encodePassword()
    }

    def beforeUpdate() {
        if (isDirty('password')) {
            encodePassword()
        }
    }

    protected void encodePassword() {
        println springSecurityService // prints null
        password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
    }

    static transients = ['springSecurityService']

    static constraints = {
        username blank: false, unique: true
        password blank: false
    }

    static mapping = {
        password column: '`password`'
    }
}

將屬性從def springSecurityService更改為public SpringSecurityService后,它告訴我HttpServletRequest的間接依賴關系。 將這些依賴項添加到插件項目可以解決此問題,但這不會改變注入無效的任何內容:

compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-web-boot"

我認為我對User和Role類的更改以解決this()問題導致了依賴項注入問題。 但是也許我錯了,這兩個問題都是由其他原因引起的,可能與我的項目設置有關。 我不知道,這真是令人困惑,從昨天開始就一直在努力。

編輯:為了使其正常工作,現在我首先通過移除this()並添加默認構造函數來修復異常,然后將springSecurityService注入到我的主項目的Bootstrap中,該項目用於在該類中的類上設置靜態公共字段ssneed springSecurityService的插件項目。 丑陋,但是它比我迄今為止嘗試過的任何方法都好。 ...好吧,現在對控制器進行以下簡單測試:

import grails.converters.JSON
import grails.plugin.springsecurity.annotation.Secured

@Secured(['ROLE_ADMIN', 'ROLE_SERVER'])
class ApiController {

    def index() {
        render getAuthenticatedUser() as JSON
    }
}

拋出有關getAuthenticatedUser()的MissingMethodException

那個Controller是通過create-controller添加的,我想這整個“將項目分成多個部分”根本無法正常工作,並且破壞了很深的東西,導致所有這些問題都出現了。 我認為,與其嘗試拆分項目,不如創建一個單獨的Web應用程序項目,該項目配置有一個標志,該標志指示其激活和停用的功能。

如果有人可以告訴我如何使用公共庫中的公共域對象來正確地拆分grails項目,請參閱此問題並在此處發布: grails3使用域類插件,特別是spring security User / Role

您可以安全地從這些類( WebsiteUserWebsiteRoleWebsiteUserWebsiteRole類)中刪除所有構造函數。 這也應該解決bean注入問題。 無需在初始化中調用它們,而是可以使用所有地圖樣式構造函數。

static def initDefaults(GrailsApplication grailsApplication) { def patientRole = new WebsiteRole(authority: "ROLE_PATIENT").save(); ... def userX = new WebsiteUser(username:"nurse", password:"password").save() WebsiteUserWebsiteRole.create user3, nurseRole, true }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM