NoClassDefFoundError GANT-скрипт на Grails - PullRequest
1 голос
/ 14 февраля 2012

Я пытаюсь создать сценарий GANT до моего Grails Plugin.По сути, я хочу расширить класс DefaultGrailsTemplateGenerator новым классом, который добавляет новый метод для автоматического создания класса обслуживания по схеме шаблонов Grails.

Предположим, я назвал свой класс с помощью генератора служб, который расширяет DefaulGrailsTemplateGenerator и добавляет метод 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, который вызывает 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)

Любая помощь будет признательна

Спасибо

1 Ответ

1 голос
/ 08 мая 2012

Я наконец сделал!

Это пример того, что вы хотите сделать: 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)
    }
}

Затем вы используете команду как "grails generate-service yourdomainclass"

Надеюсь, это поможет!

Это суть ответа:

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