grails dns bootstrapping

Crear una instancia de una clase de dominio dentro de una secuencia de comandos de Grails



dns bootstrapping (1)

No tiene que hacer todo el esfuerzo de la placa de la caldera para mostrar el entorno mientras ejecuta su secuencia de comandos. run-script hace por ti. Cuando se usa grails run-script siguientes objetivos se ejecutan de manera predeterminada: checkVersion, configureProxy, bootstrap . Y, finalmente, se run-script el script run-script .

run-script ejecuta su script personalizado en GroovyShell al proporcionar ApplicationContext y grailsApplication como enlaces al shell. Entonces, lo que terminaría con su script se muestra a continuación como si estuviera escrito en Groovy console / shell:

//scripts/player/PlayerScript.groovy def handleHeaderLine(line) { def retval = [] line.each { if(!it.equals("Game Name") && !it.equals("Total # of Copies")) { println("Creating Player: " + it) def player = new Player(name: it) player.save(flush: true) retval << it } else { retval << null } } return retval } def handleGameLine(header, line) { println("Creating Game: " + line[0]) for(int i = 1; i < line.length - 1; i++) { if(!header[i].equals("Total # of Copies")) { def count = line[i] == "" ? 0 : Integer.parseInt(line[i]); for(int j = 0; j < count; j++) { println "Creating copy of " + line[0] + " owned by " + header[i] } } } } def tsv = new File("...") def header = null tsv.eachLine { def line = it.split("/t") if(header == null) { header = handleHeaderLine(line) println header } else { handleGameLine(header, line) } }

Y luego use run-script siguiente manera:

grails run-script scripts/player/PlayerScript.groovy

que por defecto ejecutaría la secuencia de comandos en el entorno de desarrollo. Si quieres para otros entornos, utiliza como

grails test run-script scripts/player/PlayerScript.groovy

PERO
Debido a un error importante en la última versión de Grails, no podrá ejecutar el script de la manera mencionada anteriormente porque run-script siempre depende del destino de bootstrap y siempre intentará llevar a tomcat mientras ejecuta el script como el alcance del complemento en la build lo que daría como resultado Error al cargar el administrador de complementos: TomcatGrailsPlugin . La solución alternativa también se menciona en el defecto, pero aquí hay una implementación más completa. Cambie en BuildConfig.groovy como:

plugins { if ( !System.getProperty("noTomcat") ) { build ":tomcat:7.0.52.1" } .... }

y luego ejecute el comando run-script como:

grails -DnoTomcat=true run-script scripts/player/PlayerScript.groovy

En una nota lateral, la razón por la que su script no se estaba ejecutando es que la clase Player no se cargará en este momento mientras se ejecuta el script, para su uso. Tiene que ser cargado manualmente usando classLoader y luego crear una instancia fuera de él. Algo como:

includeTargets << grailsScript("_GrailsInit") includeTargets << grailsScript("_GrailsBootstrap") target(playerScript: "The description of the script goes here!") { depends configureProxy, packageApp, classpath, loadApp, configureApp def playerClass = classLoader.loadClass("gaming.Player") //Skeptical about how a domain class would behave //But a normal POGO should be good being used this way def player = playerClass.newInstance([[name: "Bob"]] as Object[]) player.save(flush: true) println player } setDefaultTarget(playerScript)

Intento crear una instancia de una clase de dominio dentro de un script de Grails 2.3.6:

def player = new Player(name:"Bob") player.save()

Pero sigo recibiendo una excepción

java.lang.NoClassDefFoundError: gaming/Player

He intentado todos los trucos de arranque diferentes que he logrado encontrar en Internet, pero en realidad no cambian el resultado:

Intenté importar:

import gaming.Player

Intenté cargar el script de arranque:

includeTargets << grailsScript("_GrailsBootstrap")

Lo intenté dependiendo de cada tarea que logré encontrar:

depends(configureProxy, packageApp, classpath, loadApp, configureApp, compile, bootstrap)

Incluso he intentado cargar la clase en tiempo de ejecución:

ApplicationHolder.application.getClassForName("gaming.Player")

Curiosamente, esta última línea no descarta lo que sugiere que los griales pueden encontrar mi clase, pero elige ignorar el hallazgo cuando realmente voy a usarlo.

Editar. Según lo solicitado, aquí está la versión actual del script

import gaming.Player import org.codehaus.groovy.grails.commons.ApplicationHolder includeTargets << grailsScript("_GrailsInit") includeTargets << grailsScript("_GrailsBootstrap") includeTargets << grailsScript("_GrailsClasspath") def handleHeaderLine(line) { def retval = [] line.each { if(!it.equals("Game Name") && !it.equals("Total # of Copies")) { println("Creating Player: " + it) def player = new Player(name:it) player.save retval << it } else { retval << null } } return retval; } def handleGameLine(header, line) { println("Creating Game: " + line[0]) for(int i = 1; i < line.length - 1; i++) { if(!header[i].equals("Total # of Copies")) { def count = line[i] == "" ? 0 : Integer.parseInt(line[i]); for(int j = 0; j < count; j++) { println "Creating copy of " + line[0] + " owned by " + header[i] } } } } target(loadAssets: "The description of the script goes here!") { depends(configureProxy, packageApp, classpath, loadApp, configureApp, compile, bootstrap) ApplicationHolder.application.getClassForName("gaming.Player") def tsv = new File("...") def header = null; tsv.eachLine { def line = it.split("/t") if(header == null) { header = handleHeaderLine(line) println header } else { handleGameLine(header, line) } } } setDefaultTarget(loadAssets)