= GEP-9:模块化 :icons: font .元数据 **** [horizontal,options="compact"] *编号*:: GEP-9 *标题*:: 模块化 *版本*:: 5 *类型*:: 功能 *状态*:: 最终 *评论*:: 部分已并入 Groovy 2.0 *负责人*:: Paul King *创建日期*:: 2011-10-26 *最后修改日期* :: 2018-10-24 **** == 摘要:模块化 本 GEP 介绍了模块化工作的目标和拟议细节,该工作将: * 为核心 Groovy 提供更精简的 jar,其他 jar 包含 Groovy 的可选部分 * 为 Groovy 库编写者提供与 groovy 运行时挂钩的接口,允许他们以各种方式扩展 Groovy - 使“grapes”更像插件而不仅仅是传统的库 * 有关模块化可能如何影响其他工件的辅助细节,例如 Groovy 构建、wiki、jira 组件等。 此活动建立在之前讨论的工作基础上:Groovy 2.0 模块化和更早的配置文件讨论 封装和模块化。 === 范围外 虽然我们应密切关注其他模块化工作,但在现阶段,我们预期 Groovy 类的结构会发生变化,这与最终使用 OSGi 或 Java 8 的 Jigsaw 模块化等技术无关。 === Jar 分组 目前,Groovy 提供两个主要的 jar 工件: * groovy.jar 包含 Groovy 的核心类,并依赖于少数几个关键的依赖 jar(即 asm、antlr 等) * groovy-all.jar 包含 Groovy 的核心类和捆绑的关键依赖 jar 版本 模块化后,主要的 Groovy 代码库将打包成额外的 jar 工件: * groovy.jar 或 groovy-core.jar(名称待定)将包含一套更小的 Groovy 核心类,并将保留其对少数几个关键依赖 jar(即 asm、antlr 等)的依赖 * 许多更小的“模块/组件”jar(确切的名称/数量/内容待定),但可能包括 groovy-bsf.jar、groovy-sql.jar、groovy-swing.jar、groovy-jmx.jar、groovy-xml、groovy-tools 等 * groovy-all.jar 包含 Groovy 的核心类、捆绑的关键依赖 jar 版本以及所有模块 jar 中的类 * 可选地,我们可能会支持其他“配置文件”——配置文件是为其他环境捆绑在一起的其他“胖”jar,例如 groovy-android.jar 可能会排除 JMX 或 Swing 模块。 欢迎提供 jar 分组的建议/推荐。 有关更多详细信息,请参阅随附的讨论:Groovy 2.0 模块化。 此捆绑工作的目标之一是通过以下方式促进 Groovy 作为语言的演变: * 使相关性较低的模块被弃用并从主项目中删除,但仍可作为外部库使用,例如 groovy-bsf 可能在大多数用户拥有 jsr-223 的情况下被视为不必要(但它可以移动到单独的模块中,并仍然可供任何需要它的人使用) * 从旧版本到新版本功能的受控迁移,例如我们可以生成一个 groovy-xml-v2 库,它可能存在破坏性更改——v2 库最初可能是一个可选模块,但后来成为主要支持的选项——旧版用户将能够“指向旧版本”,以便他们的脚本在他们愿意的情况下不会中断(稍后提供更多详细信息) * 外部模块可以更容易地并入核心发行版(用户可以自定义捆绑的某些方面) * 我们可以提供包含已弃用功能或不可预见的破坏性更改的“旧版”jar——库编写者可以将旧版 jar 并入他们的库中,以便更容易地支持跨多个 Groovy 版本使用他们的库 === 配置 Groovy 安装 Groovy 使用 conf/groovy-starter.conf 文件引导其配置。 它包含以下条目: ``` # 加载所需库 load !{groovy.home}/lib/*.jar ``` 所需的 jar 位于 Groovy 安装的 lib 目录中。 Groovy 安装现在可能有一个“modules”(或 components 或 repository)目录。 groovy-starter.conf 文件将包含以下附加条目: ``` # 加载 SQL 组件 grab org.codehaus.groovy groovy-sql 1.9.0 # 加载 XML 组件 grab org.codehaus.groovy groovy-xml 1.9.0 ``` Grapes 通过 Ivy 加载并从设置文件配置。 该文件可能包含附加条目: `````` Ivy 库(或可能是 wharf 或 aether 库)很可能会成为必需的 jar——尽管可能只支持非常有限形式的 grab,在这种情况下可能不需要额外的库。 === 运行时钩子/注册 下载 grape 时,其 jar 中的类会添加到(当前是附加到)类路径中。 此外,我们计划支持额外的集成点: [options="header"] |=== | 潜在钩子 | 目的 | 状态 m| META-INF/services/ + org.codehaus.groovy.runtime.CategoryMethods | 允许模块定义额外的类别方法 | 现在位于 `META-INF/groovy/ + org.codehaus.groovy.runtime.ExtensionModuleSpec` m| META-INF/services/ + org.codehaus.groovy.runtime.StaticCategoryMethods | 允许模块定义额外的静态类别方法 | 现在位于 `META-INF/groovy/ + org.codehaus.groovy.runtime.ExtensionModuleSpec` m| META-INF/services/ + org.codehaus.groovy.runtime.SerializedCategoryMethods | 允许模块定义已序列化的额外类别方法 | 推迟 m| META-INF/services/ + org.codehaus.groovy.runtime.ExpandoMethods | 允许模块定义额外的 ExpandoMetaClass 方法 | 推迟 m| META-INF/services/ + org.codehaus.groovy.runtime.DefaultMetaClasses | 允许模块定义类似于当前魔术包机制的额外元类脚注:[这需要与现有的用于定义自定义元类的魔术包机制相结合。] | 推迟 m| META-INF/services/groovy/defaultImports | 允许模块定义额外的普通、星号、静态导入、别名 | 移至编译器配置 m| META-INF/services/groovy/defaultExtensions | 允许模块定义支持的文件扩展名 | 移至编译器配置 m| META-INF/services/groovy/defaultAstTransforms | 允许模块定义 AST 转换 | 现在位于 `META-INF/services/ + org.codehaus.groovy.transform.ASTTransformation` | ? | 提供一种注册构建器元数据的方法 | 推迟 | ? | 是否应该有一种“发布”新的命令行级别启动脚本的方法,例如 java2groovy | 推迟 | ? | 提供一种注册运行器类的方法,例如 EasyB - 可能还需要检测运行器类型 | 现在位于 `META-INF/groovy/ + org.apache.groovy.plugin.GroovyRunner` | ? | 提供一种注册特殊编译器标志的方法,例如 '--indy' | 推迟 | ? | 提供一种注入特殊 AST 自定义的方法 | 推迟 |=== 这也是我们可以指定额外要求的地方,例如要求“invoke dynamic”——但稍后也会提及。 我们能否声明性地指定我们的安全策略要求? 或者我们能否禁用特定功能方面,例如禁用某些标准全局 AST 转换,因为我们想提供一个更好的? (这显然有安全隐患!)另一个问题是所有这些功能是否也可以通过 API 提供。 这样的 API 是否允许模块“注销”? === Groovydoc/源指针 一些模块化系统支持随模块“安装”文档(和/或源)。 模块是否应该有一个指向(或捆绑)其 GroovyDoc 和/或源代码的指针。 在 Java 生态系统中,许多库都根据通用约定发布其 javadoc/源代码,或者在线提供 javadoc。 我们是依赖这些既定约定还是提供额外支持? 对于无法访问复杂 IDE 的用户来说,将所有文档以“合并”形式集中在一处可能会很方便。 === 运行时自省 在 Groovy 中,您目前可以使用以下方式确定 Groovy 版本: ``` println GroovySystem.version ``` 这会返回一个字符串。 在 GROOVY-2422 中,它谈到了对额外版本检查的渴望。 它还谈到了列出功能。 这可以是“invokeDynamic”是否可用,或者实际上只是关于可用已加载模块。 通常,我们期望我们的依赖项作为 pom 的一部分指定并自动加载,但有时执行特殊操作会很有用。 通常,我们是否应该能够找出已加载模块的列表和版本? 或者询问特定类属于哪个模块/版本? === 构建影响 大部分讨论在此处:Groovy 2.0 模块化 每个“子模块”是否应该能够独立构建? 它是否会有自己的 javadoc、自己的编码风格规则、自己的覆盖率指标等。 === 模块健壮性 我们是否应该提供一个标准的钩子/机制来尝试对抗以下情况: * 您正在加载一个依赖于根类加载器管理的类的 jar? * 类路径中是否已经存在与您的类同名的类? * 类路径中是否已经存在与您的某个依赖项同名但版本不兼容的类 * 能够注册“ping”/健康检查方法以快速测试组件 === 辅助 IDE 支持 我们可能会定义一个标准位置或约定,例如 META-INF/services/groovy/dsld 或 META-INF/services/groovy/gdsl,IDE 可以在其中找到与该模块相关的 DSL 描述符。 === 日志记录 模块本身是否应该有标准的日志记录方式? 是 j.u.l.Logger 吗? 也许与 slf4j 桥接? == 参考资料和有用链接 === Wiki 页面(网络档案) * https://web.archive.org/web/20150508040614/http://docs.codehaus.org/display/GROOVY/Groovy+2.0+modularization[Groovy 2.0 模块化] * https://web.archive.org/web/20150512231712/http://docs.codehaus.org/display/GroovyJSR/Packaging+and+Modularity[封装和模块化] === JIRA 问题 * https://issues.apache.org/jira/browse/GROOVY-2422[GROOVY-2422:用于检查 Groovy 运行时版本和功能的 API] == 更新历史 4 (2011-10-26):: 从 Codehaus wiki 提取的版本 5 (2018-10-24):: 许多细微调整