Grails 上的 NoClassDefFoundError GANT 脚本

发布于 2025-01-05 06:20:37 字数 2127 浏览 1 评论 0原文

我正在尝试在 Grails 插件之前构建一些 GANT 脚本。 基本上,我想用新类扩展 DefaultGrailsTemplateGenerator 类,该类添加新方法以通过 Grails 模板方案自动生成服务类。

假设我用服务生成器命名了我的类,它扩展了 DefaultGrailsTemplateGenerator 并添加了generateService 方法。

import org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator;

class ServiceGenerator extends DefaultGrailsTemplateGenerator {
        void generateService(GrailsDomainClass domainClass, String destdir) {
        }
}

一切正常(例如调用了 GANT 脚本),除了在我实例化 ServiceGeneratorClass 的一行代码中,它返回错误:

Error Error executing script GenerateService: com.cygnus.grails.util.scaffolding.ServiceGenerator
java.lang.NoClassDefFoundError: com.cygnus.grails.util.scaffolding.ServiceGenerator
    at GenerateExt_groovy.class$(GenerateExt_groovy)
    at GenerateExt_groovy.$get$$class$com$cygnus$grails$util$scaffolding$ServiceGenerator(GenerateExt_groovy)
    at GenerateExt_groovy.generateForDomainClass(GenerateExt_groovy:81)

我尝试浏览此错误并尝试通过将语法从 : 更改

def templateGenerator = new ServiceGenerator(classLoader)

为 : 来调用

def myClass = classLoader.loadClass("org.my.ServiceGenerator")

该类我仍然发现了 java.lang.NoClassDefFoundError 。 我仍然不明白为什么会发生这种事。 有人可以帮助我吗?

我附上我的 GANT 脚本,它调用服务生成器

/**
 * Gant Script for generating Service Class based on Artifact
 * This Script was used for auto generate service class which is needed to handle basic transactional statements such as:
 * - AuditTrail for tables
 * - Logging before insert / update on tables
 */
includeTargets << grailsScript("_GrailsCreateArtifacts")
includeTargets << new File("${myPluginPluginDir}/scripts/GenerateExt.groovy")



target ('main': "Generates the CRUD service for a specified domain class") {
    depends(checkVersion, parseArguments, packageApp,classpath,configureProxy, 
            loadApp, configureApp, compile)

    promptForName(type: "Domain Class")
    generateViews = false
    generateForName = argsMap["params"][0]
    generateForOne()
}
setDefaultTarget(main)

任何帮助将不胜感激

谢谢

I'm trying to build some GANT script prior to my Grails Plugin.
Basicly, i want to extend DefaultGrailsTemplateGenerator Class with new Class which add new method to auto generate service class by Grails Templating scheme.

Suppose i've named my class with Service generator which extends DefaulGrailsTemplateGenerator and add generateService method.

import org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator;

class ServiceGenerator extends DefaultGrailsTemplateGenerator {
        void generateService(GrailsDomainClass domainClass, String destdir) {
        }
}

All things went normally (e.g GANT Script was called), except in a line of code which i instanstiated ServiceGeneratorClass, it returns error :

Error Error executing script GenerateService: com.cygnus.grails.util.scaffolding.ServiceGenerator
java.lang.NoClassDefFoundError: com.cygnus.grails.util.scaffolding.ServiceGenerator
    at GenerateExt_groovy.class$(GenerateExt_groovy)
    at GenerateExt_groovy.$get$class$com$cygnus$grails$util$scaffolding$ServiceGenerator(GenerateExt_groovy)
    at GenerateExt_groovy.generateForDomainClass(GenerateExt_groovy:81)

I've tried to browse on this error and try to call the class by change the syntax from :

def templateGenerator = new ServiceGenerator(classLoader)

to :

def myClass = classLoader.loadClass("org.my.ServiceGenerator")

Still i found the java.lang.NoClassDefFoundError .
I still couldn't figure out why this thing could happen.
Can someone help me ?

I attach my GANT Script which calls up Service Generator

/**
 * Gant Script for generating Service Class based on Artifact
 * This Script was used for auto generate service class which is needed to handle basic transactional statements such as:
 * - AuditTrail for tables
 * - Logging before insert / update on tables
 */
includeTargets << grailsScript("_GrailsCreateArtifacts")
includeTargets << new File("${myPluginPluginDir}/scripts/GenerateExt.groovy")



target ('main': "Generates the CRUD service for a specified domain class") {
    depends(checkVersion, parseArguments, packageApp,classpath,configureProxy, 
            loadApp, configureApp, compile)

    promptForName(type: "Domain Class")
    generateViews = false
    generateForName = argsMap["params"][0]
    generateForOne()
}
setDefaultTarget(main)

Any help would be appreciated

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趁年轻赶紧闹 2025-01-12 06:20:37

我终于完成了!

这是您想要执行的操作的示例: grails- flex-scaffold-script

这是我的实现:

*将 $userInterfacePluginDir 更改为您的插件名称

将此文件放入脚本中:

GenerateService.groovy

includeTargets << grailsScript("_GrailsInit")
includeTargets << grailsScript("_GrailsCreateArtifacts")
includeTargets << new File("$userInterfacePluginDir/scripts/_GrailsGenerateService.groovy")

target ('default': "Generates the service for a specified domain class") {
depends(checkVersion, parseArguments, packageApp)
promptForName(type: "Domain Class")
generateForName = argsMap["params"][0]
generateServiceForOne()
}

_GrailsGenerateService.groovy

import org.codehaus.groovy.grails.commons.GrailsDomainClass;
import org.codehaus.groovy.grails.scaffolding.*
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.FileSystemResource;
import grails.util.GrailsNameUtils

/**
 * Gant script that generates a service for a given domain class
 *
 * @author Martín Caballero
 *
 */

includeTargets << grailsScript("_GrailsBootstrap")

generateForName = null

target(generateServiceForOne: "Generates service for only one domain class.") {
    depends(loadApp)

    def name = generateForName
    name = name.indexOf('.') > 0 ? name : GrailsNameUtils.getClassNameRepresentation(name)
    def domainClass = grailsApp.getDomainClass(name)

    if (!domainClass) {
        grailsConsole.updateStatus "Domain class not found in grails-app/domain, trying hibernate mapped classes..."
        bootstrap()
        domainClass = grailsApp.getDomainClass(name)
    }

    if (domainClass) {
        generateServiceForDomainClass(domainClass)
        event("StatusFinal", ["Finished generation for domain class ${domainClass.fullName}"])
    }
    else {
        event("StatusFinal", ["No domain class found for name ${name}. Please try again and enter a valid domain class name"])
        exit(1)
    }
}

def generateServiceForDomainClass(domainClass) {
    UserInterfaceTemplateGenerator = classLoader.loadClass('plugin.ui.scaffold.UserInterfaceTemplateGenerator')
    def templateGenerator = UserInterfaceTemplateGenerator.newInstance(classLoader)
    templateGenerator.grailsApplication = grailsApp
    templateGenerator.pluginManager = pluginManager

    event("StatusUpdate", ["Generating service for domain class ${domainClass.fullName}"])
    templateGenerator.generateService(domainClass, basedir)
    event("GenerateServiceEnd", [domainClass.fullName])
}

UserInterfaceTemplateGenerator:(帮助程序类 - 扩展 DefaultGrailsTemplateGenerator)

package plugin.ui.scaffold

import org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator;
import grails.build.logging.GrailsConsole
import grails.util.BuildSettingsHolder
import groovy.text.SimpleTemplateEngine
import groovy.text.Template
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.codehaus.groovy.grails.plugins.GrailsPluginManager
import org.codehaus.groovy.grails.plugins.PluginManagerAware
import org.springframework.context.ResourceLoaderAware
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.ResourceLoader
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.util.Assert
import org.springframework.core.io.AbstractResource
import org.codehaus.groovy.grails.scaffolding.SimpleDomainClassPropertyComparator
import org.codehaus.groovy.grails.scaffolding.DomainClassPropertyComparator

class UserInterfaceTemplateGenerator extends DefaultGrailsTemplateGenerator {
    public UserInterfaceTemplateGenerator(ClassLoader classLoader){
        super(classLoader)
    }

    void generateService(GrailsDomainClass domainClass, String destdir) {
        Assert.hasText destdir, "Argument [destdir] not specified"

        if (domainClass) {
            def fullName = domainClass.fullName
            def pkg = ""
            def pos = fullName.lastIndexOf('.')
            if (pos != -1) {
                // Package name with trailing '.'
                pkg = fullName[0..pos]
            }

            def destFile = new File("${destdir}/grails-app/services/${pkg.replace('.' as char, '/' as char)}${domainClass.shortName}Service.groovy")
            if (canWrite(destFile)) {
                destFile.parentFile.mkdirs()

                destFile.withWriter { w ->
                    generateService(domainClass, w)
                }

                LOG.info("Controller generated at ${destFile}")
            }
        }
    }

    void generateService(GrailsDomainClass domainClass, Writer out) {
        def templateText = getTemplateText("Service.groovy")

        boolean hasHibernate =pluginManager?.hasGrailsPlugin('hibernate')
        def binding = [pluginManager: pluginManager,
                       packageName: domainClass.packageName,
                       domainClass: domainClass,
                       className: domainClass.shortName,
                       propertyName: getPropertyName(domainClass),
                       comparator: hasHibernate ? DomainClassPropertyComparator : SimpleDomainClassPropertyComparator]

        def t = engine.createTemplate(templateText)
        t.make(binding).writeTo(out)
    }

    protected canWrite(File testFile) {
        if (!overwrite && testFile.exists()) {
            try {
                def response = GrailsConsole.getInstance().userInput("File ${makeRelativeIfPossible(testFile.absolutePath, basedir)} already exists. Overwrite?",['y','n','a'] as String[])
                overwrite = overwrite || response == "a"
                return overwrite || response == "y"
            }
            catch (Exception e) {
                // failure to read from standard in means we're probably running from an automation tool like a build server
                return true
            }
        }
        return true
    }

    protected String getPropertyName(GrailsDomainClass domainClass) { "${domainClass.propertyName}${domainSuffix}" }

}

最后,这是我的模板:(将其放入 src/templates/scaffolding/)

Service.groovy

<%import org.codehaus.groovy.grails.commons.GrailsClassUtils;%>
<%=packageName ? "package ${packageName}\n\n" : ''%>
class ${className}Service {

    def getTable() {
        def query = {
            <%
                def searchFields = GrailsClassUtils.getStaticPropertyValue(domainClass.clazz, 'search' )
                if(searchFields)
                {
            %>
                    if (params.q) {
                        or{
                        <%searchFields.each { field ->%>
                            ilike("${field}", '%' + params.q + '%')
                        <%}%>
                        }
                    }
            <%  }   %>
            if (params.sort){
                order(params.sort,params.order)
            }
        }
        def criteria = ${className}.createCriteria()
        return criteria.list(query, max: params.max, offset: params.offset)
    }
}

然后,您使用命令“grailsgenerate-service yourdomainclass”

希望这有帮助!

这是答案的要点:

UserInterfaceTemplateGenerator = classLoader.loadClass('plugin.ui.scaffold.UserInterfaceTemplateGenerator')
def templateGenerator = UserInterfaceTemplateGenerator.newInstance(classLoader)

I finally done!

This is an example of what you want to do: grails-flex-scaffold-script

And this is my implementation:

*change $userInterfacePluginDir for your plugin name

Put this files in scripts:

GenerateService.groovy

includeTargets << grailsScript("_GrailsInit")
includeTargets << grailsScript("_GrailsCreateArtifacts")
includeTargets << new File("$userInterfacePluginDir/scripts/_GrailsGenerateService.groovy")

target ('default': "Generates the service for a specified domain class") {
depends(checkVersion, parseArguments, packageApp)
promptForName(type: "Domain Class")
generateForName = argsMap["params"][0]
generateServiceForOne()
}

_GrailsGenerateService.groovy

import org.codehaus.groovy.grails.commons.GrailsDomainClass;
import org.codehaus.groovy.grails.scaffolding.*
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.FileSystemResource;
import grails.util.GrailsNameUtils

/**
 * Gant script that generates a service for a given domain class
 *
 * @author Martín Caballero
 *
 */

includeTargets << grailsScript("_GrailsBootstrap")

generateForName = null

target(generateServiceForOne: "Generates service for only one domain class.") {
    depends(loadApp)

    def name = generateForName
    name = name.indexOf('.') > 0 ? name : GrailsNameUtils.getClassNameRepresentation(name)
    def domainClass = grailsApp.getDomainClass(name)

    if (!domainClass) {
        grailsConsole.updateStatus "Domain class not found in grails-app/domain, trying hibernate mapped classes..."
        bootstrap()
        domainClass = grailsApp.getDomainClass(name)
    }

    if (domainClass) {
        generateServiceForDomainClass(domainClass)
        event("StatusFinal", ["Finished generation for domain class ${domainClass.fullName}"])
    }
    else {
        event("StatusFinal", ["No domain class found for name ${name}. Please try again and enter a valid domain class name"])
        exit(1)
    }
}

def generateServiceForDomainClass(domainClass) {
    UserInterfaceTemplateGenerator = classLoader.loadClass('plugin.ui.scaffold.UserInterfaceTemplateGenerator')
    def templateGenerator = UserInterfaceTemplateGenerator.newInstance(classLoader)
    templateGenerator.grailsApplication = grailsApp
    templateGenerator.pluginManager = pluginManager

    event("StatusUpdate", ["Generating service for domain class ${domainClass.fullName}"])
    templateGenerator.generateService(domainClass, basedir)
    event("GenerateServiceEnd", [domainClass.fullName])
}

UserInterfaceTemplateGenerator: (helper class - extends DefaultGrailsTemplateGenerator)

package plugin.ui.scaffold

import org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator;
import grails.build.logging.GrailsConsole
import grails.util.BuildSettingsHolder
import groovy.text.SimpleTemplateEngine
import groovy.text.Template
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.codehaus.groovy.grails.plugins.GrailsPluginManager
import org.codehaus.groovy.grails.plugins.PluginManagerAware
import org.springframework.context.ResourceLoaderAware
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.ResourceLoader
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
import org.springframework.util.Assert
import org.springframework.core.io.AbstractResource
import org.codehaus.groovy.grails.scaffolding.SimpleDomainClassPropertyComparator
import org.codehaus.groovy.grails.scaffolding.DomainClassPropertyComparator

class UserInterfaceTemplateGenerator extends DefaultGrailsTemplateGenerator {
    public UserInterfaceTemplateGenerator(ClassLoader classLoader){
        super(classLoader)
    }

    void generateService(GrailsDomainClass domainClass, String destdir) {
        Assert.hasText destdir, "Argument [destdir] not specified"

        if (domainClass) {
            def fullName = domainClass.fullName
            def pkg = ""
            def pos = fullName.lastIndexOf('.')
            if (pos != -1) {
                // Package name with trailing '.'
                pkg = fullName[0..pos]
            }

            def destFile = new File("${destdir}/grails-app/services/${pkg.replace('.' as char, '/' as char)}${domainClass.shortName}Service.groovy")
            if (canWrite(destFile)) {
                destFile.parentFile.mkdirs()

                destFile.withWriter { w ->
                    generateService(domainClass, w)
                }

                LOG.info("Controller generated at ${destFile}")
            }
        }
    }

    void generateService(GrailsDomainClass domainClass, Writer out) {
        def templateText = getTemplateText("Service.groovy")

        boolean hasHibernate =pluginManager?.hasGrailsPlugin('hibernate')
        def binding = [pluginManager: pluginManager,
                       packageName: domainClass.packageName,
                       domainClass: domainClass,
                       className: domainClass.shortName,
                       propertyName: getPropertyName(domainClass),
                       comparator: hasHibernate ? DomainClassPropertyComparator : SimpleDomainClassPropertyComparator]

        def t = engine.createTemplate(templateText)
        t.make(binding).writeTo(out)
    }

    protected canWrite(File testFile) {
        if (!overwrite && testFile.exists()) {
            try {
                def response = GrailsConsole.getInstance().userInput("File ${makeRelativeIfPossible(testFile.absolutePath, basedir)} already exists. Overwrite?",['y','n','a'] as String[])
                overwrite = overwrite || response == "a"
                return overwrite || response == "y"
            }
            catch (Exception e) {
                // failure to read from standard in means we're probably running from an automation tool like a build server
                return true
            }
        }
        return true
    }

    protected String getPropertyName(GrailsDomainClass domainClass) { "${domainClass.propertyName}${domainSuffix}" }

}

And, finally, this is my template: (Put it in src/templates/scaffolding/)

Service.groovy

<%import org.codehaus.groovy.grails.commons.GrailsClassUtils;%>
<%=packageName ? "package ${packageName}\n\n" : ''%>
class ${className}Service {

    def getTable() {
        def query = {
            <%
                def searchFields = GrailsClassUtils.getStaticPropertyValue(domainClass.clazz, 'search' )
                if(searchFields)
                {
            %>
                    if (params.q) {
                        or{
                        <%searchFields.each { field ->%>
                            ilike("${field}", '%' + params.q + '%')
                        <%}%>
                        }
                    }
            <%  }   %>
            if (params.sort){
                order(params.sort,params.order)
            }
        }
        def criteria = ${className}.createCriteria()
        return criteria.list(query, max: params.max, offset: params.offset)
    }
}

Then, you use the command as "grails generate-service yourdomainclass"

Hope that helps!

This is the essential of the answer:

UserInterfaceTemplateGenerator = classLoader.loadClass('plugin.ui.scaffold.UserInterfaceTemplateGenerator')
def templateGenerator = UserInterfaceTemplateGenerator.newInstance(classLoader)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文