One question I'm getting a lot is from people inside offices that use a proxy. Your company will have installed a Root CA on Windows, but Maven/sbt will complain because they use a different trust store. The easiest way to fix it is to make your build tools trust your Windows CA.
That should cover it. Follow below to learn how to add your own CA to java.
We covered how to put Apache Archiva behind HAProxy with SSL termination. Now we’re covering how to configure your tools of choice to query data from that repository.
Remember that we learned how to install a local Certificate Authority that would make your internal certificates work transparently? Bad news. Java doesn’t trust Windows Trusted Root store, it ships out with its own.
You’ll have to add your Certificate Authority to the Java store. These are AdoptOpenJDK 8 and 11 paths but it’s similar to most Java implementations.
Java CA store is present in a file called
cacerts that you can find in the following places:
Now that you’ve pinpointed the location of the store we’re going back to
openssl to convert your Certificate Authority certificate to the
der format (Distinguished Encoding Rules) that Java prefers.
Keytool to the rescue!
Keytool comes with Java and is the default tool to deal with certificates Java-side.
# list certificates present in this Java keystore keytool -list -v -keystore lib\cacerts # show detailed information on a cert by alias keytool -list -v -keystore lib\cacerts -alias xxxx
Keytool is working so let’s convert the certificate you have for your Certificate Authority
ca_key.crt and convert it to
# convert your pem CA certificate to der format openssl x509 -outform der -in ca_cert.pem -out ca_cert.der # import your CA to Java CA store keytool -import -file ca_cert.der -keystore lib\cacerts
Note that AdoptOpenJDK default store password is: changeit.
Now that we have Java talking proper SSL to your artifacts repository, let’s configure your editor of choice.
For the following examples we’re going to assume that HAProxy is running on
10.1.1.2 and on port 8888 dispatching to an Archiva backend. We’re also assuming that you’ve setup a repository in Archiva called
Maven pretty much takes care of everything by itself. You can set up repositories in
pom.xml like this:
<!-- to pull internal artifacts from --> <repositories> <repository> <id>acme-company-repo</id> <name>ACME Private Repo</name> <url>https://10.0.0.2/repository/acme-company-repo</url> </repository> </repositories> <!-- if you're also distributing your project --> <distributionManagement> <id>acme-company-repo</id> <name>ACME Private Repo</name> <url>https://10.0.0.2/repository/acme-company-repo</url> </distributionManagement>
Assuming that the company repository will be password protected, at least for distribution, you should add credentials to your
<settings> ... <servers> <server> <id>acme-company-repo</id> <username>your-username</username> <password>your-password</password> </server> </servers> </settings>
That’s it! Maven will work fine out of the box.
Ant + Ivy2
For Ivy we’re going to use 3 files, plus build.xml:
ivy.xml – list dependencies
build.xml – build file with “target” for ivy to get the dependencies
ivysettings.xml – define format on how dependencies are stored
%HOMEPATH%\.ivy2\repo.properties – to store password
ivy.xml – stores project dependencies:
build.xml – your project build file now has a
resolve target to get the dependencies:
Notice that compile dependencies are downloaded to
./lib and testing dependencies to
Also notice that we link to
repo.properties on your user to store login details to repository.
ivysettings.xml – defines how dependencies are stored in your internal repository:
And the last file
%HOMEPATH%.ivy2\repo.properties serves to store your access credentials out of source control.
That’s all! While a bit more involved you can just do
ant resolve and get all the dependencies for your project from the internal server repository.
Scala’s interactive build tool can also pickup from your internal repository.
build.sbt – where we store our build instructions:
libraryDepdendencies ++= Seq( "joda-time" % "joda-time" % "2.9.9" resolvers += ( "Repository Archiva Managed acme-company-repo Repository" at "https://10.1.1.2:8888/repository/acme-internal-repo" )
Notice that the repository name must match Archiva’s realm. The rule of thumb is that archiva will place “Repository Archiva Managed ### Repository”.
%HOMEPATH%.sbt\credentials.sbt, we use a single file for credentials and then link different
sbt versions to this file. This ensures credentials are only on one file making everything tighter. Password will also be linked to repository and not to sbt version:
realm="Repository Archiva Managed acme-company-repo Repository" host=10.1.1.2 user=my-username password=my-password
%HOMEPATH%.sbt\0.13\plugins\credentials.sbt to link the credentials from
sbt 0.13 to common file:
credentials += Credentials(Path.userHome / ".sbt" / "credentials.sbt")
You must create a
credentials.sbt file on all sbt versions you’re using.
That’s all! You can start repo’ing away!
If this was helpful in any way, please leave a comment. Very interested to know how we may improve and what we’re going ok. Thanks!