Tag Archive for: jama

“What I cannot create, I do not understand.”

Richard Feynman

Redux is pretty simple. You have action creators, actions, reducers and a store. What’s not so simple is figuring out how to put all of that together the best or most “correct” way. At least this is the problem I had with it. In order to try to gain a better understanding of the philosophy behind Redux, and to gain knowledge I could further share with my team, I decided to rewrite Redux, and to document it.

To rewrite Redux, I used a wonderful article by Lin Clark as a reference point, as well as the Redux codebase itself, and of course, the Redux docs.

You may note I’m using traditional pre-ES6 Javascript throughout this article. It’s because everyone who knows Javascript knows pre-ES6 JS, and I want to make sure I don’t lose anyone because of syntax unfamiliarity.

The Store

Redux, as is the same with any data layer, starts with a place to store information. Redux, by definition of the first principle of Redux, is a singular shared data store, described by its documentation as a “Single source of truth”, so I think I’ll start by making the store a singleton:

var store;

function getInstance() { 
 if (!store) store = createStore();
 return store;
}

function createStore() { 
 return {}; 
}

module.exports = getInstance();

The dispatcher

The next principle is that the state of the store can only change in one way: through the dispatching of actions. So let’s go ahead and write a dispatcher.

However, in order to update state in this dispatcher, we’re going to have to have state to begin with, so let’s create a simple object that contains our current state.

function createStore() { 
 var currentState = {}; 
}

Also, to dispatch an action, we need a reducer to dispatch it to. Let’s create a default one for now. A reducer receives the current state and an action and then returns a new version of the state based on what the action dictates:

function createStore() { 
 var currentState = {}; 

 var currentReducer = function(state, action) { 
  return state; 
 } 
}

This is just a default function to keep the app from crashing until we formally assign reducers, so we’re going to go ahead and just return the state as is. Essentially a “noop”.

The store is going to need a way to notify interested parties that an update has been dispatched, so let’s create an array to house subscribers:

function createStore() { 
 var currentState = {}; 
 
 var currentReducer = function(state, action) { 
  return state; 
 } 
 
 var subscribers = []; 
}

Cool! OK, now we can finally put that dispatcher together. As we said above, actions are handed to reducers along with state, and we get a new state back from the reducer. If we want to retain the original state before the change for comparison purposes, it probably makes sense to temporarily store it.

Since an action is dispatched, we can safely assume the parameter a dispatcher receives is an action.

function createStore() { 
 var currentState = {}; 

 var currentReducer = function(state, action) { 
  return state; 
 } 

 var subscribers = [];

 function dispatch(action) {
  var prevState = currentState;
 }

 return {
  dispatch: dispatch
 };
}

We also have to expose the dispatch function so it can actually be used when the store is imported. Kind of important.

So, we’ve created a reference to the old state. We now have a choice: we could either leave it to reducers to copy the state and return it, or we can do it for them. Since receiving a changed copy of the current state is part of the philosophical basis of Redux, I’m going to go ahead and just hand the reducers a copy to begin with.

function createStore() { 
 var currentState = {}; 

 var currentReducer = function(state, action) { 
  return state; 
 } 

 var subscribers = [];

 function dispatch(action) {
  var prevState = currentState;
  currentState = currentReducer(cloneDeep(currentState), action);
 }

 return {
  dispatch: dispatch
 };
}

We hand a copy of the current state and the action to the currentReducer, which uses the action to figure out what to do with the state. What is returned is a changed version of the copied state, which we then use to update the state. Also, I’m using a generic cloneDeepimplementation (in my case, I used lodash’s) to handle copying the state completely. Simply using Object.assign wouldn’t be suitable because it retains references to objects contained by the base level object properties.

Now that we have this updated state, we need to alert any part of the app that cares. That’s where the subscribers come in. We simply call to each subscribing function and hand them the current state and also the previous state, in case whoever’s subscribed wants to do delta comparisons:

function createStore() { 
 var currentState = {}; 

 var currentReducer = function(state, action) { 
  return state; 
 } 

 var subscribers = []; 

 function dispatch(action) {
  var prevState = currentState;
  currentState = currentReducer(cloneDeep(currentState), action);
  subscribers.forEach(function(subscriber){
   subscriber(currentState, prevState);
  });
 }

 return {
  dispatch: dispatch
 };
}

Of course, none of this really does any good with just that default noop reducer. What we need is the ability to add reducers, as well.

Adding Reducers

In order to develop an appropriate reducer-adding API, let’s revisit what a reducer is, and how we might expect reducers to be used.

In the Three Principles section of Redux’s documentation, we can find this philosophy:

“To specify how the state tree is transformed by actions, you write pure reducers.”

So what we want to accommodate is something that looks like a state tree, but where the properties of the state are assigned functions that purely change their state.

{ 
 stateProperty1: function(state, action) { 
  // does something with state and then returns it
 }, 
 stateProperty2: function(state, action) { 
  // same 
 }, ... 
}

Yeah, that looks about right. We want to take this state tree object and run each of its reducer functions every time an action is dispatched.

We have currentReducer defined in the scope, so let’s just create a new function and assign it to that variable. This function will take the pure reducers we passed to it in the state tree object, and run each one, returning the outcome of the function to the key it was assigned.

function createStore() { 
 var currentReducer = function(state, action) { 
  return state; 
 } ...

 function addReducers(reducers) {
  currentReducer = function(state, action) {
   var cumulativeState = {};
   
   for (key in reducers) {
    cumulativeState[key] = reducers[key](state[key], action);
   }
  
   return cumulativeState;
  }
 }
}

Something to note here: we’re only ever handing a subsection of the state to each reducer, keyed from its associated property name. This helps simplify the reducer API and also keeps us from accidentally changing other state areas of the global state. Your reducers should only be concerned with their own particular state, but that doesn’t preclude your reducers from taking advantage of other properties in the store.

As an example, think of a list of data, let’s say with a name “todoItems”. Now consider ways you might sort that data: by completed tasks, by date created, etc. You can store the way you sort that data into separate reducers (byCompleted and byCreated, for example) that contain ordered lists of IDs from the todoItems data, and associate them when you go to show them in the UI. Using this model, you can even reuse the byCreated property for other types of data aside from todoItems! This is definitely a pattern recommended in the Redux docs.

Now, this is fine if we add just one single set of reducers to the store, but in an app of any substantive size, that simply won’t be the case. So we should be able to accommodate different portions of the app adding their own reducers. And we should also try to be performant about it; that is, we shouldn’t run the same reducers twice.

// State tree 1 
{ 
 visible: function(state, action) { 
  // Manage visibility state 
 } ... 
}
// State tree 2
{ 
 visible: function(state, action) { 
  // Manage visibility state (should be the same function as above) 
 } ... 
}

In the above example, you might imagine two separate UI components having, say, a visibility reducer that manages whether something can be seen or not. Why run that same exact reducer twice? The answer is “that would be silly”. We should make sure that we collapse by key name for performance reasons, since all reducers are run each time an action is dispatched.

So keeping in mind these two important factors — ability to ad-hoc add reducers and not adding repetitive reducers — we arrive to the conclusion that we should add another scoped variable that houses all reducers added to date.

... 
function createStore() { 
 ... 
 var currentReducerSet = {};

 function addReducers(reducers) {
  currentReducerSet = Object.assign(currentReducerSet, reducers);

  currentReducer = function(state, action) {
   var cumulativeState = {};

   for (key in currentReducerSet) {
    cumulativeState[key] = currentReducerSet[key](state[key], action);
   }
 
   return cumulativeState;
  }

 }
 ...
}
...

The var currentReducerSet is combined with whatever reducers are passed, and duplicate keys are collapsed. We needn’t worry about “losing” a reducer because two reducers will both be the same if they have the same key name. Why is this?

To reiterate, a state tree is a set of key-associated pure reducer functions. A state tree property and a reducer have a 1:1 relationship. There should never be two different reducer functions associated with the same key.

This should hopefully illuminate for you exactly what is expected of reducers: to be a sort of behavioral definition of a specific property. If I have a “loading” property, what I’m saying with my reducer is that “this loading property should respond to this set specific actions in these particular ways”. I can either directly specify whether something is loading — think action name “START_LOADING — or I can use it to increment the number of things that are loading by having it respond to action names of actions that I know are asynchronous, such as for instance LOAD_REMOTE_ITEMS_BEGIN” and “LOAD_REMOTE_ITEMS_END”.

Let’s fulfill a few more requirements of this API. We need to be able to add and remove subscribers. Easy:

function createStore() { 
 var subscribers = []; 
 ... 

 function subscribe(fn) { 
  subscribers.push(fn); 
 }

 function unsubscribe(fn) {
  subscribers.splice(subscribers.indexOf(fn), 1);
 }

 return {
  ...
  subscribe: subscribe,
  unsubscribe: unsubscribe
 };
}

And we need to be able to provide the state when someone asks for it. And we should provide it in a safe way, so we’re going to only provide a copy of it. As above, we’re using a cloneDeep function to handle this so someone can’t accidentally mutate the original state, because in Javascript, as we know, if someone changes the value of a reference in the state object, it will change the store state.

function createStore() { 
 ... 

 function getState() { 
  return cloneDeep(currentState); 
 }

 return {
  ...
  getState: getState
 };
}

And that’s it for creating Redux! At this point, you should have everything you need to be able to have your app handle actions and mutate state in a stable way, the core fundamental ideas behind Redux.

Let’s take a look at the whole thing (with the lodash library):

var _ = require('lodash'); 
var globalStore;

function getInstance(){ 
 if (!globalStore) globalStore = createStore();
 return globalStore;
}

function createStore() { 
 var currentState = {}; 
 var subscribers = []; 
 var currentReducerSet = {}; 
 currentReducer = function(state, action) { 
  return state; 
 };
 
 function dispatch(action) {
  var prevState = currentState;
  currentState = currentReducer(_.cloneDeep(currentState), action);
  subscribers.forEach(function(subscriber){
   subscriber(currentState, prevState);
  });
 }
 
 function addReducers(reducers) {
  currentReducerSet = _.assign(currentReducerSet, reducers);
  currentReducer = function(state, action) {
   var ret = {};
   _.each(currentReducerSet, function(reducer, key) {
    ret[key] = reducer(state[key], action);
   });
   return ret;
  };
 }
	
 function subscribe(fn) {
  subscribers.push(fn);
 }
	
 function unsubscribe(fn) {
  subscribers.splice(subscribers.indexOf(fn), 1);
 }
	
 function getState() {
  return _.cloneDeep(currentState);
 }
	
 return {
  addReducers,
  dispatch,
  subscribe,
  unsubscribe,
  getState
 };
}
module.exports = getInstance();

So what did we learn by rewriting Redux?

We learned a few valuable things in this experience:

  1. We must protect and stabilize the state of the store. The only way a user should be able to mutate state is through actions.
  2. Reducers are pure functions in a state tree. Your app’s state properties are each represented by a function that provides updates to their state. Each reducer is unique to each state property and vice versa.
  3. The store is singular and contains the entire state of the app. When we use it this way, we can track each and every change to the state of the app.
  4. Reducers can be thought of as behavioral definitions of state tree properties.

Bonus section: a React adapter

Having the store is nice, but you’re probably going to want to use it with a framework. React is an obvious choice, as Redux was created to implement Flux, a core principle data architecture of React. So let’s do that too!

You know what would be cool? Making it a higher-order component, or HOC as you’ll sometimes see them called. We pass an HOC a component, and it creates a new component out of it. And it is also able to be infinitely nested, that is, HOCs should be able to be nested within each other and still function appropriately. So let’s start with that basis:

Note: Going to switch to ES6 now, because it provides us with class extension, which we’ll need to be able to extend React.Component.

import React from 'react';
export default function StoreContainer(Component, reducers) { 
	return class extends React.Component { }
}

When we use StoreContainer, we pass in the Component class — either created with React.createClass or React.Component — as the first parameter, and then a reducer state tree like the one we created up above:

// Example of StoreContainer usage 
import StoreContainer from 'StoreContainer'; 
import { myReducer1, myReducer2 } from 'MyReducers';

StoreContainer(MyComponent, { 
 myReducer1, 
 myReducer2
});

Cool. So now we have a class being created and receiving the original component class and an object containing property-mapped reducers.

So, in order to actually make this component work, we’re going to have to do a few bookkeeping tasks:

  1. Get the initial store state
  2. Bind a subscriber to the component’s setState method
  3. Add the reducers to the store

We can bootstrap these tasks in the constructor lifecycle method of the Component. So let’s start with getting the initial state.

... 
export default function StoreContainer(Component, reducers) { 
 return class extends React.Component { 
 
  constructor() { 
   super(props); 
   // We have to call this to create the initial React 
   // component and get a `this` value to work with 
   this.state = store.getState(); 
  } 

 } 
}

Next, we want to subscribe the component’s setState method to the store. This makes the most sense because setting state on the component will then set off the top-down changes the component will broadcast, as we’d want in the Flux model.

We can’t, however, simply send this.setState to the subscribe method of the store — their parameters don’t line up. The store wants to send new and old state, and the setState method only accepts a function as the second parameter.

So to solve this, we’ll just create a marshalling function to handle it:

... 
import store from './Store';

function subscriber(currentState, previousState) { 
 this.setState(currentState); 
}

export default function StoreContainer(Component, reducers) { 
 return class extends React.Component { 

  constructor() { 
   ... 
   this.instSubscriber = subscriber.bind(this); 
   store.subscribe(this.instSubscriber);
  }

  componentWillUnmount() {
   store.unsubscribe(this.instSubscriber);
  }
 }
}
...

Since the store is a singleton, we can just import that in and call on its API directly.

Why do we have to keep the bound subscriber around? Because binding it returns a new function. When unmounting the component, we want to be able to unsubscribe to keep things clean. We know that the store merely looks for the function reference in its internal subscribers array and removes it, so we need to make sure we keep that reference around so we can get it back when we need to identify and remove it.

One last thing to do in the constructor: add the reducers. This is as simple as passing what we received to the HOC into the store.addReducers method:

... 
export default function StoreContainer(Component, reducers) { 
 return class extends React.Component { 
  ... 
  constructor() { 
   ... 
   store.addReducers(reducers); 
  } 
  ... 
 } 
}
...

So now we’re ready to provide the rendering of the component. This is the essence of HOCs. We take the Component we received and render it within the HOC, imbuing it with whatever properties the HOC needs to provide it:

... 
export default function StoreContainer(Component, reducers) { 
 return class extends React.Component { 
  ... 
  render() { 
   return (<Component {...this.props} {...this.state} />); 
  } 
 } 
} 			
...

We are “spreading” the properties and state of the HOC down to the Component it is wrapping. This effectively ensures that whatever properties we pass to the HOC get down to the component it wraps, a vital feature of infinitely nestable HOCs. It may or may not be wise to place the state as properties on the Component, but it worked well in my testing, and it was nice being able to access to the state through the this.props object of the Component that is wrapped, as you might expect to normally do with a React component that receives data from a parent component.

Here’s the whole shabang:

import React from 'react'; import store from './Store';
function subscriber(currentState, previousState) { 
 this.setState(currentState);
}

export default function StoreContainer(Component, reducers) {
 return class extends React.Component { 
  
  constructor(props) { 
   super(props); 
   this.state = store.getState(); 
   this.instSubscriber = subscriber.bind(this); 
   store.subscribe(this.instSubscriber);
   store.addReducers(reducers); 
  }
 
  componentWillUnmount() {
   store.unsubscribe(this.instSubscriber);
  }
  
  render() {
   return (<Component {...this.props} {...this.state} />);
  }
 }
}

Implementation of using StoreContainer:

import StoreContainer from 'StoreContainer'; 
import { myReducer } from 'MyReducers';
let MyComponent extends React.Component { 
 // My component stuff 
}
export default StoreContainer(MyComponent, { myReducer });

Implementation of using the Component that uses StoreContainer (exactly the same as normal):

import MyComponent from 'MyComponent'; 
import ReactDOM from 'react-dom';

ReactDOM.render(<MyComponent myProp=’foo’ />, document.body);

But you don’t have to define the data basis of your MyComponent immediately or in a long-lasting class definition; you could also do it more ephemerally, in implementation, and perhaps this is wiser for more generalized components:

import StoreContainer from 'StoreContainer'; 
import { myReducer } from 'MyReducers'; 
import GeneralizedComponent from 'GeneralizedComponent'; 
import ReactDOM from 'react-dom';
let StoreContainedGeneralizedComponent = StoreContainer(GeneralizedComponent, { myReducer });
ReactDOM.render(<StoreContainedGeneralizedComponent myProp='foo' />, document.body);

This has the benefit of letting parent components control certain child component properties.

Conclusion

Well, that might have been a bit exhaustive, and we may not have covered everything but my hope is that by opening up Redux and exposing its innards, as well as providing an implementation of its usage with a popular library, it’s a bit more clear how it’s expected to manage state in a safe manner.

If you’ve found anything erroneous in this article or want to give feedback, please feel free to reach out to me to let me know so I can keep this article informative and up-to-date.

I can’t believe Jama turns nine this summer! I started the company to solve a problem that frustrated me personally — the amount of time and money wasted when product teams built features nobody used. It seemed simple: connect stakeholders with engineers and get everyone on the same page. Problem solved!

While we’ve made tremendous progress and built a great team at Jama, we’re just getting started. Today’s products are driven by software, connected to the Internet and evolving rapidly. Complexity is increasing, development cycles are shrinking and the pressure is on to get it right the first time. To solve today’s product development challenges, we’ve got a lot more work to do.

Thinking back, I didn’t expect Jama would help our customers resupply the international space station, create breakthrough medical devices, build autonomous cars or ensure billions of dollars flow to the right accounts.  I wanted to help connect teams so they made fewer mistakes and find ways to scale product management best practices. But these customer stories make me the proudest of what we’ve accomplished.

So, here we are about to close our fiscal year 2016 and start a new year on May 1 (yes, we have an odd fiscal calendar, but that’s another story).  As we finish out the year, I wanted to share my thoughts on Jama’s growth and evolution.

This year was our first as a fully recurring revenue company with 100% year-over-year GAAP subscription revenue growth. The conversion from perpetual to subscription took two years and tons of hard work across the company — but it was worth it. The SaaS/subscription business model aligns us to our customers’ needs and requires that we deliver value for them every year. When they succeed, we succeed; it’s that simple. This is a strong foundation for building a company that delivers long-term value to the people that rely on its products and services.

We added over 100 new customers including NASA, United Technologies, Zoll, Eaton, John Deere, Samsung, NVIDIA and Estes. It’s exciting to see the products our customers are building. They truly are building the impossible products of the future, and that’s what our vision is all about. Working with our customers is what inspires me, and I love hearing the stories of these amazing projects that are changing the world.

This year, we doubled down on companies building connected products. Today’s complex systems are software-driven, with more options and new regulatory compliance challenges. These companies need new tools to help manage the complexity inherent in connected products, product variants and component reuse, and to achieve compliance — all while accelerating development cycles.

Jama has been preparing for this for some time. We committed a multi-million dollar investment in R&D to deliver on new capabilities to help customers innovate more efficiently. We are delivering a new Service-Oriented Architecture (SOA) multi-tier, horizontally scalable platform built on REST APIs. Translated into English, this means that Jama can scale to meet the performance needs of the world’s most complex global product development initiatives, from medical devices to spacecraft, to intricate enterprise software systems.

We also know that many of our customers require the security of an on-premises solution. We will soon be launching the next generation of Jama On-Premises. Jama’s enterprise private cloud bundles our multi-tier cloud platform, packages it for delivery behind the firewall and automatically replicates our scalable platform and auto-provisions the platform in our customers’ data centers. This is specially designed for companies that require top-secret product development protocols and an on-premises option, but includes the scalability benefits of the cloud.

Our product development team is also delivering on our feature roadmap and releasing new capabilities, including actionable traceability, which simplifies real-time requirements decomposition. And, these traceability updates will launch this Spring!growth

Jama launched solutions for the medical, semiconductor, aerospace and automotive industries, as well as Scaled Agile (SAFe™). Software drives rapid innovation in these industries, and companies must accelerate development cycles in order to compete. To be successful, it’s critical that companies manage the complexity of concurrent software and hardware development, all while achieving regulatory approval.

As we look to the future and continued growth, I am excited to share that after nine years leading Jama from startup to scale up, I have hired Scott Roth to lead Jama’s next phase of growth.

I’m excited for Scott to join Jama for several reasons. He brings fifteen years of SaaS experience including executive roles in product, marketing, sales and service. Most recently, Scott was EVP and General Manager of Return Path’s global 250-person email optimization division. Prior to Return Path, Scott spent six years in executive leadership for ExactTarget prior to and after their $2.5B acquisition by Salesforce.

Scott’s industry experience and business acumen, combined with his passion for growth, made him my ideal candidate to lead Jama.

But beyond the resume, I’ve gotten to know Scott personally. He’s warm, caring, wicked smart and brings a bias toward action. Most importantly, we share views on the importance of culture and people-first leadership that have made Jama a unique and rewarding place to work.

Hiring Scott enables me to transition into a new role as Chief Strategy Officer and Chairman, a position that will allow me to dive deeply into the company strategy, engage directly with customers and partners, and evangelize the benefits of collaboration within product development.

This is an energizing and exciting time for all of us at Jama, and I look forward to doing big things together as we execute on our vision to make possible the impossible products of the future.

At Jama, we enjoy opening our doors to different groups and organizations. We feel it’s important to give back to our community, encourage networking with peers and supporting local organizations within technology.  Most recently, we hosted the Computer Science Class from St. Mary’s Academy.  St. Mary’s Academy is a private girls school in downtown Portland focused on educating and inspiring the next generation of leaders in our community and the world.

St Marys 1

Mike Bedney, Jr. is on the faculty at the school and championed a tour of local Software Companies in downtown Portland for his Computer Science students. The intent of the tour was to showcase women in technology positions within software, their roles within our company, what they enjoy most about working in technology and provide guidance for the students that may help them in their pursuit of a technical career path.

St Marys 2

The students were able to meet 5 of our staff from all across our organization. One of our Graphic Designers, Customer Support Community Manager, Solution Architect, Quality Assurance Engineer and Talent Partner. They all have a unique story to tell about their journey into technology and excellent advice for those interested in pursing a career in this field.  Opportunities are abundant in hi tech and continue to grow exponentially as new technology continues to be developed.  We need to encourage and educate the younger generations of the diverse technical opportunities that are waiting for them.St marys Thank You

As all fast-growing software companies know, recruiting talent can be a big challenge. You’ve probably hired some of the best and brightest nation-wide and paid their moving costs, and are ready to sponsor working visas, all to keep your business innovative and moving forward.

At Jama our recruiting efforts were eased this year when we found a great source of wonderfully bright and talented software engineers in our own backyard!

In July 2015, we began participating in the PSU/PDX Cooperative Education Program (PCEP) in which PSU Computer Science students work at our office (or another local partner company’s office) in a series of defined, practical internship roles, while completing their degree. The two-year program offers a major jump-start for a CS student’s career–a phenomenal opportunity to gain exposure to practical business operations and an opportunity to grow a professional network locally and beyond. Only the most accomplished students gain acceptance to the PCEP program among a highly competitive candidate pool.

For us at Jama we appreciate working with fresh-minded, highly enthusiastic software engineers, eager and efficient, open and ready to soak in as much product knowledge as possible. We also strongly value the reoccurring semi-annual pool of candidates who continually refuel our team. PCEP interns widen our point of view as a business, add to our efficiency, and bring  a sharp eye to the status-quo-questioning team we are known for in the market.

Khaosanga, Souriya

Souriya Khaosanga started at Jama as a software engineering intern through the PSU/PDX Cooperative Education Program

Meet Souriya Khaosanga, a PCEP Intern, who completed the QA, DevOps, and Developer tracks at three different software companies in Portland over the last two years.

Souriya is enthusiastic about the intern program, and appreciates the real-world experience. “You get to work for some of the best software companies in Portland,” he said. “This is the best place you can get the essential experience you need to be successful in any software company.  In addition, participants are mentored throughout their internship. It’s like having a private tutor walk you through the inner workings of a software company. These are concepts that school will not give you and you can only gain through work experience.”

The exposure to many different methods and software languages has been invaluable, Souriya said. “Because I was changing technologies so frequently, I always found myself learning new tools, languages, etc.  I pretty much learned that in software, I’ll always need to be exploring and learning new tools.”

The biggest surprise to Souriya was the fact that he was actually contributing to each business: solving real problems, learning new concepts and checking off big ticket items during his internship.

The best part for us? Once the PCEP interns are finished with their two-year mutli-company rotation, after they graduate local companies present offers to these exceptional–and now experienced–software developers.

We were honored when Souriya joined our team. He says he was attracted to Jama because of the cutting-edge tools and methodologies we employ. “But I’d say the biggest reason for coming to Jama is the people.  Everyone I meet at Jama is the type of person I wanted to work with.  I am learning a lot from these people and it has been great for my career.”

There you have it! A total win-win for Souriya and Jama. We couldn’t be more excited to continue our partnership with the PCEP program. We found software developers in Portland and so can you!

“Engineers are relatively good at logical decisions. The problem is with the assumptions. Testing the assumptions is the most important trait of a good systems engineer. Keep the critical-to-customer requirements always in mind; everything else supports these. Must not strangle the project with many meetings. System Level cannot be the only verification approach—Need to do things right the first time (at lowest level). There are thousands of ways to fail; most have not been explored.

Dr. Steve Jolly, Systems Engineering Director for Lockheed Martin Space Systems. Assembled from material presented at the 2011 NASA PI Forum.

Leave it to the Systems Engineer responsible for overseeing NASA’s early warning alert spacecraft to sum up the worries that keep Systems Engineers up at night.

Here at Jama, we work regularly with Systems Engineers and know how comprehensive their skills and responsibilities are. Many of our customers serve as trusted advisers to Project Managers, and assist in decision making. Most must also be skilled leaders, listeners, negotiators and diplomats. As Jama Solutions Architect Cary Bryczek explains, “To be a successful systems engineer, you should be a natural problem solver and excellent communicator. You need to be able to consider multiple factors and figure out ways for all of these factors to come together and form a whole process.”

Suffice it to say that for Systems Engineers, achieving the desired state of harmonious integration is no easy undertaking:

Tall tasks:

  • Delivering on requirements while dealing with multiple interests, competing agendas and numerous constraints.

Pressure points:

  • Missing out on critical customer feedback during early development stages.
  • Optimizing systems design for integration and balance, with no system or sub-system sacrificed or favored at another’s expense.
  • Being able to accurately assess relationships among the parts of a complex system to understand where compromises in development can be made safely and efficiently without harming functionality.
  • Guaranteeing that different components produced by specialty engineers will work as a cohesive and efficient system or product.

Burning desires:

  • To be able to assess and address, in one single platform, design compatibility, requirements definition, management of projects, cost analysis, scheduling, maintenance needs, ease of operations and future systems upgrades, and to communicate with engineers, managers, suppliers and customers regarding system operations.

With Jama, Systems Engineers can turn foreboding “Twilight Zone” episodes into fearless “Quantum Leap” epics.

How so? You’re able to…

  • Identify possible errors early in the project so they can be remedied before they impact quality.
  • Gain visibility upstream to understand the business requirements being worked on and receive prompt notification of requirements changes that impact tasks.
  • Understand (and help others understand) how complex systems and products integrate and operate, how well they meet overall goals and objectives, and how they can be improved.
  • Communicate easily with the entire project team to get clarification and decisions made, regardless of location.

Read 2 Brains, 1 Product: The Builder’s Dilemma to find out how Systems Engineers can use Jama to balance disciplines and create high-performing systems and products that meet goals and objectives.

Check out other ways Jama helps business and engineering teams get and stay aligned:

How Jama Helps VPs of Sales

How Jama Helps VPs of Product

How Jama Helps QA Leads

How Jama Helps Project Managers

How Jama Helps Business Analysts

How Jama Helps Product Managers

An unfair truth: Project Managers are expected to be janitors.

When there’s a mess, the PM must finagle and finesse the problematic actions, unexpected errors and sidetracked key players back into one clean and streamlined product-building machine. We’ve said it before and we’ll say it again: No other team member has as much of an across-the-board influence on a project’s outcome.

Maintaining orderly processes through each iteration, spec and requirements change is often a messy process of sprint, slow down, stall and re-start. And that’s a frustrating diversion of resources when your work entails the following:

Tall tasks:

  • Negotiating and setting (and re-setting) expectations among stakeholders and team members, regulating processes, tracking decisions and enforcing accountability as projects evolve.

Pressure points:

  • Gathering status information from team members.
  • Summarizing information for team and program leaders, VPs of Product, VPs of Sales.
  • Identifying schedule, scope and functionality problems before they become critical.
  • Feeling confident that teams will deliver to expectations.
  • Spending too much time resolving conflict and performance issues.

Burning desires:

  • To know, to the minute, how the project and the people involved are tracking to the plan. To see potential snags in scope or time so that you can resolve them, or send up flares right away. To answer the questions, “What’s everyone doing now?” and “What should they be doing next?”

With Jama, Project Managers can turn agonizing “$64,000 Question” episodes into undaunted “Six Million Dollar Man” epics.

How so? You’re able to:

  • Capture and view all information related to projects in one location.
  • Monitor changes to requirements, track changes across different teams and notify everyone who is impacted.
  • Understand who is working on what and when it’s due to be completed.
  • Communicate easily with all involved teams to solicit clarification, approvals, feedback and decisions, regardless of location or time zone.
  • Communicate easily with the entire project team to get clarification and decisions made, regardless of location.

Read Remove Barriers, Decide Faster & Increase ROI and learn how Jama helps you keep collaborators, stakeholders, resources, time, scope and expectations all in alignment, and always in check.

Check out other ways Jama helps business and engineering teams get and stay aligned:

How Jama Helps VPs of Sales

How Jama Helps VPs of Product

How Jama Helps Systems Engineers

How Jama Helps QA Leads

How Jama Helps Business Analysts

How Jama Helps Product Managers

5126753753_3456846b00_b

Jama co-founders Eric, Derwyn and Sean collaborate with the dev team in one of our earlier offices

In the early days, there were three of us: Eric Winquist, Sean Tong and me. We were setting out to do something that we knew was needed in our industry, to build a truly collaborative tool that people would use to build really complex things. We had big ideas and a not so big office. As we moved into our first space, we were faced with a question of distribution: two rooms, three people.

One would have been ok, three would have been ok, but two rooms posed a problem. Making it worse was the fact that the smaller room was also the room with large bright windows looking out to some moderately good office park landscaping. Ultimately it was warm and inviting while the other room felt more like a glorified entryway. So the question loomed before us as we stood there awkwardly, each with a used laptop in hand. Who would get the small room with the windows?

It was too early in the start-up to make a decision based on hierarchy – that didn’t yet exist. We were peers embarking on a grand journey that was built on trust and respect. As the company evolved, that would happen naturally, but we weren’t there yet.

In the end, we did what any sensible start-up would do. We figured out how to cram three desks into the small room. The desks barely fit and getting in and out was awkward but it worked. The close quarters brought us closer together and enabled us to collaborate on the fly. Also, we now had a big empty room to fill with grand ideas – to stand up and talk things through when we hit roadblocks.

Since that first office, Jama has been in 8 different spaces. In each instance the first thing we’ve done is set about making it feel like home. Whiteboards are always a must, couches, computers (chosen by the user), and open spaces to think and explore.  We’ve never considered cubed walls and offices only recently have been used (with glass walls).

Instead of two rooms we now have two offices, and a lot more than 3 people. The tone struck in the early days of our inception has remained resonant through our growth. Open and collaborative remain the key tenets fostered in that early decision to focus on being a team before anything else.

forJama

Derwyn during a visit to an early Jama customer in Germany

Today, we are excited to announce a round of funding led by investors Trinity Ventures, with participation from Madrona Ventures Group. These firms are excellent, both in reputation and in their approach. Over the past six years, we have often considered the option of institutional investment, and until now, have opted to fund our growth organically, through customer revenue. Given the product delivery market opportunity, it’s the right time for the company to ignite the gas and fuel the next phase of our growth and we’ve found two partners who share our vision and who believe in the Jama plan.

Both Karan Mehandru, General Partner at Trinity Ventures, and Tim Porter, Managing Director at Madrona, have extensive experience advising Saas-based enterprise software companies. The Jama team extends a warm welcome to these new partners.

I could not be more excited about the opportunity in front of us. Jama’s strategy of addressing product-delivery challenges with an enterprisewide platform that knits together the business and development side of the process is resonating strongly with the market. Our core requirements-management, collaboration and testing solution over the past six years has proven our business model with a rapidly growing number of Jama customers – 600+ and counting – and a broader ecosystem of partners that have chosen to work closely with us on this journey to introduce a modern product delivery platform.

This journey will continue as we accelerate development of our core product and continue to take a leadership position in the market. The innovation we are delivering with social collaboration, requirements management and testing will further cement Jama as a core component of product-development strategies in the new age of highly complex, smart products, software and embedded systems.

With this funding we will focus on further investing in our own product and engineering teams, scaling our footprint geographically and raising our profile. It will enable us to increase the rate of innovation across all of the Jama projects. Those investments will continue to fulfill enterprise requirements and expand adoption with our customers in the coming months.

I am excited about the opportunity ahead. We have an amazing team here at Jama and I am thrilled to welcome these two amazing investors to our team.

At Jama, we work with the world’s most innovative companies and government agencies to manage the entire lifecycle of product delivery. They think differently, challenge the status quo, and are constantly looking for new ways to improve product delivery to gain that competitive edge. Unfortunately many find it really challenging to work with a legacy tool that no longer meets their needs. What is the risk to the business? What is the cost to move all the old data to a new solution?

We have built a world-class solution to help you move active data from IBM DOORS to Jama, a lower cost, cutting-edge product delivery platform. Jama’s import capabilities for IBM DOORS include the ability to bring along the requirements, test cases and other information you care about.

Don’t work the old way. Now is the time to move off IBM DOORS. We can help. Bring what you need into Jama, when you need it. The Jama DOORS migration solution will maintain all relationships, so you can easily configure or change any elements.

How does it works

Learn more! Contact us to see how it works.

Looking for Jama Contour? It’s still here as the solution for collaborative requirements management software, we just dropped the “Contour” and added a “Connect.” Meet Jama Connect! We’re excited to begin the next chapter of our story: redefining product delivery.

Product delivery involves the entire company. It doesn’t start with Product Managers defining requirements and end with Engineering and QA teams delivering a finished product. Successful product delivery requires connecting the right people in a company to take strategies and concepts all the way to market and ultimately translate them into business value.

Jama Connect builds on Contour’s proven requirements and test management success. It extends the current collaboration capabilities amongst the team, allowing them to capture ad-hoc conversations and decisions within the context of their projects and items. Most importantly, it provides product teams the ability to engage stakeholders outside the team into the right discussions to make timely decisions that will be part of the project’s system of record.