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都不一样,各自对应自己的路径,最后重启系统。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论