Problems with Xerces and Jenkins

Rationale TL;DR

Out of nowhere some Jenkins jobs decide to stop working, with errors like:

java.lang.ClassNotFoundException: org.apache.xerces.parsers.SAXParser
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
	at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:543)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
	at org.xml.sax.helpers.NewInstance.newInstance(NewInstance.java:82)
	at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:228)
Caused: org.xml.sax.SAXException: SAX2 driver class org.apache.xerces.parsers.SAXParser not found
java.lang.ClassNotFoundException: org.apache.xerces.parsers.SAXParser
	at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:230)
	at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:191)
	at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.<init>(XmlResponsesSaxParser.java:120)
Caused: com.amazonaws.SdkClientException: Couldn't initialize a SAX driver to create an XMLReader
	at com.amazonaws.services.s3.model.transform.XmlResponsesSaxParser.<init>(XmlResponsesSaxParser.java:123)
	at com.amazonaws.services.s3.model.transform.Unmarshallers$InitiateMultipartUploadResultUnmarshaller.unmarshall(Unmarshallers.java:315)
	at 

Solution

The issue here is that some pluing (usually the S3 or plugin-aws require the xerces jar available. There are two actions to fix this issue:

  • First one is to tell Jenkins to use its internal SAX implementation. To do that add [1] to the Jenkins startup flags (on Debian/Ubuntu, edit /etc/defaults/jenkins)
  • Second one is to download xerces 2.9.0 and put it on the plugin classpath (i.e. /var/lib/jenkins/pipeline-aws/WEB-INF/lib)

[1] -Dorg.xml.sax.driver=com.sun.org.apache.xerces.internal.parsers.SAXParser

Configure kubectl with a cluster

Rationale TL;DR

You have created a cluster with kops (or maybe bare-metal) and you want to use those same credentials elsewhere (like with a new laptop, in your CI/CD…).

Requirements

You need the API url, a user and a password. Because we assumed kops (or bare metal) deploys, the user we have is probably an admin user. Doesn’t matter right now.

First, we need to configure the credentials. We need to name those credentials so we can refer to them afterwards:

kubectl config set-credentials kubernetes_user/user.kubernetes.com --username=kubernetes_user --password=kubernetes_password

Where kubernetes_user/user.kubernetes.com is the name we decided to give to those credentials. This is totally arbitrary name.

Moving on, we need to set up a cluster. Like we did before:

kubectl config set-cluster kubernetes_cluster/cluster.kubernetes.com --insecure-skip-tls-verify=true --server=https://cluster.kubernetes.com

We named that cluster cluster.kubernetes.com.

Finally, we need to link those credentials with the cluster:

kubectl config set-context default/context.kubernetes.com/kubernetes_user --user=kubernetes_user/user.kubernetes.com --namespace=default --cluster=kubernetes_cluster/cluster.kubernetes.com

We’re naming our context default/context.kubernetes.com/kubernetes_user, using the user and clusters we declared before.

List only the commits of a given branch

Rationale TL;DR

Imagine that you have a git branch and you want to list only the commits of that branch, avoiding commits from other branches, merges, etc …

Doing it

In fact, it’s pretty easy to achieve. What we want is to list the commit list on a

git rev-list --all --not $(git rev-list --all ^BRANCH_NAME) | tail -r

This will reverse the list of commits on the branch BRANCH_NAME. That is really usefull if we want to cherry-pick commits from another branch, for example:

git rev-list --all --not $(git rev-list --all ^BRANCH_NAME) | tail -r | xargs -L 1 -I COMMIT git cherry-pick COMMIT