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
}
}
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.
Related
i have integrated spring security core 3.0.4 to grails 3.0.1. After running s2-quickstart grails to create my user, role and requestMap domains, my application will return the error Gradle build terminated with error: Compilation failed
In the file user.groovy, the line import grails.plugin.springsecurity.SpringSecurityService is underlined in red.
Also in the role.groovy file the line #GrailsCompileStatic is also underlined.
please help me. thank you.
User content
packages securites
import grails.plugin.springsecurity.SpringSecurityService
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
#GrailsCompileStatic
#EqualsAndHashCode(includes='username')
#ToString(includes='username', includeNames=true, includePackage=false)
class Utilisteur implements Serializable {
private static final long serialVersionUID = 1
SpringSecurityService springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Set<Roles> getAuthorities() {
(UtilisteurRoles.findAllByUtilisteur(this) as List<UtilisteurRoles>)*.roles as Set<Roles>
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
static transients = ['springSecurityService']
static constraints = {
password blank: false, password: true
username blank: false, unique: true
}
static mapping = {
password column: '`password`'
}
}
Role content
package securites
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import grails.compiler.GrailsCompileStatic
#GrailsCompileStatic
#EqualsAndHashCode(includes='authority')
#ToString(includes='authority', includeNames=true, includePackage=false)
class Roles implements Serializable {
private static final long serialVersionUID = 1
String authority
static constraints = {
authority blank: false, unique: true
}
static mapping = {
cache true
}
}
Update your spring security core plugin to 3.1
springSecurityService service in User is always null
I can't seem to reference the package itself in the following manner
import grails.plugin.springsecurity.*;
though spring security login page does appear, and gradle doesn't complain on anything missing.
seems like no DI is taking place.
User
package com.sciencecanvas.mykingdom
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
}
#Override
int hashCode() {
username?.hashCode() ?: 0
}
#Override
boolean equals(other) {
is(other) || (other instanceof User && other.username == username)
}
#Override
String toString() {
username
}
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`'
}
}
my build :
buildscript {
ext {
grailsVersion = project.grailsVersion
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0'
classpath "org.grails.plugins:hibernate:4.3.10.5"
}
}
plugins {
id "io.spring.dependency-management" version "0.5.2.RELEASE"
id 'com.jfrog.bintray' version '1.2'
}
version "0.1"
group "monopolyserver"
apply plugin: 'maven-publish'
apply plugin: "spring-boot"
apply plugin: "war"
apply plugin: "asset-pipeline"
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.grails-gsp"
ext {
grailsVersion = project.grailsVersion
gradleWrapperVersion = project.gradleWrapperVersion
}
assets {
minifyJs = true
minifyCss = true
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencyManagement {
imports {
mavenBom "org.grails:grails-bom:$grailsVersion"
}
applyMavenExclusions false
}
dependencies {
//custom plugins
compile 'org.grails.plugins:spring-security-core:3.0.0.M1'
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile 'mysql:mysql-connector-java:5.1.36'
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:hibernate"
compile "org.grails.plugins:cache"
compile "org.hibernate:hibernate-ehcache"
compile "org.grails.plugins:scaffolding"
//compile ':spring-security-core:2.0-RC5'
runtime "org.grails.plugins:asset-pipeline"
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
// Note: It is recommended to update to a more robust driver (Chrome, Firefox etc.)
testRuntime 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.44.0'
console "org.grails:grails-console"
}
task wrapper(type: Wrapper) {
gradleVersion = gradleWrapperVersion
}
Service injection in GORM entities is disabled by default since Grails 3.2.8. Because of that, if you want the service springSecurityService to get injected in the previous domain class you would need to turn on autowire.
grails-app/conf/application.yml
grails:
gorm:
# Whether to autowire entities.
# Disabled by default for performance reasons.
autowire: true
It's because you commented out this() in the constructor - that line of code calls the generated default constructor which does DI. This is described in the "what's new" section of the docs. Either delete the constructor and use the traditional map constructor, or restore that line of code.
You can try Holders.applicationContext.getBean('springSecurityService') instead of injecting it.
I have a very strange behaviour on a production server.
When I start for the first time my server, there is no problem, but when I want to stop and restart it, I get the following error :
Configuring Spring Security Core ...
... finished configuring Spring Security Core
2013-10-31 12:03:08,156 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:277)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
2013-10-31 12:03:08,156 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing Grails: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:277)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
oct. 31, 2013 12:03:08 PM org.apache.catalina.core.StandardContext startInternal
Here is my BootStrap.groovy :
class BootStrap {
def springSecurityService
def init = { servletContext ->
def existingAdminRole = Role.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole.user
}
if (!existingAdminUser) {
def adminRole = new Role(authority: 'ROLE_ADMIN')
def adminUser = new User(username: 'admin', password: 'admin', enabled: true)
if (adminRole.validate()) {
adminRole.save(flush: true, failOnError: true)
}
if (adminUser.validate()) {
adminUser.save(flush: true, failOnError: true)
}
UserRole userRole = UserRole.create(adminUser, adminRole, true)
if (userRole.validate()) {
userRole.save(flush: true, failOnError: true)
}
}
}
def destroy = {
}
}
Here is my User.groovy (adding the nullable constraint did not solve the problem) :
User.groovy :
class User {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static constraints = {
username nullable: true, blank: false, unique: true
password nullable: true, blank: false
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
Here are my classe Role.groovy and UserRole.groovy :
Role.groovy :
class Role {
String authority
static mapping = {
cache true
}
static constraints = {
authority nullable: true, blank: false, unique: true
}
}
UserRole.groovy :
class UserRole implements Serializable {
User user
Role role
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id &&
other.role?.id == role?.id
}
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) {
find 'from UserRole where user.id=:userId and role.id=:roleId',
[userId: userId, roleId: roleId]
}
static UserRole create(User user, Role role, boolean flush = false) {
new UserRole(user: user, role: role).save(flush: flush, insert: true)
}
static boolean remove(User user, Role role, boolean flush = false) {
UserRole instance = UserRole.findByUserAndRole(user, role)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(User user) {
executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
}
static void removeAll(Role role) {
executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
}
static mapping = {
id composite: ['role', 'user']
version false
}
}
Here is my DataSource.groovy file with the database settings :
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
driverClassName = 'com.mysql.jdbc.Driver'
username = 'root'
password = 'root'
url = 'jdbc:mysql://localhost:3306/database?autoreconnect=true&useUnicode=true&characterEncoding=utf-8'
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
}
}
production {
dataSource {
dbCreate = 'create-drop'
driverClassName = 'com.mysql.jdbc.Driver'
username = 'root'
password = 'root'
url = 'jdbc:mysql://localhost:3306/database?autoreconnect=true&useUnicode=true&characterEncoding=utf-8'
}
}
}
I really don't have any idea about what occured.
I have added the nullable constrainst, trying to put the databe into 'create-drop' / 'update'.
Funny thing : When I drop the databse then create it again, the first server start is good, but crash after a restart.
I try to put println logs into my BootStrap.groovy, I can see them into development environment, but not into production server.
So I'm not sure if my BootStrap is updated creating war.
I create the war using :
grails prod war target/my-new-war-0.0.x.war
Thanks for reading,
Snite
I'm not really sure what's wrong with your code, however your giant block of code was making my head hurt so I had to post this.
Role role = Role.findByAuthority("ROLE_ADMIN") ?: new Role(authority: "ROLE_ADMIN").save(flush: true, failOnError: true)
if (UserRole.countByRole(role) == 0) {
User user = new User(username: 'admin', password: 'admin', enabled: true).save(flush: true, failOnError: true)
UserRole.create(user, role, true)
}
hmmm well its a null point exception:
ERROR context.GrailsContextLoader - Error initializing the application: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
Unsure if the pasted content matches up exactly to your own line numbers, something you could try for now is by going around and adding the question mark :
def existingAdminRole = Role.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole.user
}
change to:
def existingAdminRole = Role?.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole?.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole?.user
}
Also you could try findorsavewhere rather than an attempt to generate a new record:
https://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/conf/BootStrap.groovy
def n1=MyContinent.findOrSaveWhere(continentName: 'Asia')
def n2=MyContinent.findOrSaveWhere(continentName: 'Europe')
// Create countries and provde continent map value as above defs
def c1 = MyCountry.findOrSaveWhere(mycontinent: n2, countryName:'United Kingdom',ccode:'GB',language:'')
def c2 = MyCountry.findOrSaveWhere(mycontinent: n2, countryName:'France',ccode:'FR',language:'')
def c3 = MyCountry.findOrSaveWhere(mycontinent: n1, countryName:'China',ccode:'CN',language:'')
def c4 = MyCountry.findOrSaveWhere(mycontinent: n1, countryName:'India',ccode:'IN',language:'')
you will need to figure out what is going on in line 32 of UserRole which will be the start of your issue followed by BootStrap on line 16..
Thanks for all of your answer which help me to solve my issue.
It was stupid but in my rundeck script to deploy the war on the production server, it was an out of date version of the war which was used -_-
So doint it manually with the correct war version solve my problem.
Thanks because your advices help me to read adequat documentation on grails's framework and help me thinking looking here.
Cheers,
Snite
Whenever i add role to my existing User its not functioning.
There are no errors in logs, I also accessed my controller with try catch but no luck.
Here is my addRole closure:
def addRole = {
def role = Role.get(params.addRoleAutoComplete_id)
def user = User.get(params.id)
if (!role) {
flash.message = "Select role from list"
} else {
try{
UserRole.create( user, role)
}catch(Exception e){e.printStackTrace()}
}
redirect action:'edit', id:user.id
}
using Grails 2.3, grails spring security plugin and STS 3.2
Here is My UserRole.Groovy:
class UserRole implements Serializable {
User user
Role role
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id &&
other.role?.id == role?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static UserRole create(User user, Role role, boolean flush = false) {
new UserRole(user: user, role: role).save(flush: flush, insert: true)
}
static boolean remove(User user, Role role, boolean flush = false) {
UserRole instance = UserRole.findByUserAndRole(user, role)
if (!instance) {
return false
}
instance.delete(flush: true)
true
}
static mapping = {
id composite: ['role', 'user']
version false
}
}
I am developing a Web App with following :
Glassfish v3.1.2
Eclipse Juno SR2
JPA EclipseLink2.0
JSF 2.0
I have different set of pages for the normal user and for admin users. While trying to setup a page filter during login i am getting this error in my login bean : javax.faces.FacesException: #{loginBean.login}: java.lang.NullPointerException
My whole login code works without this part
if (uGDB.validateGroup(username, adminGroup)) {
return "home.jsf?faces-redirect=true&includeViewParams=true";
}
return "normalHome.jsf?faces-redirect=true&includeViewParams=true"
;
What I am trying to do here is to get the Group Id of the user who is logging in and check if it is admin or not. And accordingly I want to direct the user to the corresponding page. This is because i have different set of pages for admin users and normal users. I don't want to use the Glassfish Realms because the end user doesn't require it.
Can someone please help me identify where I am going wrong in this. (Please excuse me for stupid mistakes I am just starting with such an development). Thanks a lot in advance!
Below is the code for my loginBean
package beans;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import ejb.UserDaoBean;
import ejb.UserGroupDaoBean;
import model.User;
#ManagedBean(name = "loginBean")
#RequestScoped
public class LoginBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EJB
private UserDaoBean uDB;
private UserGroupDaoBean uGDB;
private User userId;
private int adminGroup = 1;
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String login() {
FacesContext context = FacesContext.getCurrentInstance();
if (uDB.validateUser(username)) {
userId = uDB.findUser(username);
context.getExternalContext().getSessionMap().put("userId", userId);
if (uGDB.validateGroup(username, adminGroup)) {
return "home.jsf?faces-redirect=true&includeViewParams=true";
}
return "normalHome.jsf?faces-redirect=true&includeViewParams=true";
} else {
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("Username doesn't exists! OR User is trying to login from someone else's account");
context.addMessage("", message);
return null;
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
return "logout.jsf?faces-redirect=true";
}
}
Here is the complete error stack from Glassfish log
WARNING: #{loginBean.login}: java.lang.NullPointerException
javax.faces.FacesException: #{loginBean.login}: java.lang.NullPointerException
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 31 more
Caused by: java.lang.NullPointerException
at beans.LoginBean.login(LoginBean.java:49)
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:601)
at com.sun.el.parser.AstValue.invoke(AstValue.java:254)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 32 more
Here is my controller class
package ejb;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.PersistenceContext;
import model.Group;
import model.User;
import model.UserGroup;
#Stateful
#LocalBean
public class UserGroupDaoBean {
#PersistenceContext(unitName = "myPU")
private EntityManager entityManager;
public UserGroupDaoBean() {
}
public UserGroup createNewUserGroup(int groupId, String username) {
UserGroup newUserGrp = new UserGroup();
User myUsr;
myUsr = entityManager.find(User.class, username);
newUserGrp.setUser(myUsr);
Group myGrp;
myGrp = entityManager.find(Group.class, groupId);
newUserGrp.setGroup(myGrp);
saveNewUsrGrp(newUserGrp);
return newUserGrp;
}
private void saveNewUsrGrp(UserGroup usrGrp) {
entityManager.persist(usrGrp);
entityManager.flush();
}
public boolean checkUsertoGroup(String username, int groupId) {
Group chkGrp;
chkGrp = entityManager.find(Group.class, groupId);
User chkUsr;
chkUsr = entityManager.find(User.class, username);
if (chkGrp != null) {
if (chkUsr != null) {
try {
entityManager.createNamedQuery("findGroupsbyUser")
.setParameter("username", chkUsr)
.setParameter("groupId", chkGrp).getSingleResult();
System.out.println("UserGroup already exists");
return false;
} catch (NoResultException e) {
return true;
}
}
System.out.println("User doesn't exist");
return false;
}
System.out.println("Group doesn't exist");
return false;
}
public void deleteUserGroup(UserGroup userGroup) {
userGroup = entityManager.merge(userGroup);
entityManager.remove(userGroup);
}
public UserGroup update(UserGroup myUserGroup) {
return entityManager.merge(myUserGroup);
}
#SuppressWarnings("unchecked")
public List<UserGroup> getAllUserGroups() {
try {
Query query = entityManager.createNamedQuery("findAllUserGroup");
List<UserGroup> result = (List<UserGroup>) query.getResultList();
return result;
} catch (NoResultException e) {
System.out.println("No Result found");
return null;
}
}
public boolean validateGroup(String username, int groupId) {
try {
UserGroup myGroupId = (UserGroup) entityManager
.createNamedQuery("findGroup")
.setParameter("username", username)
.setParameter("groupId", groupId).getSingleResult();
if (myGroupId != null) {
System.out.println("This user is admin!!!");
return true;
}
} catch (NoResultException e) {
return false;
}
System.out.println("This user is not admin");
return false;
}
}
Below is my entity UserGroup
package model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the UserGroup database table.
*
*/
#NamedQueries({
#NamedQuery(name = "findGroupsbyUser", query = "Select ug.group from UserGroup ug where ug.user=:username AND ug.group=:groupId"),
#NamedQuery(name = "findAllUserGroup", query="Select ug from UserGroup ug"),
#NamedQuery(name = "findAdminGroupId", query = "Select ug from UserGroup ug where ug.user=:username AND ug.group=:groupId"),
})
#Entity
#Table(name="usergroup")
public class UserGroup implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="RowId" )
private int rowId;
//bi-directional many-to-one association to Group
#ManyToOne
#JoinColumn(name="groupId")
private Group group;
//bi-directional many-to-one association to User
#ManyToOne
#JoinColumn(name="username")
private User user;
public UserGroup() {
}
public int getRowId() {
return this.rowId;
}
public void setRowId(int rowId) {
this.rowId = rowId;
}
public Group getGroup() {
return this.group;
}
public void setGroup(Group group) {
this.group = group;
}
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
}
Read the stack trace: the NPE is thrown at line 49 of LoginBean.java.
With high probability, uGBD is null, because the EJB annotation is missing. You need to use the #EJB annotation in front of each of the EJBs you are injecting:
#EJB
private UserDaoBean uDB;
#EJB
private UserGroupDaoBean uGDB;
...