下载项目依赖项时,Maven抛出IllegalStateException(与SSL相关?) [英] IllegalStateException thrown by Maven (SSL-related?) when downloading project dependencies

查看:116
本文介绍了下载项目依赖项时,Maven抛出IllegalStateException(与SSL相关?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ARM机器上设置开发环境,使用以下版本的Java和Maven,都通过 apt-get 安装:

I'm setting up a development environment on an ARM machine, with the following versions of Java and Maven, both installed via apt-get:

(xenial)craig@localhost:~$ mvn -version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-armhf/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.14.0", arch: "arm", family: "unix"

(xenial)craig@localhost:~$ java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-0ubuntu4~16.04.1-b14)
OpenJDK Zero VM (build 25.91-b14, interpreted mode)

但是,当我运行 mvn clean install 在我的项目中,它无法尝试下载 存在的POM文件。 (我可以在浏览器中访问它。)

However, when I run a mvn clean install on my project, it fails attempting to download a POM file that does exist. (I can visit it in my browser.)

堆栈跟踪非常大,但根似乎是:

The stacktrace is quite large, but the root seems to be:

Caused by: java.lang.IllegalStateException
    at sun.security.ec.ECDHKeyAgreement.deriveKey(Native Method)
    at sun.security.ec.ECDHKeyAgreement.engineGenerateSecret(ECDHKeyAgreement.java:130)
    at sun.security.ec.ECDHKeyAgreement.engineGenerateSecret(ECDHKeyAgreement.java:163)
    at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:648)
    at sun.security.ssl.ECDHCrypt.getAgreedSecret(ECDHCrypt.java:101)
    at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1067)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)

不幸的是,Maven失败了:

There unfortunately isn't much more to it - Maven fails with:

Caused by: org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.jacoco:jacoco-maven-plugin:jar:0.7.6.201602180812

堆栈以 deriveKey()中抛出的异常结束。我在机器上错过了一些加密库吗?

And the stack ends with the exception thrown in deriveKey(). Am I missing some crypto library on my machine?

这是新安装的Xenial(16.04 LTS)。

This is a fresh install of Xenial (16.04 LTS).

推荐答案

虽然安装Oracle JRE是一个简单的方法,但这里有一些说明,以便您特别使用OpenJDK Zero VM,无论是Maven,SSL,ECDH密钥协议或者在OpenJDK默认加密提供程序中的本机代码中实现的任何其他加密方法。

While installing the Oracle JRE is the easy way out, here are the instructions in case you want to use the OpenJDK Zero VM specifically, be it with Maven, SSL, the ECDH key agreement or any other crypto method that's implemented in native code in the OpenJDK default crypto provider.

我假设 ECDHKeyAgreement.deriveKey 方法失败,因为它是本机方法和OpenJDK Zero VM在Ubuntu中为Raspberry Pi打包只是无法处理它;我没有能力调试那个失败。

I've assumed that the ECDHKeyAgreement.deriveKey method fails because it is a native method and the OpenJDK Zero VM as packaged in Ubuntu for Raspberry Pi just can't handle it; I'm not equipped to debug that failure.

Ubuntu打包用纯Java实现的BouncyCastle加密提供程序。你需要以通常的方式安装它:

Ubuntu packages the BouncyCastle crypto provider which is implemented in pure Java. You need to install it the usual way:

sudo apt install libbcprov-java*

(这也会安装文档)

然后按照<$ c $中的说明操作c> /usr/share/doc/libbcprov-java/README.Debian 使其成为默认的加密提供程序。具体来说,您需要从JRE的ext目录链接到提供者jar,所以请执行 update-java-alternatives -l <​​/ code>后跟(在我的情况下 - 我一直在使用Ubuntu 16.04 Raspberry Pi服务器安装中提供的默认值 - 特定的JRE目录可能会及时更改):

Then follow the instructions in /usr/share/doc/libbcprov-java/README.Debian to make it the default crypto provider. Specifically, you need to make a link to the provider jar from the ext directory of the JRE, so do a update-java-alternatives -l followed by (in my case - I've been using the defaults provided in Ubuntu 16.04 Raspberry Pi server install - the specific JRE directory may change in time):

sudo ln -s /usr/share/java/bcprov.jar /usr/lib/jvm/java-1.8.0-openjdk-armhf/jre/lib/ext/bcprov.jar

然后编辑 /usr/lib/jvm/java-1.8.0-openjdk-armhf/jre/lib/security /java.security 文件(使用 sudo 调用编辑器),添加以下行:

Then edit the /usr/lib/jvm/java-1.8.0-openjdk-armhf/jre/lib/security/java.security file (invoking the editor with sudo), adding the line:

security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider

...其中列出了加密提供程序,并将已加密的提供程序的优先级加1,以便列表看起来类似于:

...where the crypto providers are listed, and adding 1 to the priority of the ones already there, so that the list looks similar to this:

security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=sun.security.ec.SunEC
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC

Java中的加密应该可以正常工作虽然很慢。这是一个我用来确认它的示例程序,如果你不想使用Maven:

Crypto in Java should now work, albeit very slowly. Here's an example program I've used to confirm that it does, if you don't want to use Maven for that:

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class URLGet {
        public static void main(String[] args) {
                try {
                        URL url = new URL(args[0]);
                        URLConnection urlConnection = url.openConnection();
                        try (
                                InputStream stream = urlConnection.getInputStream();
                        ) {
                                byte[] buf = new byte[4096];
                                int read;
                                while ((read = stream.read(buf, 0, buf.length)) > 0) {
                                        System.out.write(buf, 0, read);
                                }
                        }
                } catch (Exception e) {
                        e.printStackTrace(System.err);
                }
        }
}

将其指向任何https网址(例如 java URLGet https://www.google.com/ )确认Java可以处理SSL。

Point it at any https URL (e.g. java URLGet https://www.google.com/) to confirm that Java can handle SSL.

这篇关于下载项目依赖项时,Maven抛出IllegalStateException(与SSL相关?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆