Reputation: 10302
I am new to grails and I am using grails 3.1.11 to write APIs that are secured with spring security 3.1.1. I am using Document DB to persist data.
Using the plugin command I created domain classes
grails s2-quickstart com.documentstore.domain User Role
which generated classes User.groovy, Role.groovy, UserRole.groovy and application.groovy in the required package. I modified the Bootstrap.groovy as follows :
import com.documentstore.domain.Role
import com.documentstore.domain.User
import com.documentstore.domain.UserRole
class BootStrap {
def init = { servletContext ->
def role = new Role(authority: 'ROLE_USER')
role.save()
def me = new User(username : 'vamsi', password : 'password')
me.save()
UserRole.create(me, role)
UserRole.withSession {
it.flush()
it.clear()
}
}
def destroy = {
}
}
When I try to run the app, I got the domain class not recognized error :
ERROR org.springframework.boot.SpringApplication - Application startup failed
java.lang.IllegalStateException: Either class [com.documentstore.domain.Role] is not a domain class or GORM has not been initialized correctly or has already been shutdown. If you are unit testing your entities using the mocking APIs
at org.grails.datastore.gorm.GormEnhancer.stateException(GormEnhancer.groovy:161)
at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy:167)
at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.currentGormInstanceApi(GormEntity.groovy:1322)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:98)
at org.grails.datastore.gorm.GormEntity$Trait$Helper$save.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:125)
at com.documentstore.domain.Role.save(Role.groovy)
at com.documentstore.domain.Role.save(Role.groovy)
at org.grails.datastore.gorm.GormEntity$save.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:117)
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.codehaus.groovy.reflection.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:1024)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1089)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:408)
Is there something wrong with the code. How can this be fixed?
the build.gradle and the plugin generated code are specified for reference:
Build.gradle
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
console "org.grails:grails-console"
compile "org.grails.plugins:spring-security-core:3.1.1"
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage
compile group: 'com.microsoft.azure', name: 'azure-storage', version: '4.3.0'
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-documentdb
compile group: 'com.microsoft.azure', name: 'azure-documentdb', version: '1.8.1'
profile "org.grails.profiles:web"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2"
//runtime "com.h2database:h2"
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-documentdb
runtime group: 'com.microsoft.azure', name: 'azure-storage', version: '4.3.0'
// https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
}
Role.groovy
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
@ToString(includes='authority', includeNames=true, includePackage=false)
class Role implements Serializable {
private static final long serialVersionUID = 1
String authority
static constraints = {
authority blank: false, unique: true
}
static mapping = {
cache true
}
}
User.groovy
package com.documentstore.domain
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
User(String username, String password) {
this()
this.username = username
this.password = password
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this)*.role
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
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`'
}
}
UserRole.groovy
package com.documentstore.domain
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
import org.apache.commons.lang.builder.HashCodeBuilder
@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {
private static final long serialVersionUID = 1
User user
Role role
UserRole(User u, Role r) {
this()
user = u
role = r
}
@Override
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id && other.role?.id == role?.id
}
@Override
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static UserRole get(long userId, long roleId) {
criteriaFor(userId, roleId).get()
}
static boolean exists(long userId, long roleId) {
criteriaFor(userId, roleId).count()
}
private static DetachedCriteria criteriaFor(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}
}
static UserRole create(User user, Role role, boolean flush = false) {
def instance = new UserRole(user: user, role: role)
instance.save(flush: flush, insert: true)
instance
}
static boolean remove(User u, Role r, boolean flush = false) {
if (u == null || r == null) return false
int rowCount = UserRole.where { user == u && role == r }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
rowCount
}
static void removeAll(User u, boolean flush = false) {
if (u == null) return
UserRole.where { user == u }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static void removeAll(Role r, boolean flush = false) {
if (r == null) return
UserRole.where { role == r }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static constraints = {
role validator: { Role r, UserRole ur ->
if (ur.user == null || ur.user.id == null) return
boolean existing = false
UserRole.withNewSession {
existing = UserRole.exists(ur.user.id, r.id)
}
if (existing) {
return 'userRole.exists'
}
}
}
static mapping = {
id composite: ['user', 'role']
version false
}
}
Upvotes: 0
Views: 1138
Reputation: 10302
This is because spring security and spring security rest plugins are dependent on hibernate, ehcache and h2 database jars. Since, I was using a different database, I have removed these jar dependencies. After I included these jars as runtime dependencies and modified the application.yml to include the default configuration for these datasources, everything worked fine as expected.
Upvotes: 1