Grails 和 Maven:一种不方便的结合

工程 | Dave Syer | 2007 年 7 月 14 日 | ...

介绍

Grails 似乎发展势头越来越好,并且看起来确实“有潜力”,正如他们所说。我很有兴趣将这些潜力扩展到 Web 应用程序领域之外。如果您了解我在Spring Batch 上的工作,您大概可以猜出这会把我带到哪里。但在这篇文章中,我想分享一些我在 Grails 应用程序的基本、低级部署和构建方面的一些经验。

我对 Maven 2 既爱又恨,我正在学习喜欢 Grails,但遗憾的是这两者配合得并不特别好。如果能有更紧密的集成就好了。Maven 并不总是我们想要的样子,但有些东西确实让它物有所值。它是一种某种程度的标准(爱它或恨它),所以当我从某个地方下载一个项目时,我已经知道如何构建它,它的依赖是什么,以及文档在哪里。Grails 也有一些相同的特性,事实上,它自己基于 Groovy 脚本的 Ant 就包含了一个相当复杂的构建工具。也许 there is a middle way, where we can have the best of both worlds?

我也意识到这个领域的一些其他活动,我希望我们能围绕着什么东西团结起来(也许由这个论坛和 Grails JIRA 中的讨论驱动)。例如,请看 Frederick Verbist 的 博客 和 Arnaud Heritier 的 maven 集成项目(目前才刚刚起步)。Grails 团队对 Maven 一向不以为然(例如,请看 这里),但我与 Graeme Rocher 聊过,他愿意接受建议,所以我希望我们能在此取得一些进展。

为 Grails 原型开发使用 Maven 进行依赖管理

本着朝着 Maven 集成迈出简单步骤的精神,我附加了一组 poms,它们(大致)描述了我所了解的 Grails 0.5.6 的依赖结构。如果您在使用 Spring 版本时遇到问题,可以忽略或更改 Spring 版本号 - Grails 0.5.6 使用 Spring 2.0,但我正在进行的一个项目需要 2.1。Graham 说 Grails 可能无法与更高版本的 Spring 正常工作,所以您的使用情况可能会有所不同。这就是 Maven 的优点,对吧?您可以显式地、传递地看到项目依赖,并且可以以您控制的方式调整它们,以适应您自己的需求和风险承受能力。

对 Maven 用户的一点说明:依赖插件比以前工作得好多了,您可以使用“mvn dependency:tree”来打印依赖树。这仅适用于全新的插件,所以请确保您的插件存储库中包含 apache-snapshots 存储库


<pluginRepositories>
	<pluginRepository>
		<id>apache-snapshots</id>
		<url>http://people.apache.org/maven-snapshot-repository</url>
	</pluginRepository>
</pluginRepositories>

比必须构建整个站点并查看依赖报告要方便得多,我以前经常这样做。

一个 POM,一个 POM,我的王国换一个 POM...

这是第一个面对 Grails 项目并试图理解它是如何组合在一起的陷入疯狂的 Maven 用户发出的呼喊。希望我们在这里将展示如何安抚这位可怜的发狂的个人。为此,我们将介绍一些简单的步骤来为现有的 Grails 项目创建一个 Maven 项目。

在附带的沙箱存档中,有三个 poms,每个都在自己的项目中

  • base = 与 Web 应用程序无关的依赖项的基础 POM。我已经相当宽松了(例如,包括 Spring Weblfow)。目标是仅凭这些依赖项就可以启动 grails console。
  • web = 创建 Web 应用程序 WAR 文件所需的其他依赖项。这在一定程度上可能取决于平台,但此处包含的依赖项可以在 Servlet 2.4 容器(如 Jetty 5.1,Grails 传统上使用它)中工作。
  • launch = Jetty 和 JSP 依赖项,仅用于在独立或开发环境中启动 Web 应用程序

要安装 Grails poms,您应该不需要手动将任何工件添加到本地存储库。还有几个“奇怪的”(我找不到任何标准的公共存储库),我已将其包含在“spring-ext”存储库中(在 pom 中定义)。如果连接到互联网,它应该可以直接使用。

运行示例的先决条件

您需要 Maven (2.0.*) 和 Grails (0.5.6) 来运行示例应用程序。我使用的是 Maven 2.0.7。“grails”和“mvn”启动脚本需要位于您的路径中,并且您需要定义 GRAIL_HOME 环境变量才能运行 Grails(标准安装过程)。

测试项目

还有一个测试项目,它使用上述 poms 来管理 Web 应用程序。我决定坚持使用 Grails 的目录布局。Graham 告诉我,web-app/WEB-INF 中几乎所有的“可变”内容都将在 Grails 1.0 中被移除,所以我认为使用 Grails 制定的结构是最好的前进方向(最不容易出错,Grails 开发人员容易理解)。

从 Grails 命令行启动

$ cd test
$ mvn package
$ grails run-app

要为测试项目添加其他依赖项,只需将它们添加到 pom 中并重复此过程(或者在 Eclipse 中什么都不做,请参见下文)。Maven 真是太棒了,不是吗?

请注意,Grails 依赖项在项目 pom 中具有 scope=provided。这应该意味着它们在 Maven 和 Eclipse 的类路径中,但不会包含在任何 Maven 包(如果已实现)中。

仅限 Eclipse 用户

测试项目还包括 Eclipse 项目工件 - 为了获得最佳效果,请使用 Maven Eclipse 扩展(http://m2eclipse.codehaus.org/update-dev/)。使用此 Eclipse 扩展,您将能够处理工作区中其他作为 Maven 工件的项目,如果它们是 Grails 项目的依赖项,它们将被自动添加到类路径中,并在您进行更改时动态更新。

如果您不使用 Maven Eclipse 扩展,那么您可以使用 Eclipse Maven 插件(也称为 maven-eclipse-plugin)。使用“mvn eclipse:eclipse”来更新 .classpath 并刷新,然后您应该就可以了,但无法自动与 Eclipse 中其他项目的更改同步。

您需要首先从命令行执行“grails package”(只需一次)

$ cd test
$ grails package

这将为您生成一个 web.xml,并从 grails-app/conf 复制和过滤一些属性文件。据称,长期来看,web.xml 将是 web-app/WEB-INF 中唯一生成的文件(因此,每个人的源代码管理系统只有一个 svn:ignore)。

在 Eclipse 中,您可以导入测试项目。然后您可以选择 Run... 并从 Java Applications 中选择“test”启动器。您可以调试,并且可以动态更改代码,包括 Grails 应用程序本身以及依赖项目中的代码。

下一步

我附加的工具还有一些缺失/不方便的地方。它们还远未完成。如果有人尝试使用它们,无疑会提出如何做得更好的建议。请在此处或 Grails JIRA 上回复

以下是一些已知的问题或令人恼火的地方

Grails 打包中的重复 Jar

核心 Grails 的一些依赖项可能与 POM 中的依赖项(Grails POM 或项目 POM)不同或名称不同。当您执行“grails package”时,它会将 GRAILS_HOME/lib 中的 jar 复制到 web-app/WEB-INF/lib 中,并且无法阻止重复。例如, wherever Grails does not use the fully-qualified jar name, you will see duplicates in WEB-INF/lib。

Maven 依赖插件不允许我们排除提供的依赖项(至少目前是这样),这使得问题更加复杂,所以当你执行“mvn package”时,所有的 Grails 依赖项都会进入 ./lib。这对 Grails 开发人员来说是不方便的,因为它们通常是从 GRAILS_HOME/lib 复制的。理想情况下,在我们可以称之为真正的 Maven-Grails 集成之前,这种冲突将得到解决。

缺少其他 Maven 生命周期阶段

简单的演示为 Grails 提供了 clean 和 package 生命周期增强。我们希望能够使用 Maven 为我们完成更多的开发和持续集成工作。

例如,我们希望从 Grails 项目布局构建 WAR 文件。使用 Ant 和 Maven 实现这一点并不难。理想情况下,它应该实现为一个 Maven 插件 - 这基本上是 Arnaud 的项目,所以我希望他能取得一些进展,但也希望他能从这里的经验中学习。

其他有用的生命周期阶段也缺失。例如,无法从示例中的 Maven 驱动测试。

Grails 打包周期

Grails 和 Maven 各自拥有自己的“package”周期。通常 Grails 的周期只需要发生一次(在 clean 之间),但仍然很麻烦,需要记住去执行它。

Eclipse 的 Groovy 插件

在 .groovy 源文件中进行语法高亮显示很好,但除此之外,Groovy 插件似乎会碍事。这实际上与 Maven 或 Grails 都无关,但众所周知,它会导致其他 Grails Eclipse 用户出现问题。例如,如果您编辑控制器或服务,您可能会看到一个警告消息,询问您是否要终止应用程序。Groovy 插件检测到更改,Eclipse 无法处理类路径的更改。但 Grails 可以,所以通常您可以点击“Continue”按钮。但并非总是可以。在项目属性中禁用 Groovy 编译是安全的,但这样您就会失去非 grails-app 类的动态编译。
再次附上附件:点击 这里

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有