1

我在生产服务器上有一个非常奇怪的行为。

当我第一次启动我的服务器时,没有问题,但是当我想停止并重新启动它时,我收到以下错误:

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

这是我的 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 = {
    }
}

这是我的 User.groovy (添加可为空的约束并没有解决问题):

用户.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)
    }
}

这是我的类 Role.groovy 和 UserRole.groovy :

角色.groovy:

class Role {

    String authority

    static mapping = {
        cache true
    }

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

用户角色.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
    }
}

这是我的带有数据库设置的 DataSource.groovy 文件:

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'
        }
    }
}

我真的不知道发生了什么。我添加了可为空的约束,试图将数据放入“create-drop”/“update”中。

有趣的是:当我删除数据库然后再次创建它时,第一个服务器启动很好,但重新启动后崩溃。

我尝试将 println 日志放入我的 BootStrap.groovy,我可以在开发环境中看到它们,但不能在生产服务器中看到它们。

所以我不确定我的 BootStrap 是否在创建战争时更新。

我使用以下方法创建战争:

grails prod war target/my-new-war-0.0.x.war

谢谢阅读,

斯奈特

4

3 回答 3

0

我不太确定你的代码有什么问题,但是你的巨大代码块让我头疼,所以我不得不发布这个。

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)
}
于 2013-10-31T17:08:25.210 回答
0

嗯,它是一个空点异常:

错误 context.GrailsContextLoader - 初始化应用程序 时出错:在 BootStrap$_closure1.doCall(BootStrap.groovy:16) 的 com.aftmevent.security.UserRole.create(UserRole.groovy:32) 处出现null java.lang.NullPointerException

不确定粘贴的内容是否与您自己的行号完全匹配,您现在可以尝试的方法是四处走动并添加问号:

def existingAdminRole = Role.findByAuthority('ROLE_ADMIN')
        def existingUserRole = null
        def existingAdminUser = null
        if (existingAdminRole) {
            existingUserRole = UserRole.findByRole(existingAdminRole)
        }
        if (existingUserRole) {
            existingAdminUser = existingUserRole.user
        }

改成:

def existingAdminRole = Role?.findByAuthority('ROLE_ADMIN')
        def existingUserRole = null
        def existingAdminUser = null
        if (existingAdminRole) {
            existingUserRole = UserRole?.findByRole(existingAdminRole)
        }
        if (existingUserRole) {
            existingAdminUser = existingUserRole?.user
        }

您也可以尝试 findorsavewhere 而不是尝试生成新记录: 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:'')

您需要弄清楚 UserRole 的第 32 行发生了什么,这将是您的问题的开始,然后是第 16 行的 BootStrap。

于 2013-10-31T17:13:12.703 回答
0

感谢您的所有回答,这有助于我解决我的问题。

这很愚蠢,但在我在生产服务器上部署战争的 rundeck 脚本中,它是使用的战争的过时版本 - _ -

所以用正确的战争版本手动解决我的问题。

谢谢,因为您的建议帮助我阅读有关 grails 框架的足够文档,并帮助我思考看这里。

干杯,

斯奈特

于 2013-11-01T20:06:04.173 回答