2012-02-14 59 views
1

我想在我的Grails插件之前創建一些GANT腳本。 基本上,我想擴展DefaultGrailsTemplateGenerator類與新的類添加新的方法來自動生成服務類通過Grails模板方案。NoClassDefFoundError Grails上的GANT腳本

假設我已經用Service generator生成了我的類,它擴展了DefaulGrailsTemplateGenerator並添加了generateService方法。

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

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

所有的事情進展正常(如GANT腳本叫),除了在一條線上的,我instanstiated 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) 

任何幫助,將不勝感激

感謝

+0

。我認爲這是要走的路,但我還沒有時間去嘗試它:[在Grails Gant腳本中使用您的應用程序類](http://groovytard.blogspot.com.ar/2010/10/using- your-application-classes-inside.html) – mpccolorado 2012-05-07 17:26:18

回答

1

我終於完成了!

這是你想要做什麼的例子: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 /模板/腳手架/)

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) 
+0

我會盡快嘗試,並會通知您。感謝您的回覆和努力:-) – 2012-06-26 13:59:14

+0

它正在爲我工​​作。我爲了重構一些東西而改變了這一點,但代碼很好。您可以按照自己喜歡的方式更改服務模板。我的腳本現在接受用於在指定插件中生成服務的插件參數(針對插件中的模塊化應用程序)。 – mpccolorado 2012-07-05 17:01:23

+0

我還在Jira中提交了一個修補程序:[generate-service](http://jira.grails.org/browse/GRAILS-9131) – mpccolorado 2012-07-05 17:05:19

相關問題