We're hiring!

We're actively seeking designers and developers for all three of our locations.

Serving Static Assets with DropWizard

Over the last few months, I’ve had the opportunity to do a lot of work with DropWizard, an awesome Java web framework for developing RESTful web services.

I was recently prototyping a small application, and I wanted to serve static files directly from DropWizard. While this isn’t what DropWizard is primarily designed to do, I didn’t want to go through the process of setting up another web server just to serve static assets for a prototype. While DropWizard has some out-of-the-box support for serving static assets, I found the documentation surrounding it to be incomplete and confusing. It actually took me a couple hours of debugging to figure out how to do exactly what I wanted, So I thought I would document what I learned here.

My end goal was to serve a small single page JavaScript app on the root of my DropWizard application, while having my DropWizard REST endpoints available at /api. The limited documentation around serving assets in DropWizard suggest that setting up an AssetsBundle for / and changing the application context path in your config file should be enough to achieve this, but that did not work for me. I had to do the following steps: Read More »

Posted in Java, Web Apps | Tagged | Leave a comment

Interacting with Git: Cryptic RPC Errors, HTTPS, and SSH

PC_Load_Letter_590

In my experience, working with a Git repository hosted by Gitlab, Github, or Gitorious has generally been issue free and enjoyable. Recently, however, three members of my team ran across the same cryptic RPC error when trying to push changes to a remote repository on Gitlab:

error: RPC failed; result=22, HTTP code = 411

In two cases, developers were trying to push new framework libraries (they were moderately sized, 2-9 MB). In the third case, a designer was trying to push a large batch of image assets. In all cases, the problem was caused by using the HTTPS protocol with a server configuration that disallowed individual files larger than 1 MB.

After some basic investigation (thanks Stack Overflow!), we found that using the SSH protocol with Git solved the problem. This type of issue could trip up a new user of Git, so I am going to use this post to briefly describe the problem and summarize the pros/cons of using HTTPS vs. SSH protocols to talk to remote repositories.

Read More »

Posted in Developer Tools | Tagged , , , | Leave a comment

Why Sustainable Pace Is Important

Sustainable Pace

As software developers, we work in a highly skilled industry. Our day-to day-work is extremely collaborative, very thought intensive, and down right exhausting. Burnout is prevalent among developers, and we owe it to ourselves and our coworkers to make sure we are all working at a sustainable pace.

Psychologists use the term burnout to explain feelings of exhaustion and diminished interest. Inability to concentrate, lack of restful sleep, fatigue, irritability, and negativity are all glaring symptoms. A burned out developer is an ineffective developer who is going to make mistakes. Here are three reasons why it’s best to avoid burnout and seek a sustainable pace. Read More »

Posted in Personal Optimization | Tagged | Leave a comment

Nicer C99 APIs with Designated Initializers

While working on a library for property-based testing in C, I discovered a trick that can be used to make significantly nicer library interfaces in C99: “designated initializers”. As of C99, struct literals can have their fields set by name, in any order. The C99 standard explicitly updated the behavior for how fields in struct literals are handled:

6.7.8 point 21:

“If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.” (emphasis mine)

Since memory with static storage duration is already initialized to zero, this means that in C99 we can finally depend on stack-allocated structs’ fields being set to zero, rather than garbage data from previous stack frames. This is a huge improvement! If pointers to structs are used as arguments for function calls, it also gives C99 a portable way of using optional and keyword arguments. Read More »

Posted in C & C++ | Tagged , , , | 3 Comments

SoftwareGR – Now on YouTube!

As long-time Spin readers will be aware, Atomic Object founded a non-profit trade association in 2003 called SoftwareGR. Our fall speaker series season has kicked off, and we’re very happy to announce a new experiment. We’re going to be filming several speakers and posting the videos to the SoftwareGR YouTube channel. We think our speakers do a great job and present very interesting information, we’d like to be able to share these talks with a wider audience.

For our first session, on September 23rd, Brett Hackleman presented his talk “Life in a Hardware Startup.”

We were very happy to have a full house for the presentation and a spirited Q&A session that lasted a good 30 minutes after the talk. If you weren’t able to make it, I’d highly recommend checking out this very entertaining session! If you were at the meeting and enjoyed it, I’d appreciate you sharing the link. Read More »

Posted in Evolving the Industry | Leave a comment

8 Questions to Ask before You Automate

This post is revised and republished from Carl’s blog at Crain’s Detroit Business.

Mobile phone construction conceptInnovation is not exclusively about revolutionary new products or services. Extending an existing offering or improving an internal business process can be an important form of innovation, too.

When I talk with business owners about using software to automate an existing business process, the request usually goes something like this: “We have this clunky process to do X which uses an old buggy application (or spreadsheets or email). It drives the people who do the work crazy. We’re growing and really need to automate the whole thing. Can you help?”

Of course, custom software and even automation is not always the answer. Given the cost of software development, jumping into a project too quickly can doom the hoped-for return. I always start with a few crucial questions: Read More »

Posted in Planning Your Project | Leave a comment

Turning Asynchronous Networking Inside-Out

Developing asynchronous networking applications is an interesting problem with unique challenges and no shortage of solutions for, particularly in Python. But the way you’ve traditionally had to write your code to make it work well could leave you with a codebase that, while solid, could be challenging to read or follow.

I’ll take you through a quick introduction to what asynchronous networking is, show you a callback-based asynchronous implementation using the venerable and excellent Twisted, and then finally show you how Python’s new asyncio library uses coroutines to solve the problem in a whole new way.

Read More »

Posted in Development Techniques | Tagged , , | Leave a comment

Where Does Atomic Thrive?

Atomic-Offices

In 2001, Atomic Object came to life in a small, rented workspace in an old red brick building in Grand Rapids’ Eastown neighborhood. In 2003, when Atomic was still young and very small, we moved west on Wealthy Street to the red brick building we now call AOHQ. We’ve grown a lot since then, so it was smart of us to invest in a bigger house than we needed at the time. Turns out, the Uptown neighborhood suits us just fine.

In July 2012, we opened our Detroit office in another old, red brick building. And in September 2013, we hung the Atomic shingle out in Ann Arbor — in, you guessed it, a red brick building.

Atomic has chosen to locate our offices on the fringe of downtown in two larger Michigan cities (Grand Rapids and Detroit) and the center of a smaller scale city (Ann Arbor), where older, red brick commercial buildings are more likely to be the workplace options in stock. Read More »

Posted in Culture | Leave a comment

AngularJS: Adding One Resolve to All Routes

$routeProvider doesn’t come with the functionality to include a resolve in every single route on an application. But universal resolves can be added in using angular.extend(), an angular method that copies one object into another.

A quick refresher on resolves in Angular routes: a resolve is a dependency that should be injected into the controller for a route. The main difference between using a resolve and just requiring the dependency in the controller is that promises in resolves are completed before Angular renders the controller. If there are any errors in completing the promise, the $routeChangeError event triggers. Resolves take the complexity of completing a promise and checking for errors out of the controller itself. (You can read more on $routeProvider and resolves in the Angular docs.)

Read More »

Posted in Web Apps | Tagged , | Leave a comment

Simple Flow Control Made Easy

We are currently working on a product that utilizes a long-range and low-bandwidth network. Moreover, the devices that are being communicated with are severely limited with regard to memory availability and CPU cycles. Given these constraints, it’s important that the network and devices are not overwhelmed with traffic.

Recently, we encountered a acute problem where the network and devices could easily be overwhelmed if they are powered on and join the network at approximately the same time.

Problem

When the devices join they communicate with a server, informing it that it has just joined and that it needs to be configured (name, time, etc.). It will continue to send these configuration requests at a steady rate until it receives all of the necessary configuration information. The problem is that the server would gladly respond to every request, even if the information it is sending is duplicated.

We had to make sure that duplicate messages were dropped within a certain time period. Read More »

Posted in Java | Tagged | Leave a comment