java - Problems using Maven and SSL behind proxy


Keywords:java 


Question: 

I just downloaded Maven and was trying to run the simple command found on the "Maven in Five Minutes" page (). This is the command:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

When I run it I get an error with SSL certificate and cannot download from the central Maven repository at . The error is "SunCertPathBuilderException: unable to find valid certification path to requested target".

I am sitting behind a corporate firewall and have correctly configured the proxy settings for both http and https access via the settings.xml file. I doubt that everyone who downloads Maven and runs it for the first time has to import the SSL certificate of the Maven repository, so the problem must be with the proxy. Does anyone have any experience with this?

Here's the stack trace in full debug mode (-X):

 mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T22:58:10+02:00) Maven home: C:\Projects\maven\bin.. Java version: 1.7.0_45, vendor: Oracle Corporation Java home: C:\Program Files\Java\jdk1.7.0_45\jre Default locale: it_IT, platform encoding: Cp1252 OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows" [DEBUG] Using connector WagonRepositoryConnector with priority 0.0 for via *****:8080 with username=*****, password=*** Downloading: [WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-clean-plugin:2.5: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5 org.apache.maven.plugin.PluginResolutionException: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5 at org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver.resolve(DefaultPluginDependenciesResolver.java:122) at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getPluginDescriptor(DefaultMavenPluginManager.java:148) at org.apache.maven.plugin.DefaultBuildPluginManager.loadPlugin(DefaultBuildPluginManager.java:81) at org.apache.maven.plugin.prefix.internal.DefaultPluginPrefixResolver.resolveFromProject(DefaultPluginPrefixResolver.java:138) at org.apache.maven.plugin.prefix.internal.DefaultPluginPrefixResolver.resolveFromProject(DefaultPluginPrefixResolver.java:121) at org.apache.maven.plugin.prefix.internal.DefaultPluginPrefixResolver.resolve(DefaultPluginPrefixResolver.java:85) at org.apache.maven.lifecycle.internal.MojoDescriptorCreator.findPluginForPrefix(MojoDescriptorCreator.java:260) at org.apache.maven.lifecycle.internal.MojoDescriptorCreator.getMojoDescriptor(MojoDescriptorCreator.java:220) at org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator.calculateTaskSegments(DefaultLifecycleTaskSegmentCalculator.java:103) at org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator.calculateTaskSegments(DefaultLifecycleTaskSegmentCalculator.java:83) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:85) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214) at org.apache.maven.cli.MavenCli.main(MavenCli.java:158) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) Caused by: org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5 at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:349) at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:231) at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(DefaultRepositorySystem.java:288) at org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver.resolve(DefaultPluginDependenciesResolver.java:108) ... 23 more Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact org.apache.maven.plugins:maven-clean-plugin:pom:2.5 from/to central (): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:459) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:262) at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:239) at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:334) ... 26 more Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact org.apache.maven.plugins:maven-clean-plugin:pom:2.5 from/to central (): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at org.eclipse.aether.connector.wagon.WagonRepositoryConnector$6.wrap(WagonRepositoryConnector.java:1016) at org.eclipse.aether.connector.wagon.WagonRepositoryConnector$6.wrap(WagonRepositoryConnector.java:1004) at org.eclipse.aether.connector.wagon.WagonRepositoryConnector$GetTask.run(WagonRepositoryConnector.java:725) at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) Caused by: org.apache.maven.wagon.TransferFailedException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at org.apache.maven.wagon.providers.http.AbstractHttpClientWagon.fillInputData(AbstractHttpClientWagon.java:935) at org.apache.maven.wagon.StreamWagon.getInputStream(StreamWagon.java:116) at org.apache.maven.wagon.StreamWagon.getIfNewer(StreamWagon.java:88) at org.apache.maven.wagon.StreamWagon.get(StreamWagon.java:61) at org.eclipse.aether.connector.wagon.WagonRepositoryConnector$GetTask.run(WagonRepositoryConnector.java:660) ... 4 more Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) at org.apache.maven.wagon.providers.http.httpclient.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:280) at org.apache.maven.wagon.providers.http.httpclient.impl.conn.HttpClientConnectionOperator.upgrade(HttpClientConnectionOperator.java:167) at org.apache.maven.wagon.providers.http.httpclient.impl.conn.PoolingHttpClientConnectionManager.upgrade(PoolingHttpClientConnectionManager.java:329) at org.apache.maven.wagon.providers.http.httpclient.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:392) at org.apache.maven.wagon.providers.http.httpclient.impl.execchain.MainClientExec.execute(MainClientExec.java:218) at org.apache.maven.wagon.providers.http.httpclient.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194) at org.apache.maven.wagon.providers.http.httpclient.impl.execchain.RetryExec.execute(RetryExec.java:85) at org.apache.maven.wagon.providers.http.httpclient.impl.execchain.RedirectExec.execute(RedirectExec.java:108) at org.apache.maven.wagon.providers.http.httpclient.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186) at org.apache.maven.wagon.providers.http.httpclient.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.maven.wagon.providers.http.AbstractHttpClientWagon.execute(AbstractHttpClientWagon.java:756) at org.apache.maven.wagon.providers.http.AbstractHttpClientWagon.fillInputData(AbstractHttpClientWagon.java:854) ... 8 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323) ... 27 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 33 more


10 Answers: 

The fact is that your maven plugin try to connect to an https remote repository
(e.g )

This is a new SSL connectivity for Maven Central was made available in august, 2014 !

So please, can you verify that your settings.xml has the correct configuration.

    <settings>
  <activeProfiles>
    <!--make the profile active all the time -->
    <activeProfile>securecentral</activeProfile>
  </activeProfiles>
  <profiles>
    <profile>
      <id>securecentral</id>
      <!--Override the repository (and pluginRepository) "central" from the
         Maven Super POM -->
      <repositories>
        <repository>
          <id>central</id>
          <url>http://repo1.maven.org/maven2</url>
          <releases>
            <enabled>true</enabled>
          </releases>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://repo1.maven.org/maven2</url>
          <releases>
            <enabled>true</enabled>
          </releases>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
</settings>

You can alternatively use the simple http maven repository like this

 <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Maven Plugin Repository</name>
      <url>http://repo1.maven.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

Please let me know if my solution works ;)

J.

 

The answer above is a good working solution, but here's how to do it if you want to use the SSL repo:

  • Use a browser (I used IE) to go to
    • Click on lock icon and choose "View Certificate"
    • Go to the "Details" tab and choose "Save to File"
    • Choose type "Base 64 X.509 (.CER)" and save it somewhere
  • Now open a command prompt and type (use your own paths):

    keytool -import -file C:\temp\mavenCert.cer -keystore C:\temp\mavenKeystore

  • Now you can run the command again with the parameter

    -Djavax.net.ssl.trustStore=C:\temp\mavenKeystore

  • Under linux use absolute path

    -Djavax.net.ssl.trustStore=/tmp/mavenKeystore

    otherwise this will happen

  • Like this:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false -Djavax.net.ssl.trustStore=C:\temp\mavenKeystore

Optional:

You can use the MAVEN_OPTS environment variable so you don't have to worry about it again. See more info on the MAVEN_OPTS variable here:

 

Update

I just stumbled on this bug report:

It appears to be the cause of our problems here. Something with ca-certificates-java encountering an error and not fully populating cacerts. For me, this started happening after I upgraded to 15.10 and this bug probably occurred during that process.

The workaround is to execute the following command:

sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure

If you check the contents of the keystore (as in my original answer), you'll now see a whole bunch more, including the needed DigiCert Global Root CA.

If you went through the process in my original answer, you can clean up the key we added by running this command (assuming you did not specify a different alias):

sudo keytool -delete -alias mykey -keystore /etc/ssl/certs/java/cacerts

Maven will now work fine.


Original Answer

I'd just like to expand on Andy's answer about adding the certificate and specifying a keystore. That got me started, and combined with information elsewhere I was able to understand the problem and find another (better?) solution.

Andy's answer specifies a new keystore with the Maven cert specifically. Here, I'm going a bit more broad and adding the root certificate to the default java truststore. This allows me to use mvn (and other java stuff) without specifying a keystore.

For reference my OS is Ubuntu 15.10 with Maven 3.3.3.

Basically, the default java truststore in this setup does not trust the root certificate of the Maven repo (DigiCert Global Root CA), so it needs to be added.

I found it here and downloaded:

Then I found the default truststore location, which resides here:

/etc/ssl/certs/java/cacerts

You can see what certs are currently in there by running this command:

keytool -list -keystore /etc/ssl/certs/java/cacerts

When prompted, the default keystore password is "changeit" (but nobody ever does).

In my setup, the fingerprint of "DigiCert Global Root CA" did not exist (DigiCert calls it "thumbprint" in the link above). So here's how to add it:

sudo keytool -import -file DigiCertGlobalRootCA.crt -keystore /etc/ssl/certs/java/cacerts

This should prompt if you trust the cert, say yes.

Use keytool -list again to verify that the key exists. I didn't bother to specify an alias (-alias), so it ended up like this:

mykey, Dec 2, 2015, trustedCertEntry, Certificate fingerprint (SHA1): A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36

Then I was able to run mvn commands as normal, no need to specify keystore.

 

This may not be the best solution. I changed my maven from 3.3.x to 3.2.x. And this issue gone.

 

You can import the SSL cert manually and just add it to the keystore.

For linux users,

Syntax:

keytool -trustcacerts -keystore /jre/lib/security/cacerts -storepass changeit -importcert -alias nexus -file

Example :

keytool -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -importcert -alias nexus -file ~/Downloads/abc.com-ssl.crt

 

I actually had the same problem.

when I run

mvn clean package

on my maven project, I get this certificate error by the maven tool.

I followed @Andy 's Answer till the point where I downloaded the .cer file

after that the rest of the answer didn't work for me but I did the following(I am running on Linux Debian machine)

first of all, run:

keytool -list -keystore "Java path+"/jre/lib/security/cacerts""

for example in my case it is:

keytool -list -keystore /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/security/cacerts

if it asks about the password, just hit enter.

this command is supposed to list all the ssl certificates accepted by the java. when I ran this command, in my case I got 93 certificates for example.

Now add the downloaded file .cer to the cacerts file by running the following command:

sudo keytool -importcert -file /home/hal/Public/certificate_file_downloaded.cer -keystore /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/security/cacerts

write your sudo password then it will ask you about the keystore password

the default one is changeit

then say y that you trust this certificate.

if you run the command

keytool -list -keystore /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/lib/security/cacerts

once again, in my case, I got 94 contents of the cacerts file

it means, it was added successfully.

 

I was getting the same error about the SSL certificate when Maven tried to download the necessary modules automatically.
As a remedy, I was attempting to implement Luke's answer above, but found that the DigiCert Global Root CA certificate is already in Java's trusted keystore.

What helped me was adding %JAVA_HOME%\bin to the Path variable (I am running Windows). And %JAVA_HOME% is a JDK location, not just a JRE location, since Maven needs a JDK.
I am not certain why it helped, but it did. I am absolutely sure that this was the only thing I changed.

 

If this issue happens for the HTTPS repository, f.e. you can just try to replace with non secured: . And that's it

 

I ran into this problem in the same situation, and I wrote up a detailed answer to a related question on stack overflow explaining how to more easily modify the system's cacerts using a GUI tool. I think it's a little bit better than using a one-off keystore for a specific project or modifying the settings for maven (which may cause trouble down the road).

 

Step 1: GET the contents of the Certificate of the website( you want to have it imported as a trusted root)

$ keytool -printcert -rfc -sslserver maven.2xoffice.com*

-----BEGIN CERTIFICATE-----
MIIFNTCCBB2gAwIBAgIHJ73QrVnyJjANBgkqhkiG9w0BAQsFADCBtDELMAkGA1UEBhMCVVMxEDAO
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMxITAfBgNVBAoT
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
...
-----END CERTIFICATE-----
The -rfc option outputs the certificate chain in PEM-encoded format for easy import back into a keystore.

Step 2: Save the whole thing (including the BEGIN CERTIFICATE and END CERTIFICATE lines, which are significant in this case) as godaddyg2.pem and imported it into my trust store via:

Step 3: Import the certificate in the keystore( java trusted key store)

$ keytool -importcert -file ./godaddyg2.pem -keystore $JRE_LIB/lib/security/cacerts