在编写使用 Maven 编译运行 Storm 代码教程时遇到了一个比较棘手的问题,首次编译代码需要下载相应的依赖包,有时会下载失败,一直以为多试几次就可以,但后来发现,并非是简单的网络问题,依赖包链接(clojars.org)在浏览器中可以打开,却始终无法通过 Maven 进行下载。困扰了好几天终于解决了,在此记录一下遇到的问题以及解决方法。
默认镜像无法下载依赖的问题
发现这个问题的缘由是我在另一台电脑上编译运行 Storm 代码时,一运行 maven ....
进行编译就遇到了问题,并且试了好几次,间隔一两天后还是会如此,输出信息如下:
Downloading: https://repo.maven.apache.org/maven2/org/apache/storm/storm/0.9.6/storm-0.9.6.pom
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for org.apache.storm:storm-starter:[unknown-version]: Could not transfer artifact org.apache.storm:storm:pom:0.9.6 from/to central (https://repo.maven.apache.org/maven2): java.security.ProviderException: java.security.KeyException and 'parent.relativePath' points at wrong local POM @ line 20, column 11
@
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project org.apache.storm:storm-starter:[unknown-version] (/usr/local/storm/examples/storm-starter/pom.xml) has 1 error
[ERROR] Non-resolvable parent POM for org.apache.storm:storm-starter:[unknown-version]: Could not transfer artifact org.apache.storm:storm:pom:0.9.6 from/to central (https://repo.maven.apache.org/maven2): java.security.ProviderException: java.security.KeyException and 'parent.relativePath' points at wrong local POM @ line 20, column 11 -> [Help 2]
在下载第一个 pom 文件时就出错了,提示无法从中心库(Maven central)中下载,并且 'parent.relativePath' 属性指向的是一个错误的本地 POM。'parent.relativePath' 这个错误实际上是个误导,这个错误在这边是没有影响的,只要换个 Maven 镜像就可以了,可使用开源中国 Maven 库来解决该问题。
修改 Maven 的配置文件(安装目录下的 conf/settings.xml 文件),将 <mirrors>..</mirrors>
间的内容改为:
<mirrors>
<!-- mirror | Specifies a repository mirror site to use instead of a given
repository. The repository that | this mirror serves has an ID that matches
the mirrorOf element of this mirror. IDs are used | for inheritance and direct
lookup purposes, and must be unique across the set of mirrors. | -->
<mirror>
<id>nexus-osc</id>
<mirrorOf>central</mirrorOf>
<name>Nexus osc</name>
<url>http://maven.oschina.net/content/groups/public/</url>
</mirror>
<mirror>
<id>nexus-osc-thirdparty</id>
<mirrorOf>thirdparty</mirrorOf>
<name>Nexus osc thirdparty</name>
<url>http://maven.oschina.net/content/repositories/thirdparty/</url>
</mirror>
</mirrors>
以及将 <profile>...<profile>
之间的内容改为:
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>nexus</id>
<name>local private nexus</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>local private nexus</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
改好后保存,再次执行 maven ...
应该就可以了。
Maven 第三方库(thirdparty)
开源中国 Maven 库的说明里是说“补充: 如果还需要osc的thirdparty仓库或多个仓库,需要如下修改”,但实测若没有加上thirdparty(也就是上述 mirror 设置中,id 为 nexus-osc-thirdparty 的那一项)的话,可能会遇到如下的错误:
Could not find artifact clj-time:clj-time:jar:0.4.1 in nexus-osc (http://maven.oschina.net/content/groups/public/)
clojars.org 的 https 证书问题
有时需要多试几次才能下载完全部依赖包,通常遇到的问题是 clojars.org 这个网站的依赖包下载不了(clojars.org这个网站确实有时无法访问),提示的错误如下:
Downloading: https://clojars.org/repo/clj-time/clj-time/0.4.1/clj-time-0.4.1.pom
Downloading: https://clojars.org/repo/compojure/compojure/1.1.3/compojure-1.1.3.pom
...
Downloading: https://clojars.org/repo/reply/reply/0.3.0/reply-0.3.0.pom
Could not transfer artifact clj-time:clj-time:pom:0.4.1 from/to clojars (https://clojars.org/repo/): java.security.ProviderException: java.security.KeyException
试了下,通过浏览器可以访问列出来无法下载的连接,但通过 wget
命令却无法下载,提示“证书通用名 "www.clojars.org" 与所要求的主机名 "clojars.org" 不符”。注意到 Maven 给出的错误为“java.security.ProviderException: java.security.KeyException”,搜索了下,看出这是 https 的问题。把 https://clojars.org 的证书下载来看,证书的通用名(CN)为 www.clojars.org,而不是 *.clojars.org...
通过 http 可以访问,但通过 https 无法访问,看似不好解决,但后来脑洞大开,在配置文件中为 clojars.org 单独设置一个 http 镜像就可以了。
在 Maven 配置文件中添加如下配置:
<!-- 在 <mirrors> .. </mirrors> 中添加如下配置: -->
<mirror>
<id>clojars</id>
<mirrorOf>clojars</mirrorOf>
<url>http://clojars.org/repo/</url>
</mirror>
<!-- 在 <repositories> .. </repositories> 中添加如下配置: -->
<repository>
<id>clojars</id>
<url>http://clojars.org/repo/</url>
</repository>
配置完再次编译,perfect,问题完美解决,从 clojars 下载的依赖包都通过 http 下载了...
如果你需要这份配置文件,可以直接下载笔者修改好的版本,下载地址:http://pan.baidu.com/s/1qXwZlsK,下载后执行如下命令替换配置文件:
cp ~/下载/maven-settings.xml /usr/local/maven/conf/settings.xml # /usr/local/maven 为maven的安装目录
sbt 也存在 https 的问题
在编写 Spark 快速入门指南时,需要使用 sbt 编译打包 Scala 编写的代码,同样遇到了 https 的问题,运行时会出现如下错误:
Getting org.scala-sbt sbt 0.13.9 ...
:: problems summary ::
:::: WARNINGS
module not found: org.scala-sbt#sbt;0.13.9
==== local: tried
/home/hadoop/.ivy2/local/org.scala-sbt/sbt/0.13.9/ivys/ivy.xml
-- artifact org.scala-sbt#sbt;0.13.9!sbt.jar:
/home/hadoop/.ivy2/local/org.scala-sbt/sbt/0.13.9/jars/sbt.jar
...
::::::::::::::::::::::::::::::::::::::::::::::
:: UNRESOLVED DEPENDENCIES ::
::::::::::::::::::::::::::::::::::::::::::::::
:: org.scala-sbt#sbt;0.13.9: not found
::::::::::::::::::::::::::::::::::::::::::::::
:::: ERRORS
Server access Error: java.security.ProviderException: java.security.KeyException url=https://jcenter.bintray.com/org/scala-sbt/sbt/0.13.9/sbt-0.13.9.pom
:: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
unresolved dependency: org.scala-sbt#sbt;0.13.9: not found
Error during sbt execution: Error retrieving required libraries
(see /home/hadoop/.sbt/boot/update.log for complete log)
Error: Could not retrieve sbt 0.13.9
这里有两个问题:
- 用浏览器访问给出的链接,也是 404 的状态,这就需要修改 repositories 的地址。
- 提示 “Server access Error: java.security.ProviderException: java.security.KeyException”,但通过浏览器可以访问,就跟 Maven 遇到的问题一样,需要将 https 改成通过 http 访问。
sbt 修改镜像会稍微麻烦一些,需要先下载官方的 sbt-launch.jar,解压后修改配置文件,再重新打包,可以下载笔者修改好的版本: http://pan.baidu.com/s/1eRyFddw。
自行修改的话,命令如下:
mkdir ~/sbt
cd ~/sbt
wget https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.9/sbt-launch.jar -O ./sbt-launch.jar # 下载
unzip -q ./sbt-launch.jar # 解压
需要修改其中的 ./sbt/sbt.boot.properties 文件(vim ./sbt/sbt.boot.properties
),将 [repositories] 处修改为如下内容(即增加了一条 oschina 镜像,并且将原有的 https 镜像都改为相应的 http 版):
[repositories]
local
oschina: http://maven.oschina.net/content/groups/public/
jcenter: http://jcenter.bintray.com/
typesafe-ivy-releases: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
maven-central: http://repo1.maven.org/maven2/
保存后,重新打包 jar:
rm ./sbt-launch.jar # 删除旧的
jar -cfM ./sbt-launch.jar . # 重新打包
ls | grep -v "sbt-launch.jar" | xargs rm -r # 解压后的文件已无用,删除
注意打包时,需要使用 -M 参数,否则 ./META-INF/MANIFEST.MF 会被修改,导致运行时会出现 “./sbt-launch.jar中没有主清单属性” 的错误。