构建 Maven 时如何覆盖远程资源?

How can I override remote resources when building Maven?

我正在尝试从源代码构建 Maven 3.5.2。 (原因:我在一台安装了Maven 3.0.5的机器上,但不允许下载二进制文件(Maven依赖项除外),我需要更高版本的Maven,所以我正在计划使用 Maven 3.0.5 构建 Maven 3.5.2。根据文档,这是可能的。)

我用来构建的机器也无法访问互联网。

Maven 构建尝试从 apache.org 访问 Apache 许可证,但如果无法下载许可证文件,则会失败。特别是,这里是构建输出的尾端(运行 作为 root,尽管在 SElinux 下):

[INFO] --- apache-rat-plugin:0.11:check (rat-check) @ apache-maven ---
[INFO] 51 implicit excludes (use -debug for more details).
[INFO] Exclude: src/test/resources*/**
[INFO] Exclude: src/test/projects/**
[INFO] Exclude: src/test/remote-repo/**
[INFO] Exclude: **/*.odg
[INFO] Exclude: src/bin/m2.conf
[INFO] Exclude: bootstrap/**
[INFO] Exclude: README.bootstrap.txt
[INFO] Exclude: .repository/**
[INFO] Exclude: .maven/spy.log
[INFO] Exclude: .java-version
[INFO] Exclude: README.md
[INFO] Exclude: DEPENDENCIES
[INFO] 19 resources included (use -debug for more details)
[INFO] Rat check: Summary of files. Unapproved: 0 unknown: 0 generated: 0 approved: 16 licence.
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:unpack-dependencies (unpack-jansi-native) @ apache-maven ---
[INFO] Unpacking /root/.m2/repository/org/fusesource/jansi/jansi/1.16/jansi-1.16.jar to /tmp/maven-build/apache-maven/target/dependency with includes "META-INF/native/**" and excludes ""
[INFO] 
[INFO] --- maven-remote-resources-plugin:1.5:process (default) @ apache-maven ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Apache Maven ...................................... SUCCESS [25.091s]
[INFO] Maven Model ....................................... SUCCESS [18.000s]
[INFO] Maven Artifact .................................... SUCCESS [4.418s]
[INFO] Maven Plugin API .................................. SUCCESS [4.677s]
[INFO] Maven Builder Support ............................. SUCCESS [1.900s]
[INFO] Maven Model Builder ............................... SUCCESS [5.690s]
[INFO] Maven Settings .................................... SUCCESS [1.905s]
[INFO] Maven Settings Builder ............................ SUCCESS [2.010s]
[INFO] Maven Repository Metadata Model ................... SUCCESS [1.511s]
[INFO] Maven Artifact Resolver Provider .................. SUCCESS [5.110s]
[INFO] Maven Core ........................................ SUCCESS [13.168s]
[INFO] Maven SLF4J Simple Provider ....................... SUCCESS [5.013s]
[INFO] Maven Embedder .................................... SUCCESS [3.617s]
[INFO] Maven Compat ...................................... SUCCESS [4.462s]
[INFO] Apache Maven Distribution ......................... FAILURE [4:18.467s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5:58.134s
[INFO] Finished at: Mon Feb 12 21:03:11 GMT 2018
[INFO] Final Memory: 83M/190M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-remote-resources-plugin:1.5:process (default) on project apache-maven: Error rendering velocity resource. Invocation of method 'getResourceAsFile' in  class org.codehaus.plexus.resource.DefaultResourceManager threw exception org.codehaus.plexus.resource.loader.ResourceNotFoundException: Could not find resource 'https://www.apache.org/licenses/LICENSE-2.0.txt'. at remote-resources[line 38, column 26] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <goals> -rf :apache-maven

我认为远程资源插件可能是从 Apache parent POM 中引入的东西,但我不确定,因为我不太明白它是如何工作的。该配置似乎引入了已经包含 LICENSE.txt 的依赖项 apache-jar-resource-bundle,因此无需从 Internet 获取它。

有没有办法禁用远程资源检索(可能有利于本地资源),最好是通过将命令行参数传递给 Maven,但失败了,通过修改 Maven's root POM 的本地副本?


编辑:添加完整堆栈跟踪。似乎方法 getResourceAsFile 是使用 Velocity 的反射调用的,这让我认为在 Apache 工件之一中必须有一个引用 getResourceAsFile 的 Velocity 模板,但我在 repo 中找不到任何东西在 https://svn.apache.org/repos/asf/maven/resources/

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-remote-resources-plugin:1.5:process (default) on project apache-maven: Error rendering velocity resource. Invocation of method 'getResourceAsFile' in  class org.codehaus.plexus.resource.DefaultResourceManager threw exception org.codehaus.plexus.resource.loader.ResourceNotFoundException: Could not find resource 'https://www.apache.org/licenses/LICENSE-2.0.txt'. at remote-resources[line 38, column 26] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-remote-resources-plugin:1.5:process (default) on project apache-maven: Error rendering velocity resource.
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
    at java.lang.reflect.Method.invoke(Method.java:508)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:414)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:357)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error rendering velocity resource.
    at org.apache.maven.plugin.resources.remote.ProcessRemoteResourcesMojo.processResourceBundles(ProcessRemoteResourcesMojo.java:1246)
    at org.apache.maven.plugin.resources.remote.ProcessRemoteResourcesMojo.execute(ProcessRemoteResourcesMojo.java:520)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getResourceAsFile' in  class org.codehaus.plexus.resource.DefaultResourceManager threw exception org.codehaus.plexus.resource.loader.ResourceNotFoundException: Could not find resource 'https://www.apache.org/licenses/LICENSE-2.0.txt'. at remote-resources[line 38, column 26]
    at org.apache.velocity.runtime.parser.node.ASTMethod.handleInvocationException(ASTMethod.java:243)
    at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:187)
    at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:280)
    at org.apache.velocity.runtime.parser.node.ASTReference.value(ASTReference.java:567)
    at org.apache.velocity.runtime.parser.node.ASTExpression.value(ASTExpression.java:71)
    at org.apache.velocity.runtime.parser.node.ASTSetDirective.render(ASTSetDirective.java:142)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
    at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:87)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
    at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:87)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.Foreach.render(Foreach.java:420)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
    at org.apache.velocity.runtime.directive.Foreach.render(Foreach.java:420)
    at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:207)
    at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:342)
    at org.apache.velocity.runtime.RuntimeInstance.render(RuntimeInstance.java:1378)
    at org.apache.velocity.runtime.RuntimeInstance.evaluate(RuntimeInstance.java:1314)
    at org.apache.velocity.app.Velocity.evaluate(Velocity.java:254)
    at org.apache.maven.plugin.resources.remote.ProcessRemoteResourcesMojo.processResourceBundles(ProcessRemoteResourcesMojo.java:1218)
    ... 22 more
Caused by: org.codehaus.plexus.resource.loader.ResourceNotFoundException: Could not find resource 'https://www.apache.org/licenses/LICENSE-2.0.txt'.
    at org.codehaus.plexus.resource.DefaultResourceManager.getResource(DefaultResourceManager.java:173)
    at org.codehaus.plexus.resource.DefaultResourceManager.getResourceAsFile(DefaultResourceManager.java:91)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
    at java.lang.reflect.Method.invoke(Method.java:508)
    at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.doInvoke(UberspectImpl.java:395)
    at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:384)
    at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:173)
    ... 41 more

编辑 2:我想我找到了罪魁祸首:https://github.com/apache/maven/blob/maven-3.5.2/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm

它使用 getResourceAsFile 许可证 URL。

但我不知道这是从远程资源插件中提取的。

我不熟悉 Apache Velocity。谁能帮助解决如何覆盖它?


注意:不是 的重复,因为那个问题是关于依赖项解析的,但这是关于远程资源的,这是不同的。正在下载的文件不是 Maven 依赖项,它只是一个文本文件。我希望它使用的相应 Maven 依赖项是 apache-jar-resource-bundle,但该依赖项已经存在于我有权访问的远程存储库中,因此我不需要强制 Maven 在本地读取它。然而,它似乎确实尝试直接下载文件,而不是通过 Maven 依赖项。

在意识到 LICENSE.vm(和 the one inside apache-maven, not the other one)是问题所在后(参见我的 "EDIT 2"),我发现它也包含解决方案。 Glassfish 的 URL 被手动重定向到另一个,它位于文件的第 32-35 行。所以我想我可以为我的场景做类似的事情。

首先我弄清楚了所有的许可证并下载了它们。我给了它们所有 .license 扩展名,这样我就可以告诉 Git 将具有此扩展名的文件视为二进制文件(通过 .gitattributes),这样它就不会试图通过转换行结尾来弄乱文件,因为我想复制实际构建的功能。我实际需要下载的文件总共只有5个。

其次,我创建了一个小片段以插入到 VM 文件中;我称之为 license-redirect-snippet.vm:

## redirect all license URLs to local files
#if ($url == "https://www.apache.org/licenses/LICENSE-2.0.txt")
#set ( $url = '/usr/local/share/maven-build-licenses/apache2-txt.license' )
#end
#if ($url == "http://www.apache.org/licenses/LICENSE-2.0.txt")
#set ( $url = '/usr/local/share/maven-build-licenses/apache2-txt.license' )
#end
#if ($url == "http://www.apache.org/licenses/LICENSE-2.0")
#set ( $url = '/usr/local/share/maven-build-licenses/apache2-html.license' )
#end
#if ($url == "https://glassfish.java.net/public/CDDLv1.0.html")
#set ( $url = '/usr/local/share/maven-build-licenses/cddl1-html.license' )
#end
#if ($url == "http://www.eclipse.org/legal/epl-v10.html")
#set ( $url = '/usr/local/share/maven-build-licenses/epl1-html.license' )
#end
#if ($url == "http://www.opensource.org/licenses/mit-license.php")
#set ( $url = '/usr/local/share/maven-build-licenses/mit-html.license' )
#end

注意:文件末尾有一个新行。

然后就是将我的许可证复制到给定文件夹 (/usr/local/share/maven-build-licenses/) 并在构建之前使用 sed 修改 VM 文件的问题,在第 35 行之后添加代码段:

sed -i '35r /tmp/license-redirect-snippet.vm' /tmp/maven-build/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm

之后,构建通过!!

我可能可以想出更好的东西,例如根据目录的内容和一些键值对动态生成代码片段文件,甚至重写 getResourceAsFile 方法,这样就不需要重写这个变量了,但是对于这样一个简单的情况来说,这似乎有点过分了只有 5 个许可证需要处理。