【问题标题】:How to execute a Groovy Script from my Grails app?如何从我的 Grails 应用程序执行 Groovy 脚本?
【发布时间】:2009-12-18 10:28:02
【问题描述】:

嗯,这似乎是一项简单的任务,但我没有设法让它运行。

当从提示符调用时,我有一个在 Windows Vista 下运行良好的 groovy 脚本:

> cd MY_GAILS_PROJECT_DIR
> groovy cp src/groovy scripts/myscript.groovy

现在,我想通过我的维护服务类(从控制器调用)执行这个脚本(并将一些输入参数传递给它),如下所示,

class MaintenanceService {
  def executeMyScript() {
    "groovy cp src/groovy scripts/myscript.groovy".execute()
  }
}

它根本不起作用!我什至无法让 execute() 方法识别任何引发异常的命令(如 "cd .".execute()):

Error 500: java.io.IOException: Cannot run program "cd": CreateProcess error=2, The system cannot find the file specified

1- 如何从我的 grails 应用程序中执行一个 groovy 脚本?

2- 这里的最佳做法是什么?例如,我应该使用 QuartzPlugin 然后使用 triggerNow 方法来执行脚本吗?我应该使用 Gant 任务吗?如果是,怎么做?

谢谢。

【问题讨论】:

  • 是否有一个特定的原因,它必须是一个时髦的“脚本”,而不是一个你可以调用的类,正如 bastianneu 建议的那样?
  • 是的。我也需要在没有 Grails 环境的情况下执行这个 groovy 脚本。

标签: grails scripting groovy


【解决方案1】:

如果您不介意您的脚本异步运行(在与服务方法不同的进程中),假设 groovy 在您的 PATH 变量上,以下应该可以工作:

def cmd = ['groovy.bat', 'cp', 'src/groovy scripts/myscript.groovy']
cmd.execute()

如果您想在应用程序控制台中查看进程的输出,您应该尝试类似这样的操作

// Helper class for redirecting output of process
class StreamPrinter extends Thread {
    InputStream inputStream

    StreamPrinter(InputStream is) {
        this.inputStream = is
    }

    public void run() {
        new BufferedReader(new InputStreamReader(inputStream)).withReader {reader ->
            String line
            while ((line = reader.readLine()) != null) {
                println(line)
            }
        }
    }
}

// Execute the script
def cmd = ['groovy', 'cp', 'src/groovy scripts/myscript.groovy']
Process executingProcess = cmd.execute()

// Read process output and print on console
def errorStreamPrinter = new StreamPrinter(executingProcess.err)
def outputStreamPrinter = new StreamPrinter(executingProcess.in)
[errorStreamPrinter, outputStreamPrinter]*.start()

更新: 针对您在下面的评论,请尝试以下操作(假设您使用的是 Windows):

1:创建文件 C:\tmp\foo.groovy。这个文件的内容应该很简单:

println 'it works!'

2:在 groovy 控制台中,运行以下命令:

cmd = ['groovy.bat', 'C:\\tmp\\foo.groovy']
cmd.execute().text

3:您应该会在 Groovy 控制台中看到脚本的结果(文本“它可以工作!”)

如果您无法让这个简单的示例正常运行,则说明您的环境有问题,例如“groovy.bat”不在您的 PATH 中。如果您可以使这个示例正常运行,那么您应该能够从它向前推进以实现您的目标。

【讨论】:

  • 嗨。谢谢你的回答,但它会抛出完全相同的结果。例如 def cmd = ['cd', 'd:/temp']; cmd.execute() => 系统找不到指定的文件。你有什么想法吗?
  • 非常感谢!从您的示例返回,我设法使其与路径和“groovy.bat”的反斜杠一起使用,而不是 groovy。现在它起作用了!谢谢。一个问题:你知道为什么“groovy.bat”有效,但“groovy”无效(而在命令提示符下两者都有效)?
  • 我猜这是因为在命令提示符中“.bat”被识别为可执行文件类型,但在操作系统级别,您需要提供完整的文件名,除非它是“.exe”。顺便说一句,在 Linux 上,您可以使用“grails”或“grails.sh”
【解决方案2】:

从 grails 1.3.6 开始,内置了 run-script 命令让您运行

grails run-script myScript.groovy

对于早期版本的 grails,check out my updated blog post 来自 Carlos 上面发布的内容。

【讨论】:

    【解决方案3】:

    最简单的方法:

    生成一个 Groovy 类并将其放置在 Grails 项目的 /src/groovy 文件夹中。 在您的域类中导入该类并使用您定义的函数。

    我的 2 美分...

    【讨论】:

      【解决方案4】:
      【解决方案5】:

      另一个可以使用 GroovyScriptEngine 的决定,例如:

      文件 MyScript.groovy:

      static String showMessage() {
          println("Message from showMessage")
      }
      

      文件 BootStrap.groovy:

      class BootStrap {
      
          def init = { servletContext ->
              new GroovyScriptEngine("scripts")
                      .loadScriptByName("MyScript.groovy")
                      .showMessage()
          }
          def destroy = {
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-14
        • 2019-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多