0

我在一个体面的 Java 项目上工作,该项目使用 Perl 脚本编写一些胶水代码。我试图弄清楚如何用 Groovy 脚本替换这些脚本,以便我们可以方便地编写脚本,但可以更好地访问多年来构建的所有 Java 代码。这是我们的项目结构的示例。

.
|____core
| |____classes
| | |____com
| |   |____project
| |     |____core
| |       |____CoreClass.class
| |____src
|   |____com
|     |____project
|       |____core
|         |____CoreClass.java
|____scripts
| |____someScript.groovy
|____util
  |____classes
  | |____com
  |   |____project
  |     |____util
  |       |____UtilClass.class
  |____src
    |____com
      |____project
        |____util
          |____UtilClass.java

(注意:util并且core只是项目中大约十几个类似文件夹中的两个)

我想从命令行运行someScript.groovy,它需要能够实例化UtilClassCoreClass. 我已经阅读了各种使用 Groovy 脚本设置类路径的方法,但我发现没有一种方法是合适的。

这里的重点是找到一种使用 Groovy 的方法,它比我们当前使用 Perl 的系统更容易使用。为了做到这一点,我认为我需要满足三个标准。

  • 不污染系统或环境

我想让项目尽可能地独立。开发人员应该能够从源代码控制中检查项目,运行someScript.groovy并让它知道在哪里可以找到项目中的其他类。我不想要求开发人员将 CLASSPATH 环境变量设置为指向所有项目类目录。

  • 没有长命令行参数

脚本应该很容易从命令行运行。如果-cp需要该标志,则开发人员必须键入小说才能指定我们项目中的所有各种类目录。

  • 没有样板someScript.groovy

我见过一些解决方案,包括获取类加载器的实例并指定.java文件的路径.class。这将使脚本编写起来过于困难和乏味。

这些标准不是绝对的。如果我不得不对其中一个稍作让步,该解决方案可能仍然有效。我们在这里使用 Eclipse,因此涉及通过 Eclipse 进行某种类型的项目配置的解决方案可能是合适的。如果需要样板代码,也许有一个 Groovy 源文件,该文件由 Eclipse 自动编译为包含必要样板代码的版本。

通过groovy someScript.groovy或调用脚本someScript.groovy可能是可以接受的。

4

5 回答 5

0

这是另一种选择:

  1. 下载最新的 groovy 版本
  2. bin/, conf/ and lib/目录从 groovy 复制到项目根目录
  3. 编辑conf/groovy-starter.conf

添加以下条目

load !{groovy.home}/core/classes
load !{groovy.home}/util/classes
....and all your other directories

要运行someScript.groovy,您将从项目根目录运行以下命令:

bin/groovy scripts/someScript.groovy

这是完全独立的,开发人员不需要安装 groovy。所需的一切都已JAVA_HOME设置。每当您想升级 groovy 时,只需下载最新版本并替换bin/lib/目录即可。

如果lib/您的项目中已经是一个目录,您可以将 groovy 库重命名为groovy-lib/并调整其中的条目conf/groovy-starter.conf(您可能还需要调整bin/startGroovy脚本中的一两行)。

bin/groovy scripts/someScript.grooy如果你想进一步简化事情,你总是可以在你的项目根目录中创建一个包装脚本来调用。

于 2012-06-30T04:27:23.187 回答
0

您可以使用以下方法将内容动态添加到 Groovy 脚本的根类加载器:

this.class.classLoader.rootLoader.addURL(new URL('file:///path/to/jar'))

所以剩下的就是让脚本确定脚本本身的位置:

scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent

然后找到那棵树上的所有罐子。

于 2012-06-30T04:37:27.470 回答
0

一种选择是编写一个接受要运行的 Groovy 脚本名称的 shell 脚本。然后,shell 脚本调用该groovy命令,传递 Groovy 脚本和正确的(相对)类路径。

由于 Groovy Eclipse 插件可以运行 Groovy 脚本,另一个选项可能是修改运行配置并在那里设置正确的类路径。

于 2012-06-29T01:59:52.793 回答
0

为什么不在“lib/”目录中包含 groovy-all.jar 和其他依赖项。然后编写将类路径设置为“lib/*”的包装器 .bat 和 .sh 脚本。有一个主类“groovy.lang.GroovyShell”,您可以将脚本作为参数传递给它运行。

一些脚本.sh

#!/bin/bash
java -cp 'lib/*' groovy.lang.GroovyShell somescript.groovy
于 2012-06-29T02:00:14.163 回答
0

有时我使用派生加载器,当我只能接受来自正常/禁止包的类时(即没有来自 io 包等的文件)

package script;

import org.codehaus.groovy.control.CompilationFailedException;

import groovy.lang.GroovyClassLoader;

public class MyGroovyClassLoader extends GroovyClassLoader {

@Override
public Class loadClass(String name, boolean lookupScriptFiles, boolean preferClassOverScript) throws ClassNotFoundException,
        CompilationFailedException {
    if( ... ! requiredPackaIsOk ... ) 
        throw Exception("class cannot be loaded"); 
    return super.loadClass(name, lookupScriptFiles, preferClassOverScript);
}

@Override
public Class loadClass(String name, boolean lookupScriptFiles, boolean preferClassOverScript, boolean resolve)
        throws ClassNotFoundException, CompilationFailedException {
    if( ... ! requiredPackaIsOk ... ) 
        throw Exception("class cannot be loaded"); 
        return super.loadClass(name, lookupScriptFiles, preferClassOverScript, resolve);
}

@Override
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
    if( ... ! requiredPackaIsOk ... ) 
        throw Exception("class cannot be loaded"); 
        return super.loadClass(name, resolve);
}

}

于 2015-08-02T21:26:24.057 回答