Earlier this year, while working on a project for TRIOLOGY GmbH, I once again used maven to write a version name into an application, using the mechanism described in my post Maven: Create a simple build number. As a more sophisticated version name was required for this project, we expanded it by a time stamp, SCM information (branch and commit), build number and a also created a special name for releases. You can find a how-to here – Version names with Maven: Creating the version name – which is the first part of a small series of blog posts on this topic.
The second part shows how the version name can be read from within the application. While writing the examples for the post, I wondered how many times I must have implemeted reading a version name from a file in Java. Way too often! So I decided that this would be the very last time I had to do it, and extracted the logic into a small library: versionName, availble on GitHub. What it does and how to use it is described in the second part of the post: Version names with Maven: Reading the version name.
Hopefully, this will be useful for someone else. Funny enough, in the new project I’m on, I’m about to reuse it once again. I’m glad I don’t have to write it again. Here’s to reusability 🍺
make sure to back up you instance before you continue: rhc snapshot save -a <application name>--filepath <backup destination>
or ssh <UID>@<application name>-<yourAccount>.rhcloud.com 'snapshot' > sonar.tar.gz
SonarQube will update it’s database during the process.
If you followed this post to set up your SonarQube instance and therefore use an SSH tunnel to access the SonarQube database, note that you can now get rid of this workaround. From SonarQube 5.2 the analyses can be run without direct contact to the database.
That is, you can also remove the database connection from your the configuration of the SonarQube plugin in jenkins.
Install new SonarQube instance
To install SonarQube 5.2, execute the following steps on your machine:
Branch Specifier (blank for 'any'): origin/master Build Triggers: Tick Build when a change is pushed to GitHub Build Environment: Tick Prepare SonarQube Scanner environment Build | Execute Shell
# Start the actual build
mvn clean package $SONAR_MAVEN_GOAL --settings $OPENSHIFT_DATA_DIR/.m2/settings.xml -Dsonar.host.url=$SONAR_HOST_URL
I’d also recommend the following actions Post-build Actions| Add post-build action| Publish JUnit test result report Test report XMLs=target/surefire-reports/TEST-.xml* Post-build Actions| Add post-build action| E-mail Notification Recipients=<your email address>
Finally, press Save and start you first build. Check Jenkins console output for errors. If everything succeeds you should see the result of the project’s analysis on SonarQube’s dashboard.
At the time of writing OpenShift features Maven 3.0.4 and OpenJDK Server 1.7.0_85. Why would you want to change those? Best example is a Java8 project to be build on Jenkins. Can we just advise Jenkins to download the newest Oracle JDK and we’re good to go? Nope, it’s not that simple on OpenShift! Jenkins does download the new JDK, sets the JAVA_HOME variable and the correct PATH, but maven is always going to use the stock JDK. Why? Running this command provides the answer
The stock maven is setting its own environment variables that cannot be overridden by Jenkins!
So, in order to exchange the JDK, we need to exchange maven first.
SSH to the machines where your builds are executed (e.g. your slave node). The following example show what to do for maven 3.3.3:
tar -xvf apache-maven-3.3.3-bin.tar.gz
Edit maven config
Add the following to the <settings> tag (replace <UID> by your OpenShift UID first)
Set Environment variables PATH=$OPENSHIFT_DATA_DIR/maven/apache-maven-3.3.3/bin:$PATH M2_HOME=$OPENSHIFT_DATA_DIR/maven/apache-maven-3.3.3
And that’s it, your builds are now running on the custom maven!
This allows for using a specific JDK in Jenkins. You could just choose a specific JDK via Jenkins console. This is comfortable, but has one disadvantage: It takes a lot of memory (approx. 600MB per JDK), because the JDK is stored twice – compressed in cache to be sent to slave and again uncompressed to be used on the master. If you got enough memory, you’re done here.
However, In case you’re running a small gear with only 1GB of memory, you might want to save a bit of your precious memory. The following example shows how to do so for JDK 8 update 51 build 16.
wget --no-check-certificate --no-cookies --header &quot;Cookie: oraclelicense=accept-securebackup-cookie&quot; http://download.oracle.com/otn-pub/java/jdk/8u51-b16/jdk-8u51-linux-x64.tar.gz
tar -xvf jdk-8u51-linux-x64.tar.gz
This post showed how to build GitHub projects with Jenkins, Maven and SonarQube 4 on OpenShift. For starters, it used the Jenkins master node for running build jobs. However, when running on a small gear, the master node might run out of memory pretty fast, resulting in a reboot of the node during builds.
In order to resolve this issue, there are two options:
limitting the memory of the build or
running the build on a slave node.
As spawning additional nodes is easy in a PaaS context such as OpenShift and provides a better performance than running builds with small memory, the slave solution seems to be the better approach.
This post shows how.
Create new DYI app as a slave node (a how-to can be found here), name the node e.g. slave
Set the following values: Remote FS root:/app-root/data folder on slave. Typically this is /var/lib/openshift/<slave's UID>/app-root/data/jenkins, you can find out by SSHing to the slave node and calling
Labels: Some label to use within builds to refer the node, e.g. OS Slave #1 Host: the slave’s hostname, e.g. slave-<youraccount>.rhcloud.com
Add Credentials username: <slave's UID> Private Key File:Path to a private key file that is authorized for your OpenShift account. In the first post this path was used: /var/lib/openshift/<UID of your jenkins>/app-root/data/git-ssh/id_rsa. Note: $OPENSHIFT_DATA_DIR seems not to work here.
BTW: You can change the credentials any time later via this URL
As the different cartridges (jenkins and DIY) have different environment variables for their local IP addresses ($OPENSHIFT_JENKINS_IP vs $OPENSHIFT_DIY_IP) we’ll have to improvise at this point. There are two options: Either
Replace all occurrences of $OPENSHIFT_JENKINS_IP
In all builds and in
After finishing the migration from Actionbarsherlock to appcompat described in the first Post on modernizing android UIs, it turns out there are even more things to modernize in terms of android UIs.
Tabs and design support library
If you used Tabs within the ActionBar, after migrating to appcompat-v7 API 22 you might recognize a warning, that tells you that they are now deprecated.
In order to modernize those, you should use the design support library that was added to the Android SDK with API level 22. Similar to the appcompat -v7, the design support library provides backports of material design components of Android lollipop (5.x) for older versions of Android.
Here’s the steps that rid you of the deprecation warning
Add the design library to your eclipse workspace and link it with your project in pretty much the same way as appcompat described in the first Post. The library can be found on the following path: <sdkdir>/extras/android/support/design.
Import it into eclipse as Existing Android Code Into Workspace, change the build target to level 22, and link the appcompat project with it.
Once you’re done with this and have the design support library up an running, you could modernize your app by using more of the library’s features like navigation drawers, floating labels and buttons, snackbars, collapsing toolsbars, etc. See this blog post for more features.
The screenshots bellow show a before-after comparison – deprecated tabs vs material design tabs.
Tabs: design support library, API-22
Tabs: AppCompat-v7, API-22, deprecated
Checkboxes to switches
Android API level 14 introduces the switch component, that according to google should be used when only one option is available. For API levels < 14 there’s no such thing as switches. So we’ll have to rely on checkboxes there. Here’s how to replace checkbox preferences by switches for devices running API level 14 and above
However, If you want to keep compatibility with API levels < 14, you’re only choice is to keep redundant copies of the same preferences.xml in
res/xml/ that contains the preferences with CheckBoxPreferences and
res/xml-v14/ that contains the same file with SwitchPreferences.
Another before-after comparison is shown bellow – checkboxes vs switches.
Preferences: AppCompat-v7, with checkboxes
AppCompat-v7, API-22 with switches
Using Action Buttons
Action Buttons are icons that realize the most important actions on the actionBar if there is enough room to display them. These could have been used in Actionbarsherlock already, but if you still didn’t modernized them then it’s about time 🙂
One reason for not using action buttons might be that you don’t have suitable icons. Here’s the solution: Google provides a huge amount of material design icons under open source (CC-BY) license. They can be found on this site, or you can just clone their git repository.
So it’s as easy as that
Choose proper icons for your actions and copy them to your res/drawable-xyz folders