Java Sound on a Raspberry Pi with OpenJDK

try(InputStream inputStream = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream("beep.wav"));
    AudioInputStream audioIn = AudioSystem.getAudioInputStream(inputStream)) {
    AudioFormat format = audioIn.getFormat();
    DataLine.Info info = new DataLine.Info(Clip.class, format);
    Clip clip = (Clip) AudioSystem.getLine(info);;
    Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException  e1) {
    log.error("Error playing sound.", e1);


 at org.classpath.icedtea.pulseaudio.PulseAudioMixer.openImpl(
 at org.classpath.icedtea.pulseaudio.PulseAudioMixer.openLocal(
 at org.classpath.icedtea.pulseaudio.PulseAudioMixer.openLocal(


I was pretty bummed when my sound stopped playing on my Raspberry Pi when I switched to OpenJDK 8 after originally using Oracle JDK 8.

Editing the for the OpenJDK solved my problem.

sudo vim /etc/java-8-openjdk/


Comment out the icedtea classpath configs:



Remove the comments from the sun classpath configs:


Problem solved.

SaltStack – Open an reverse SSH tunnel to a Raspberry Pi minion from the salt-master in AWS

Executing salt modules and states on minions is the normal way to interact with a minion, but sometimes it is a lot faster to manage a remote machine with a terminal shell over ssh. If that machine is behind a NAT, then it gets more difficult to ssh to that box, but if you control the salt master then you can setup a reverse SSH tunnel to the minion. Here’s how I did it from an AWS Lightsail salt-master and a Raspberry Pi without touching the minion except to set it up as a salt minion to my master. At some point I will likely turn this into a salt state so it can executed faster.

// It'd be better security-wise if you used a separate pivot machine instead of the salt master
// Generate an ssh key pair for a user on your salt-master

// Copy your ssh public key to the salt-master file root
 sudo mkdir /srv/salt/ssh_keys
 sudo cp /home/ubuntu/.ssh/ /srv/salt/ssh_keys/

// Create a new, limited user on your salt-master
// Ideally you would lock this user down as much as possible, 
// but still allow it to ssh to the salt-master and open up a reverse ssh tunnel.
 sudo useradd -m sshtunnel -s /bin/bash

// Generate ssh keys for sshtunnel
 sudo ssh-keygen -f sshtunnel

// Copy the key to your salt file root
 sudo cp sshtunnel /srv/salt/ssh_keys/sshtunnel.id_rsa

// Add they public key in to authorized_keys file
 sudo cp /home/sshtunnel/.ssh/authorized_keys
 sudo chown -R sshtunnel:sshtunnel /home/sshtunnel/.ssh

// Add your salt-master user's public ssh key to the 
// minion's /home/pi/.ssh/authorized_keys
 sudo salt minion01 ssh.set_auth_key_from_file pi salt://ssh_keys/

// Place salt master fingerprint in /home/pi/.ssh/known_hosts
 sudo salt minion01 ssh.set_known_host pi

// Generate a md5 sum of /srv/salt/ssh_keys/sshtunnel.id_rsa because 
// you'll need it when placing the file on the minion in the next command
 sudo md5sum /srv/salt/ssh_keys/sshtunnel.id_rsa

// Place ssh key from the master's /home/sshtunnel/.ssh/id_rsa on 
// the minion at /home/pi/.ssh/id_rsa
 sudo salt minion01 file.manage_file /home/pi/.ssh/id_rsa '' '{}' salt://ssh_keys/sshtunnel.id_rsa '{hash_type: 'md5', 'hsum': ''}' pi pi '600' base ''

//////////   MAKE THE CONNECTION ////////////////
// Open SSH Tunnel from the minion to the master with a port forward
 sudo salt minion01 runas=pi 'ssh -f -R 7000:localhost:22 sleep 30' --async
// Connect from the master to the minion on the local port that was opened
 ssh pi@localhost -p 7000

// You are now connected to the minion and can manage and debug things faster
// Once you quit the ssh session, the minion->master ssh session will close

// Cleanup to avoid giving minions access to the master
// Remove ssh key from /home/pi/.ssh/id_rsa
 sudo salt minion01 file.remove /home/pi/.ssh/id_rsa

Pi4J – ADC MCP3008 – SPI – Sensor Reader Example


import java.nio.ByteBuffer;

public class SpiMCP3008 {

    public static SpiDevice spi = null;
    public static byte INIT_CMD = (byte) 0xD0; // 11010000

    public static void main(String args[]) throws InterruptedException, IOException {
        System.out.println("<--Pi4J--> SPI test program using MCP3008 AtoD Chip");

        spi = SpiFactory.getInstance(SpiChannel.CS0,
                                     SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
                                     SpiDevice.DEFAULT_SPI_MODE); // default spi mode 0

        while(true) {
            read(0); // Read channel 1
			read(1); // Read channel 2

    public static void read(int channel) throws IOException {
        // 10-bit ADC MCP3008
        byte packet[] = new byte[3];
        packet[0] = 0x01;  // INIT_CMD;  // address byte
        packet[1] = (byte) ((0x08 + channel) << 4);  // singleEnded + channel
        packet[2] = 0x00;
        byte[] result = spi.write(packet);
        System.out.println( ((result[1] & 0x03 ) << 8) | (result[2] & 0xff) );

Pi4J – DAC MCP4725 – I2C Example – Variable Voltage for a SyRen Motor Controller



public class I2CTest {

    public static void main(String[] args) throws Exception {

        final I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);

        MotorController motorController = new MotorController(bus);

        while (true) {


    public static class MotorController {

        private I2CDevice device;

	int REG_WRITEDAC = 0x40;
        int REG_WRITEDACEEPROM = 0x60;

        public MotorController(I2CBus bus) throws IOException {
            device = bus.getDevice(0x62); // MCP4725

        public void write(int voltage) throws IOException {
            // 12-bit DAC
	    if (voltage > 4095) {
                voltage = 4095;
            if (voltage < 0) {
                voltage = 0;
            System.out.println("Setting voltage to: " + voltage);
            // Value needs to be left-shifted four bytes for the MCP4725
            byte[] bytes = {(byte)((voltage >> 4) & 0xFF),(byte)((voltage << 4) & 0xFF)};
            device.write(REG_WRITEDACEEPROM, bytes, 0, 2);

        public int read() throws IOException {
            byte[] buf = new byte[256];
            int res =, buf, 0, 6);
            return 0;



Throttled Producers and Consumers in Java

BlockingQueue queue = new ArrayBlockingQueue<>(QUEUE_MAXIMUM_SIZE);

producers:  queue.put(dbObject);

consumers: while (RUNNING) {  DBObject dbObject = queue.poll(1, TimeUnit.SECONDS); ...

When transferring large volumes of data from one type of database (Mongo for example), to another (DynamoDB), the fastest way is to do things in parallel. Reading from one Mongo cursor from one Mongo server in the cluster gives you limited performance. Writing to DynamoDB on one thread maxes out quickly to something like 100/s. I ended up creating many threads to read from Mongo in parallel on defined partitions to utilize all of the shards and replica sets in the cluster. I had these threads put items on the queue. Setting a max size on the BlockingQueue would throttle my reads to not flood the consumers and run out of memory. The consumers would read from the queue and eventually be told to stop when all of the producers were done. This model was very performant and easy to monitor. By monitoring the size of the queue, I could see if the consumers or producers were working faster. With the BlockingQueue, the producers were not allowed to out-pace the consumers. The consumers didn’t have any problems with this though since DynamoDB is way more scalable than Mongo.

AWS DynamoDB map object to Base64 encoded gzipped JSON in Java

Annotation in a DynamoDBTable class:
    private Pojo pojo;

public static class PojoMarshaller extends GzipJsonMarshaller<Pojo> { }


import com.fasterxml.jackson.databind.*;
import org.apache.commons.codec.binary.Base64;

import java.nio.ByteBuffer;

import static com.amazonaws.util.Throwables.failure;

public class GzipJsonMarshaller<T extends Object> implements DynamoDBMarshaller<T> {

    private static final ObjectMapper mapper = new ObjectMapper();
    private static final ObjectWriter writer = mapper.writer();

    public String marshall(T obj) {
        try {
            String plainJsonString = writer.writeValueAsString(obj);
            byte[] binaryBytes = compressString(plainJsonString).array();
            String base64BinaryString = Base64.encodeBase64String(binaryBytes);
            return base64BinaryString;
        } catch (Exception e) {
            throw failure(e, "Unable to marshall the instance of " + obj.getClass() + "into a string");

    public T unmarshall(Class<T> clazz, String base64BinaryString) {
        try {
            byte[] binaryBytes = Base64.decodeBase64(base64BinaryString);
            String plainJsonString = uncompressString(ByteBuffer.wrap(binaryBytes));
            return mapper.readValue(plainJsonString, clazz);
        } catch (Exception e) {
            throw failure(e, "Unable to unmarshall the string " + base64BinaryString + "into " + clazz);

    public static ByteBuffer compressString(String input) throws IOException {
        ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutput = new GZIPOutputStream(byteArrayOutput);
        byte[] compressedBytes = byteArrayOutput.toByteArray();
        ByteBuffer buffer = ByteBuffer.wrap(compressedBytes);
        return buffer;

    public static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream byteArrayInput = new ByteArrayInputStream(bytes);
        GZIPInputStream gzipInput = new GZIPInputStream(byteArrayInput);
        ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
        IOUtils.copy(gzipInput, byteArrayOutput);
        return new String(byteArrayOutput.toByteArray(), "UTF-8");


Convert Mongo DBObject to POJO with Jongo

import org.jongo.ResultHandler;
import org.jongo.bson.Bson;
import org.jongo.bson.BsonDocument;
import org.jongo.marshall.Unmarshaller;
import org.jongo.marshall.jackson.JacksonEngine;
import org.jongo.marshall.jackson.configuration.Mapping;


    public Pojo getPojo(DBObject dbObject) {
        JacksonEngine engine = new JacksonEngine(new Mapping.Builder().build());
        ResultHandler<Pojo> handler = new UnmarshallingResultHandler<>(engine, Pojo.class); 
        Pojo pojo =;
        return pojo;

    public static class UnmarshallingResultHandler<T> implements ResultHandler<T> {
        private final Unmarshaller unmarshaller;
        private final Class<T> clazz;
        public UnmarshallingResultHandler(Unmarshaller unmarshaller, Class<T> clazz) {
            this.unmarshaller = unmarshaller;
            this.clazz = clazz;
        public T map(DBObject result) {
            BsonDocument bsonDocument = Bson.createDocument(result);
            return unmarshaller.unmarshall(bsonDocument, clazz);