[英]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
您可以安全地從這些類( WebsiteUser
, WebsiteRole
和WebsiteUserWebsiteRole
類)中刪除所有構造函數。 這也應該解決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.