Java

Supported Tools and Versions

Solano CI supports Java. Supported implementations include:

  • java-6-openjdk
  • java-7-openjdk
  • java-7-oracle
  • java-8-openjdk
  • java-8-oracle

Supported build systems include:

  • Ant
  • Maven 2
  • Maven 3 (3.0, 3.1, 3.2, 3.3)
  • Gradle (1.6, 1.9, 1.11, 1.12, 2.0, 2.4)

Configuration

You configure your tests and their environment in a file called solano.yml. This configuration file is in YAML. It should be in your repository at the root of the directory tree. A simple example might look like this:

java:
  java_version: java-7-openjdk
  maven_version: '3.3.3'	# See our Java documentation for versions
tests:
  - mvn verify

Also it is possible to customize test command name using name key:

tests:
  - name: Java test example
    command: mvn verify

You can see a sample application using this configuration here:

https://github.com/solanolabs/spring-mvc-showcase/tree/no-junit-collection

Dependency Caching

Solano CI’s built-in dependency cache works with Maven and Gradle repository caches, as well as the Android SDK. See Caching Dependencies for more details.

Maven

To enable caching for Maven, add a cache section to your solano.yml.:

cache:
  key_paths:     # Define the files Solano will use to determine when to rebuild your cache
  - pom.xml
  save_paths:    # Define the paths to save into the cache
  - HOME/.m2     # Make sure to include the whole .m2 directory.  Also note it's "HOME", not "$HOME"

You can see a sample application using Maven caching here:

https://github.com/solanolabs/spring-mvc-showcase/tree/cache-mvn

Gradle

To enable caching for Gradle:

cache:
  key_paths:     # Define the files Solano will use to determine when to rebuild your cache
  - build.gradle
  save_paths:    # Define the paths to save into the cache
  - .gradle      # Relative to the repo
  - HOME/.gradle

Android SDK

To enable caching for Android SDK:

cache:
  key_paths:        # Define the files Solano will use to determine when to rebuild your cache
  - sdk-install.sh  # Script that defines required packages and installs them if they are not already installed
  save_paths:       # Define the paths to save into the cache
  - HOME/android-sdk-linux
  - HOME/.android

Parallel JUnit

See JUnit for more information on how to set up JUnit result collection for a single command run with no automatic task distribution.

If your JUnit-XML-compatible build needs to be distributed across workers, you can set a file pattern to enable our test enumerator:

java:
  java_version: java-6-openjdk
tests:
  - type: junit
    mode: parallel
    output: exit-status
    files:
    - include: 'test/*Test.java'
    command: "bin/solano-runner" 
    report_files: 
    - "target/surefire-reports/*.xml"

This configuration will use the Ruby-glob include pattern to match all .java files ending with Test.java, under test/. Solano CI will distribute batches of tests across the workers assigned to your build. For each batch, it will invoke the shell command listed under command with the test class files it should execute.

For example, say there are the following tests:

test/ATest.java
     BTest.java
     CTest.java
     DTest.java

Solano CI will enumerate these files and split them into batches. Assuming 2 batches, the following command lines will run:

bin/solano-runner test/ATest.java test/BTest.java
bin/solano-runner test/CTest.java test/DTest.java

The bin/solano-runner script actually executes the tests, in this case by constructing a mvn test commandline.

#!/usr/bin/env ruby
 
require 'optparse'
 
options = {}
OptionParser.new do |opts|
  opts.banner = "Usage: #{$0} [options]"
 
  opts.on("-d PREFIX", String, "Prefix") do |v|
    options[:prefix] = v
  end
end.parse!
 
classes = ARGV.map{|f| File.basename(f).split('.')[0]}
cmd = "("
cmd += "cd #{options[:prefix]} && " if options[:prefix]
cmd += "mvn -Dtest=#{classes.join(",")} test"
cmd += ")"
 
puts cmd
 
system(cmd)

You can use whatever runner that works for you, and whatever framework you desire, as long as it will produce an XML file for each of the test files supplied to it as arguments.

When each batch completes, the JUnit XML that’s generated will be captured from the configured report path, and processed to produce per-class test results, which will be reported back to the Solano UI.

Please contact us at support@solanolabs.com if you’re interested in parallel JVM test execution.

Android

Solano CI supports testing Android applications, with the necessary 32-bit libraries already installed on Solano worker images. See the GitHub Android app as one of our Example Repositories. Contact support@solanolabs.com with any questions about Android support.

The $ANDROID_HOME environmental variable may need to be set for each hook and test as they each run in separate processes.

hooks:
  pre_setup: export ANDROID_HOME=$HOME/android-sdk-linux && solano-pre_setup.sh
tests:
  - export ANDROID_HOME=$HOME/android-sdk-linux && ./gradlew -i test

Java Cryptography Extensions

By default, Solano CI does not install the JCE policy files required for the Java Cryptography Extensions due to licensing restrictions. If sudo support is enabled for your account, you can install these extensions for your build.

First, download the JCE policy files, if you are legally entitled to do so. For Java 8, these files are available from Oracle. You can then either download the ZIP file and add it to your repository or put it somewhere where the worker can download it in a setup hook.

You should then configure your pre_setup hook script to unpack the ZIP file and copy the jar files in the archive to $JAVA_HOME/jre/lib/security/. For instance if you check in the ZIP file as dependencies/jce_policy-8.zip, you could add the following shell script fragment to your setup hook:

set -e
cp dependencies/jce_policy-8.zip /tmp
cd /tmp
unzip jce_policy-8.zip
sudo -n -E cp UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jre/lib/security/
cd $TDDIUM_REPO_ROOT                # Reset working directory