JAW Speak

Jonathan Andrew Wolter

Subversion Parallel Multi-Branch Development And Merging

with 3 comments

Reading time: 2 – 2 minutes

As discussed in my previous post, I dislike merging-based-development, preferring Trunk Based Development instead. But, sometimes you’re stuck with a long-lived development branch, and you need to merge changes (subversion tree-conflicts and all). At the end of the post, I have several scripts I used to make this easier. Not the prettiest, but saved a lot of pain when we had major refactorings in trunk, and needed to locate and merge the changes to those files in a long lived (read: horrible) dev branch.

Imagine this scenario: Multiple streams of development, with a long-lived “3.0 dev” branch that has never reintegrated with the trunk. (Because 3.0 has new features that won’t go into production for many months).

branch-and-merge-problems-1

There are substantial dangers in this approach. This diagram only touches on the surface of the areas of risk in which a merge could fail. Solution? Trunk based development / branch by abstraction.

branch-and-merge-problems-2

Given this required scenario, I developed a few best practices and scripts for merging. The best practices involved having multiple branches checked out into different directories. And then we would find equivalent files that have moved and merge the tree-conflicts.

Scripts to assist in Subversion 3 way merging.

Custom diff3-cmd configuration setting in svn:

Bookmark and Share

Written by Jonathan

November 3rd, 2010 at 4:21 am

The Management Myth: Management Consulting Past, Present & Largely BogusThe Management Myth: Management Consulting Past, Present & Largely Bogus – Book Review

with one comment

Reading time: 5 – 8 minutes

The Management Myth: Management Consulting Past, Present & Largely BogusThe Management Myth: Management Consulting Past, Present & Largely Bogus by Matthew Stewart

My rating: 5 of 5 stars

A highly entertaining read where Matthew Stewart dismantles the Management Consulting industry. For you with experience in consulting, parts of this are hilarious as Stewart chronicles both the imploding of the consultancy he helped create, and the overall history of the industry.

One by one, he tears apart Fredrick Taylor (the father of “scientific management”), Elton Mayo (of the “famous” Hawthorn Effect), Management Consultants, Strategy (as a science), popular Management Gurus, and offers a harsh critique of MBA’s in general. His main premises is that “Management” is not a profession on the level with Medicine or Law, however management education through business schools have attempted to professionalize it. And to that end, they have manufactured “science” (in a very non-rigorous and untestable sense), truisms, frameworks, and case studies.

Here are a few highlights. I didn’t agree with all that he had to say, but I did enjoy reading it. I was laughing out loud towards the end as he details how his fellow partners are embroiled in litigation with him as he tries to sever all ties. Stewart is genuinely funny, giving characters nicknames such as “The Prince of Darkness”, “The Troll,” “Dr. Bob” the corporate shrink, and others.

As for management consultants, he had less-than-flattering quotes:

“[C]onsultants often serve not to provide new knowledge to their clients but merely to communicate ideas already formed. In many instances, our work amounted to harnessing work performed in one part of an organization and then packaging it all as our own work for the benefit of another part of the same organization.”

I can’t speak for all organizations, but I am extraordinarily fortunate to say at ThoughtWorks (my employer) this has never been my case. We are not a traditional management consulting McKinsey style strategy consulting firm, true. However, we do have consulting projects, some the strategic management consulting types. I’ve seen us bring our outside expertise and influence and avoid acting solely as grease in the wheels. Becoming grease may let others bill lots of money, but isn’t very intellectually fulfilling.

Even better, if you have worked in a traditional pyramid style company, (of which ThoughtWorks is very, very, very, very much not) he has this gem to explain it:

“It’s like being stuck in a dungeon with a bunch of rats and a giant block of cheese. All the rats keep climbing the cheese, two years at level one, two years at level two. The threes shit on the twos and the twos shit on the ones, and everyone shits all the time on the rats at the bottom. All they care about is rat-face-time. As in, please-sir-would-you-stick-your-rodent-butt-closer-to-my-face time. You keep going up until one of the other rats bites your ass off.”

Up or out. Several friends of mine elsewhere have shared this is a fairly accurate description.

Strategy. He also tears apart Porter and his Five Forces [3]. Stewart claims all business strategists describe strategy in hindsight (not so useful if you want to implement “strategy” for, you know… the future). I have a little bit of a hard time accepting that all of modern strategy is hogwash, as instead I think while bounded in utility, different frameworks help one to position a problem and look for solutions in diverse ways.

Due to business schools’ roots in Taylor, Mayo and others that he sequentially defuses of all credibility, the author also suggests that the fundamental underpinning of MBA’s are shaky. The academic and scientific rigor is weak, and the content is easily grasped by otherwise intelligent people.

“After 100 years of fruitless attempts to produce such a discipline, it should be clear that [Business Management] does not exist. preparing managers to manage, in fact, is not different from preparing people to live in a civilized world. Managers to not need to be trained; they need to be educated. And for that purpose, although a certain amount of study of business-related subjects may prove useful, the business schools as they are presently constituted are at best superfluous.”

A jaded view? Yes. But also very fun. The best parts is the parallel narrative that progresses through the book about his firm. I don’t want to spoil much, but it is especially fun when his firm’s acquiring company’s CEO steps down because he wishes to promote full time his beliefs in UFO’s and alien-human technology transfer. Serious. [4] This guy had a crazy consulting journey, and has a great style of writing about it.

If you are interested in this book, first read his article on The Atlantic [1], which gives you a taste of the content here. Second, check out the WSJ book review [2], by Philip Broughton, author of a similar book that I recently reviewed. Also check out the New Yorker’s review [5].

[1] http://www.theatlantic.com/magazine/arch…
[2] http://online.wsj.com/article/SB10001424…
[3] Michael Porter, of Harvard. Father of the 5 Forces, which are: (1) the bargaining power of suppliers, (2) the bargaining power of buyers, (3) the rivalry among existing firms, (4) the threat of new entrants, and (5) the threat of substitute products. Extremely influential, he also advocated all strategy aims for a single, measurable goal: excess profits. (Unsurprisingly, Stewart takes criticism of this).
[4] http://articles.sfgate.com/1999-01-09/ne…
[5] http://www.newyorker.com/arts/cri…

And, please share with me your comments.

View all my reviews

Bookmark and Share

Written by Jonathan

October 31st, 2010 at 5:03 am

No-Nonsense Guide to International Development – Book Review

without comments

Reading time: 3 – 4 minutes

No-nonsense Guide to International Development (No-Nonsense Guides)No-nonsense Guide to International Development by Maggie Black

My rating: 4 of 5 stars

A fast read about international development’s history and future. The statistics are staggering. “10 million people a year are displaced due the construction of dams and urban transportation systems. Compare to 12 million annually with wars and other ‘disasters’.” I enjoyed this book, read it in about a week, and recommend it as an introductory text. It discredits the historical Marshall Plan style of development, which attempted to funnel infrastructure investment in a massive global scale. Post-WW2 Europe developed so quickly because of an educated cadre waiting to run it, eager human capital, and an abundant educated workforce. This is not present in the poorest of developing nations. Maggie Black cites an epic failure of mechanizing agriculture in Tanzania, Uganda, and Zambia when tractors suffered from rapid breakdowns, no spare parts, misuse for private purposes, and endless other problems. (Great life lesson: you have to meet people where they are, rather than where your biases initially lead you).

Black covers aid with its many failures, some successes such as smallpox eradication, but overall underwhelming performance in ending poverty. She summarizes aid as generally ineffective: “the machinery of official aid is not designed to address the poverty of people, but the state of nations.” Next she moves to the World Bank/IMF and their program of “structural adjustments,” and the “Washington consensus.” Both were macroeconomic agendas pushing prudent fiscal and monetary policies, inflation control, and free markets. Seemingly wise ideas, but which often resulted in great challenges for the debtor nations: cut services and subsidized foreign commodities competition, and lost local jobs.

- Today a third of the world’s population – about 2 billion people – still remain outside the modern economy or survive at the edges.
- Circa 2007, two thirds of Indians are still involved in agriculture; in China she claims it is 44%.
- In 1960 the income gap between the fifth of the world population in the richest countries and the fifth in the poorest was 30 to one; by 1997 it was 74 to one.
- As of 2004, 1.1 billion people were without a supply of safe water, and 2.6 billion without a proper means of sanitation. And don’t think just digging wells or creating a water utility will solve this.

What is her summary? “Less effort should be put into grand international initiatives – ‘Marshall Plans for Africa’ and achieving the Millennium Development Goals – and more into making things work on the ground.” She goes into detail of successes where local scale efforts have still been able to assist millions of people. These, she posits are the keys to future success in international development, as opposed to the “bigger picture, more western perspective” of macro-economic adjustments.

The book is interesting in the treatment of details, and in the journey it takes the reader on.

View all my reviews on Goodreads

Bookmark and Share

Written by Jonathan

October 20th, 2010 at 1:13 pm

Session State – it’s not complicated, but options are limited

with 2 comments

Reading time: 3 – 4 minutes

Web apps have numerous choices for storing stateful data in between requests. For example, when a user goes through a multi-step wizard, he or she might make choices on page one that need to be propagated to page three. That data could be stored in http session. (It also could get stored into some backend persistence and skip session altogether).

So where does session get stored? There are basically four choices here.

  1. Store state on one app server, i.e. for java in HttpSession. Subsequent requests need to be pinned to that particular app server via your load balancer. If you hit another app server, you will not have that data in session.
  2. Store state in session, and then replicate that session to all or many other app servers. This means you don’t need a load balancer to anchor a user to one app server; multiple requests can either hit any app server (full replication). Or use the load balancer to pin to particular cluster (themselves replicating sessions, and giving higher availability). Replication can be smart so only the deltas of binary data are multicast to the other servers.
  3. Store the state on the client side, via cookies, hidden form fields, query strings, or client side storage in flash or html 5. Rails has an option to store it in cookies automatically. Consider encrypting the session data. However, some of these options can involve a lot of data going back and forth on every request, especially if it’s in a cookie and images/scripts are served from the same domain.
  4. Store no state on app servers, instead write everything in between requests down to backend persistence. Do not necessarily use the concept of http session. Use id’s to look up those entities. Persistence could be a relational database, distributed/replicated key/value storage, etc. Your session data is serialized in one big object graph, or as multiple specific entries.

What you choose is up to many factors, however a few guidelines help:

  1. Try to keep what is in session small.
  2. If possible, keep session state on the client side.
  3. Prefer key/value storage replicated among a small cluster over replicating all session state among all app servers.
  4. Genuinely consider sticky sessions, which home users to a particular app server. Many benefits abound, including what Paul Hammant talks about w.r.t Servlet spec 7.7.2 Appengine’s Blind Spot.
  5. If you serialize an object graph, recognize that when you do a deployment it will probably mean existing sessions are now unable to be deserialized by the newly deployed app. Avoid this by using your load balancer to swing new traffic into the new deployments, monitor errors, and then let the old sessions expire before switching all users over to the new deployment. Bleed them over.
  6. Session is not for caching. It may be tempting to store data in session for caching purposes, but soon you will need a cache.
  7. Store in session what is absolutely necessary for that user, but not more. See caches, above.

Update: see also  http://www.ibm.com/developerworks/websphere/library/bestpractices/httpsession_performance_serialization.html

Bookmark and Share

Written by Jonathan

July 30th, 2010 at 3:39 pm

Posted in architecture, code, java

Tagged with

Spring Request Scoped FactoryBean returning null gets cached forever

without comments

Reading time: 2 – 4 minutes

We are using FactoryBeans extensively to own the responsibility of interesting work in constructing our object graph. These are request scoped, because they may depend on other objects that were themselves created by FactoryBeans specific to this request. For example, we have a Customer which needs an Account, so CustomerFactoryBean depends on the field Account to be injected. (We use field or setter injection because otherwise creating a factory bean that depends on another object that is created by a factory bean may create a spring exception about circular dependencies.)

package com.example.dotcom;
 
import com.example.common.Account;
import com.example.dotcom.session.CustomSession;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
 
// the scope is crucial, this controls the scope of the factory bean
@Scope("request")
public class AccountFactoryBean implements FactoryBean {
 
       // this is itself created from another factory bean
       @Autowired
       CustomSession session;
 
	@Override
	public Object getObject() throws Exception {
		// Sometimes this is going to return null, other times an instance.
                // The fix is to always return a non-null instance (despite what the
                // javadoc says). Use the Null Object pattern.
                return session.get(Account.class);
 
 
		// Note: you will need to implement caching in here or in 
		// a custom scope (which we did). Or every time you need
		// to inject the Account it will call getObject(), which
		// could be problematic if it was a slow operation.
	}
 
	@Override
	public Class getObjectType() {
		return Account.class;
	}
 
	@Override
	public boolean isSingleton() {
		return false;
	}
}

We are using autowiring by type, but we encountered a problem when the result of a factory bean’s getObject() is sometimes null. If the first call to that request scoped factory bean returned null, it would never call getObject() again in future requests. Upon investigation, you can see there is a subtle caching of null return values from factory beans. (Even if they are request scoped.) Might be a bug, I don’t know. But the work around is probably a good idea to implement anyways: use Null Objects instead of passing around null.

Here is the problematic code from Spring that caches the null return value: AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement. There is a field cached and cachedFieldValue. These are set if the value is null, and then on subsequent calls they will return the null value without calling getObject on the factory bean.

I recommend not returning null in factory beans, or else it might be cached by Spring and your factory bean will not be called again when that object is needed.

Bookmark and Share

Written by Jonathan

July 27th, 2010 at 11:18 pm

Posted in code, java

Tagged with

Less Hate with Maven Part 2: The Wrapper Script

without comments

Reading time: < 1 minute

I previously wrote about useful debugging techniques with maven. Our maven builds have become complex, with Branch By Abstraction, and about 40 devs working simultaneously on the codebase in 2 continents. We have at least 3 profiles for each of the branch abstractions that are currently running in the codebase. I’m one of the tech leads, and in order to keep the team’s build consistent and easy to remember, we have a wrapper script (thanks to Cosmin).

Here it is:

Bookmark and Share

Written by Jonathan

May 28th, 2010 at 9:03 am

Posted in automation, code, thoughtworks

Tagged with

Hotspot caused exceptions to lose their stack traces in production – and the fix

with 2 comments

Reading time: 3 – 4 minutes

Today I was working with Kumar and Elian where we encountered production logs with dozens of NullPointerExceptions with no stack trace. We identified that the JIT compiler will optimize away stack traces in certain exceptions if they happen enough. The code below reproduces it. We are on jdk 1.6 (I don’t remember the minor version now).

public class NpeThief {
    public void callManyNPEInLoop() {
        for (int i = 0; i &lt; 100000; i++) {
            try {
                ((Object)null).getClass();
            } catch (Exception e) {
                // This will switch from 2 to 0 (indicating our problem is happening)
                System.out.println(e.getStackTrace().length);
            }
        }
    }
    public static void main(String ... args) {
        NpeThief thief = new NpeThief();
        thief.callManyNPEInLoop();
    }
}

Run it as follows and the issue will appear (the stack trace length changes from 2 to 0):
javac NpeThief.java && java -classpath . NpeThief
javac NpeThief.java && java -server -classpath . NpeThief

How to fix it? The following options resolve it and it stays at 2, never going to 0 as length of NPE’s stack trace:
javac NpeThief.java && java -XX:-OmitStackTraceInFastThrow -server -classpath . NpeThief
javac NpeThief.java && java -XX:-OmitStackTraceInFastThrow -classpath . NpeThief
javac NpeThief.java && java -Xint -classpath . NpeThief
javac NpeThief.java && java -Xint -server -classpath . NpeThief

So the solution is to start with -XX:-OmitStackTraceInFastThrow argument to java which instructs the JIT to remove this optimization [1,2], or operate in interpreted only mode [3]. What is going on? [2]

The JVM flag -XX:-OmitStackTraceInFastThrow disables the performance optimization of the JVM for this use case. If this flag is set, the stacktrace will be available. (editor: or if the -Xint is set).

“The compiler in the server VM now provides correct stack backtraces for all “cold” built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.” http://java.sun.com/j2se/1.5.0/relnotes.html

How does this impact performance? I did extremely naive timing and time java [args] -classpath . NpeThief. It behaved as expected, with interpreted the slowest. Is that the solution?

No. We weren’t going to change production JVM options to resolve this, instead since our isolated example code above indicated that initial exceptions would throw with the full stack trace, we went back into older logs and grepped. Sure enough, right after we deployed there were exceptions appearing with the full stack trace. That gives us enough information where we can identify and fix the bug.

Notes:
[1] Related sun bug 4292742 NullPointerException with no stack trace
[2] Helpful StackOverflow discussion of NullPointerException missing stack traces
[3] -Xint: Operate in interpreted-only mode. Compilation to native code is disabled, and all bytecodes are executed by the interpreter. The performance benefits offered by the Java HotSpot VMs’ adaptive compiler will not be present in this mode.

Bookmark and Share

Written by Jonathan

May 26th, 2010 at 12:46 am

Posted in code, java, thoughtworks

12 Tips for Less* Hate of Maven

with 4 comments

Reading time: 3 – 5 minutes

We’re (stuck*) using maven on a project, and this means often the build doesn’t act like you’re expecting. Debugging requires knowledge about maven’s capabilities and less documented features. Here are some tips, please add more in the comments.

  1. The -X flag shows debug logging, and tee it to a file which you then search for clues of what happened. This is great for verifying if a plugin actually ran, and what it did. Example: mvn -X install | tee out.txt
  2. mvn dependency:tree (show the transitive dependencies of your dependencies) [1]
  3. -Dtest=MyJavaTest (just use the name of the class, no package necessary)
  4. mvn help:system (show environmental variables and system properties) [2]
  5. mvn help:active-profiles (show the active profiles to be run)
  6. mvn help:all-profiles (show all profiles maven reads)
  7. mvn help:effective-pom (show the logical pom.xml being used)
  8. mvn help:effective-settings (show the logical settings.xml which is being used)
  9. mvn help:describe -DgroupId=org.apache.maven.plugins -DartifactId=maven-resources-plugin -Ddetail (show details about a plugin’s options)
  10. -DskipTests this will skip running tests, but still compile it. or -Dmaven.test.skip=true which will skip compilation and execution of tests (use with judgment, I believe in testing)
  11. If -X doesn’t show you the properties when you needed them, you can also use the ant-run plugin to echo a property value (does anyone else know a better way to do this in maven? Tell me what a property value is at the time of the plugin or goal executing?)
  12. Run your tests paused in debug mode, waiting for a debugger to attach to port 5005 with mvn -Dmaven.surefire.debug test [4]

References:

*Note: Initially I disliked the confusion and long, slow learning curve with maven. After working 8 months with maven and my colleagues Lucas Ward and Paul Hammant, I’m feeling much more comfortable and am generally okay with it. For small open source work, where you want a project quickly, but don’t want to spend a few hours with ant, I like it very much. For our large project, maven is fundamentally broken. Too much file copying is required, and manual intervention on a complex build is impossible, or extremely tedious. Running with our own build script we control could be dramatically more flexible.

On a mailing list Paul recently recommended a few other to consider:

Maven Dependency plugin
mvn dependency:tree
- shows me the transitive deps (say, “how the hell is MX4J being dragged into the build ?”)
mvn dependency:analyze
- show me unused, but declared dependencies.
There’s a ton of free capability to that plugin – http://maven.apache.org/plugins/maven-dependency-plugin/

An Atlassian dependency plugin
Atlassian wrote a plugin ( http://confluence.atlassian.com/display/DEV/FedEx+XI+-+Keeping+track+of+you+maven+dependencies ) that guards against undesired changing dependencies.

Maven Enforcer Plugin
A more intrusive way of guarding against deps that, say, should not make it into a war.  http://maven.apache.org/plugins/maven-enforcer-plugin/

What tips do you have? Please share them in the comments.

Bookmark and Share

Written by Jonathan

May 14th, 2010 at 8:13 am

Posted in code, java, thoughtworks

Tagged with ,

Injecting HttpServletResponse into Spring MVC request scoped interceptors

without comments

Reading time: 3 – 5 minutes

I’ve been heavily refactoring a large team’s codebase that stuffed many critical dependencies into request attributes. You see request.getAttribute() throughout the code, which is counter to dependency injection’s principles. Instead of getting what you want, be given it to you. We are moving to a more idiomatic way of using spring to inject things such as our custom Session object.

However, there was a lifecycle mismatch between some singleton interceptors which needed the session object, which is only request scoped. We had everything working, except one of those interceptors also needed the response object as a collaborator.

I had a spring instantiated non-controller bean that is request scoped, and I want to inject in two collaborators:

HttpServletRequest (which can be injected)
HttpServletResponse (which fails injection)

Here is my bean:
<bean id="sessionFactory" scope="request">
<aop:scoped-proxy/> <!-- scoped-proxy to get around the singleton requests injection of a request scoped object problem -->
</bean>

Here are the autowired fields:
@Autowired HttpServletRequest request;
@Autowired HttpServletResponse response;

Can I inject the response object in this bean?

This is the error I was getting:
[INFO] Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name ’scopedTarget.sessionFactory’: Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Could not autowire field: javax.servlet.http.HttpServletResponse com.example.web.SessionRequiring$SessionFactory.re sponse; nested exception is org.springframework.beans.factory.NoSuchBeanDefini tionException: No unique bean of type [javax.servlet.http.HttpServletResponse] is defined: Unsatisfied dependency of type [interface javax.servlet.http.HttpServletResponse]: expected at least 1 matching bean
[INFO] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterIn stantiation(AutowiredAnnotationBeanPostProcessor.j ava:243)

I navigated to GenericWebApplicationContext, which delegates to WebApplicationContextUtils.registerWebApplicationS copes(beanFactory), which then registers ServletRequest.class and HttpSession.class as injectable. But not the response object.

So here’s what I did, which works for me:

In web.xml add a filter that will store every ServletResponse in a threadlocal, which will be accessible only from your FactoryBean.

  <filter>
        <filter-name>responseInScopeFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>responseInScopeFilter</param-value>
        </init-param>
  </filter>
  <filter-mapping>
        <filter-name>responseInScopeFilter</filter-name>
        <url-pattern>/*</url-pattern>
  </filter-mapping>

Create the filter:

    /**
     * We need a filter to capture the HttpServletResponse object such that it can be injectable elsewhere in request scope.
     */
   public static class ResponseInScopeFilter implements Filter {
        // not the most elegant, but our spring commiter friends suggested this way.
        private ThreadLocal<HttpServletResponse> responses = new ThreadLocal<HttpServletResponse>();
        public void init(FilterConfig filterConfig) throws ServletException { }

        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            responses.set(response);
            chain.doFilter(servletRequest, servletResponse);
            responses.remove();
        }

        /** Only to be used by the BeanFactory */
        private HttpServletResponse getHttpServletResponse() {
            return responses.get();
        }

        public void destroy() { }
    }

And also create the FactoryBean:

/** We need our own FactoryBean because Spring does not offer a way to
     * inject request scoped HttpServletResponse objects.
     * See http://forum.springsource.org/showthread.php?p=298179#post298179 */
    public static class HttpServletResponseFactoryBean implements FactoryBean {
        @Autowired ResponseInScopeFilter responseInScopeFilter;

        public Object getObject() throws Exception {
            return responseInScopeFilter.getHttpServletResponse();
        }

        public Class getObjectType() {
            return HttpServletResponse.class;
        }

        public boolean isSingleton() {
            return false;
        }
    }

Wire it all together in applicationContext.xml

<bean id="httpServletResponse" class="com.example.web.SessionRequiring$HttpServletResponseFactoryBean" scope="request"/>
<bean id="responseInScopeFilter" class="com.example.web.SessionRequiring$ResponseInScopeFilter"/>

Elsewhere I can now inject an HttpServletResponse object and it will be request scoped appropriately for this request. You can read more about this in my post on the spring forums.

Bookmark and Share

Written by Jonathan

May 6th, 2010 at 9:32 pm

Posted in code, java, thoughtworks

Being Part of ThoughtWorks: Pillar 3 Social and Economic Justice

with 3 comments

Reading time: 2 – 3 minutes

At ThoughtWorks, we have many great technological projects, and brilliant coworkers. But beyond all that is a power for social good that is out at work in the world. Today, many of us are involved in ongoing projects with UNICEF and other non-profit organizations, helping solve fundamental human issues with technology. Last winter North America had an all-hands, and we brought in people like Merrick who’s helping the world with mobile SMS based apps at UNICEF. And we have Jeff Wishnie who is a Silicon Valley veteran, paragliding instructor, and now our Director of Social Engagement. He brings both socially aligned clients, and goes out and leads missions into all parts of the world using technology to better humanity.

ThoughtWorks has three distinct pillars that describe it:

  • First it needs to be a sustainable business.
  • Second it champions software excellence.
  • Third it has a passion for social and economic justice.

Our founder and chairman, Roy Singam, sent a great email out a few days ago that inspired this post, and reminded me the importance of how each of us choose to spend our working hours. Over coffee and engaging life-beyond-mere-profitability conversations he gave me permission to quote him:

“Being part of an organization that advances a cause is an important. Associating with people who collectively encourage moral behavior is one of the most important decisions one makes in life. To ignore this and treat these decisions as simple career decisions (or give a little guilt money) is avoiding moral responsibility.”

We have ThoughtWorkers on the ground in real projects working with global and local NGO’s that allow us to directly apply technology, process design, and lean management to changing the world. The mobile space is especially exciting.

I believe future proof, profitable corporations, with reason beyond profit will retain the most capable employees, and provide lasting global impact as 100-year socially-positive companies. Profit, smarts, and growth is essential, but the meaning of work-life must extend beyond the bottom line.

Bookmark and Share

Written by Jonathan

April 29th, 2010 at 1:48 am

Posted in career, thoughtworks