繁体   English   中英

下载项目依赖项时,Maven抛出IllegalStateException(与SSL相关?)

[英]IllegalStateException thrown by Maven (SSL-related?) when downloading project dependencies

我在ARM机器上设置开发环境,使用以下版本的Java和Maven,都通过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文件。 (我可以在浏览器中访问它。)

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

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失败了:

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

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

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

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

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

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

sudo apt install libbcprov-java*

(这也安装了文档)

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

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调用编辑器),添加以下行:

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

...列出加密提供程序,并在已存在的加密提供程序的优先级中加1,以使列表看起来类似于:

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:

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 URL(例如java URLGet https://www.google.com/ )以确认Java可以处理SSL。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM