maven依赖导入问题
之前在做项目的时候就遇到了这个问题,pom文件中引入依赖时,会有如下报错:
pkix path building failed: sun.security.provider.certpath.suncertpathbuilderexception:
unable to find valid certification path to requested target
这是因为maven请求远程仓库进行下载依赖jar包时进行了安全证书的验证,由于本地jdk没有添加安全证书,因此在执行安全验证时没有通过,造成了依赖无法引入的问题。
解决方法
1.手动下载依赖
我第一次遇到这个问题的时候就是这样解决的,现在想来也是非常头铁的一种解决方式。
需要什么依赖自己下载到本地maven仓库。
由于不可名状的原因国内开发者不可能访问国外的maven库因此需要使用aliyun提供的maven库,此处附上网址:https://maven.aliyun.com/mvn/view
2.忽略ssl证书校验
既然我们没有证书,那么就直接忽略证书校验好了。
idea打开file->settings->build,execution,development->build tools->runner->vm options,在输入框中输入命令使运行时忽略sll证书的校验即可。
附上mvn命令:
-dmaven.wagon.http.ssl.insecure=true -dmaven.wagon.http.ssl.allowall=true
3.生成并导入ssl证书
如果我们没有证书,又不想忽略校验,那么我们就自己生成一个ssl证书即可。
3.1
import javax.net.ssl.*; import java.io.*; import java.security.keystore; import java.security.messagedigest; import java.security.cert.certificateexception; import java.security.cert.x509certificate; public class installcert { public static void main(string[] args) throws exception { string host; int port; char[] passphrase; if ((args.length == 1) || (args.length == 2)) { string[] c = args[0].split(":"); host = c[0]; port = (c.length == 1) ? 443 : integer.parseint(c[1]); string p = (args.length == 1) ? "changeit" : args[1]; passphrase = p.tochararray(); } else { system.out .println("usage: java installcert <host>[:port] [passphrase]"); return; } file file = new file("jssecacerts"); if (file.isfile() == false) { char sep = file.separatorchar; file dir = new file(system.getproperty("java.home") + sep + "lib" + sep + "security"); file = new file(dir, "jssecacerts"); if (file.isfile() == false) { file = new file(dir, "cacerts"); } } system.out.println("loading keystore " + file + "..."); inputstream in = new fileinputstream(file); keystore ks = keystore.getinstance(keystore.getdefaulttype()); ks.load(in, passphrase); in.close(); sslcontext context = sslcontext.getinstance("tls"); trustmanagerfactory tmf = trustmanagerfactory .getinstance(trustmanagerfactory.getdefaultalgorithm()); tmf.init(ks); x509trustmanager defaulttrustmanager = (x509trustmanager) tmf .gettrustmanagers()[0]; savingtrustmanager tm = new savingtrustmanager(defaulttrustmanager); context.init(null, new trustmanager[]{tm}, null); sslsocketfactory factory = context.getsocketfactory(); system.out .println("opening connection to " + host + ":" + port + "..."); sslsocket socket = (sslsocket) factory.createsocket(host, port); socket.setsotimeout(10000); try { system.out.println("starting ssl handshake..."); socket.starthandshake(); socket.close(); system.out.println(); system.out.println("no errors, certificate is already trusted"); } catch (sslexception e) { system.out.println(); e.printstacktrace(system.out); } x509certificate[] chain = tm.chain; if (chain == null) { system.out.println("could not obtain server certificate chain"); return; } bufferedreader reader = new bufferedreader(new inputstreamreader( system.in)); system.out.println(); system.out.println("server sent " + chain.length + " certificate(s):"); system.out.println(); messagedigest sha1 = messagedigest.getinstance("sha1"); messagedigest md5 = messagedigest.getinstance("md5"); for (int i = 0; i < chain.length; i++) { x509certificate cert = chain[i]; system.out.println(" " + (i + 1) + " subject " + cert.getsubjectdn()); system.out.println(" issuer " + cert.getissuerdn()); sha1.update(cert.getencoded()); system.out.println(" sha1 " + tohexstring(sha1.digest())); md5.update(cert.getencoded()); system.out.println(" md5 " + tohexstring(md5.digest())); system.out.println(); } system.out .println("enter certificate to add to trusted keystore or 'q' to quit: [1]"); string line = reader.readline().trim(); int k; try { k = (line.length() == 0) ? 0 : integer.parseint(line) - 1; } catch (numberformatexception e) { system.out.println("keystore not changed"); return; } x509certificate cert = chain[k]; string alias = host + "-" + (k + 1); ks.setcertificateentry(alias, cert); outputstream out = new fileoutputstream("jssecacerts"); ks.store(out, passphrase); out.close(); system.out.println(); system.out.println(cert); system.out.println(); system.out .println("added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); } private static final char[] hexdigits = "0123456789abcdef".tochararray(); private static string tohexstring(byte[] bytes) { stringbuilder sb = new stringbuilder(bytes.length * 3); for (int b : bytes) { b &= 0xff; sb.append(hexdigits[b >> 4]); sb.append(hexdigits[b & 15]); sb.append(' '); } return sb.tostring(); } private static class savingtrustmanager implements x509trustmanager { private final x509trustmanager tm; private x509certificate[] chain; savingtrustmanager(x509trustmanager tm) { this.tm = tm; } public x509certificate[] getacceptedissuers() { throw new unsupportedoperationexception(); } public void checkclienttrusted(x509certificate[] chain, string authtype) throws certificateexception { throw new unsupportedoperationexception(); } public void checkservertrusted(x509certificate[] chain, string authtype) throws certificateexception { this.chain = chain; tm.checkservertrusted(chain, authtype); } } }
新建一个installcert类运行证书生成代码,注意,在执行前需要设置main参数,参数即为maven地址,如"maven.aliyun.com/nexus/content/groups/public"。
程序运行过程中需要确定,输入1即可。执行完成后会在程序同级目录生成jssecacerts证书,接下来就是将证书导入。
ps:如果不想设置main参数也可以自定义一个string[] str变量并赋值为maven仓库的url,然后把代码中的args改成str即可。
此处附上证书生成代码:
3.2 把生成的证书文件放至路径 java_home/jre/lib/security下,每个人的 java_home都不一样,各自对应自己的路径,最后重启系统。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论