Maven, Ant and sbt, how to pull from a local SSL repo?
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:
AdoptOpenJDK\jdk-8.0.252-hotspot\jre\lib\security\cacerts
AdoptOpenJDK\jdk-11.0.6.10\lib\security\cacerts
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
Great! Keytool
is working so let’s convert the certificate you have for your Certificate Authority ca_key.crt
and convert it to der
.
# 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.
Build Tools
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 acme-company-repo
.
Maven
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 %HOMEPATH%\.m2\settings.xml
:
<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
As you probably know Apache Ant uses Apache Ivy to support repository management.
For Ivy we’re going to use 3 files, plus build.xml:
1) ivy.xml
– list dependencies
2) build.xml
– build file with “target” for ivy to get the dependencies
3) ivysettings.xml
– define format on how dependencies are stored
4) %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 ./lib-test
.
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.
sbt
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!