Merging pdf’s on Mac OS X from a non-duplex scanner
Reading time: 2 – 3 minutes
Goal: scan in hundreds of duplex documents in a non-duplex scanner and combine into 1 pdf in automated way. Status: it was harder than it should have been, and not that automated, but this works.
Scan in the papers as pdf’s from your paper-feed equipped scanner. Scan them right side up, then flip over and scan the other sides. The two pdf’s will contain pages: 1, 3, 5… and 2, 4, 6…
Reverse the even pages.
#!/usr/bin/ruby if __FILE__ == $0 puts "Run this on ubuntu or somewhere that pdftk is easy to be had. (which isn't os x)" if ARGV.length != 1 puts "Syntax: #{__FILE__} pdf_to_reverse.pdf" exit end pdf = ARGV[0] reversed_pdf = pdf.gsub(/\.pdf/i, "_reversed.pdf") page_count = `pdfinfo #{pdf} | grep Pages`.scan(/\d+/) `pdftk #{pdf} cat #{page_count}-#{1} output #{reversed_pdf}` end
Lastly, combine the two pdf’s, shuffling every other page, starting with the odds. Note it has some dependencies on pdftk and pdfinfo for the reversing (which are excruciatingly difficult to install on os x), and os x (for the merging).
#!/usr/bin/ruby if __FILE__ == $0 puts "Run this on os x to shuffle two pdf's, where the even pages are already reversed (reverse them with other script)" if ARGV.length != 3 puts "Syntax: #{__FILE__} odds.pdf reversed_evens.pdf output.pdf" exit end odds_pdf = ARGV[0] reversed_evens_pdf = ARGV[1] output_pdf = ARGV[2] # obviously, only works on os x. I didn't see an easy way to combine pdf's # in pdftk or other tools I searched for `python '/System/Library/Automator/Combine PDF Pages.action/Contents/Resources/join.py' --output '#{output_pdf}' --shuffle '#{odds_pdf}' '#{reversed_evens_pdf}'` end
References:
Fast and Easily Testable GWT JUnit Tests
Reading time: 4 – 6 minutes
GWTTestCase. (It’s too slow). So that means never instantiate or reference a GWT widget in the controller. They must always be decoupled by interfaces. Here’s some of what we learned. Formerly my controller had an async event handler in it that showed a pop up message on a failure.private AsyncCallback asyncCallback = new AsyncCallback() { public void onFailure(Throwable caught) { Window.alert("An error occured, please try again. \n" + caught.getMessage()); } public void onSuccess(PackageDto pkg) { firePackageUpdate(pkg); // throw an event in here that is handled by a // listener, which is the gui code and which has no logic // (logic is in the controller!) } };
java.lang.ExceptionInInitializerError Caused by: java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code! It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor. at com.google.gwt.core.client.GWT.create(GWT.java:91) at com.google.gwt.user.client.Window.(Window.java:230) ... 28 more
- Implement the AsyncCallback<T> interface with BaseAsyncCallback<T> , and implement the onFailure() to call Window.alert(). In tests, I would subclass and override onFailure() in tests, preventing the Window.alert() from executing. I generally don’t like subclassing for tests, so I wasn’t too keen on this.
- Implement the AsyncCallback<T> interface with a class BaseAsyncCallback<T>, but this time take in a constructor parameter, FailureHandler (which would be an interface or class of my own.) Then in onFailure(), delegate to the FailureHandler field. In tests, pass a different FailureHandler implementation or subclass, to avoid calling the GWT widget code.
- The recommended solution is to treat this the same way I deal with onSuccess(). Tell a listener that a failure event occurred, and let it handle it.
GWTTestCase or Selenium).- Separate the Controllers from all references to Views (GWT UI objects) by using event listener / notifier interfaces.
- Martin Fowler’s Humble View and Supervising Controller
- MVP post from google code testing blog
- GWT architecture talk by Ray Ryan at google IO this year (pending a sample app using the event bus he describes. See discussion group and watch video below).
Test Driven log4j Logging Code Example
Reading time: 3 – 4 minutes
Update: Added a snippet so that you can easily assert a message was contained in the logged messages.
Frequently logging is not viewed as “important” by engineers as, say, the logic for refunding a customer’s purchase. The customer’s won’t mind, after all, if we forget to log something right? Maybe so, until there are problems and the operational team supporting your application has very little ability to diagnose problems.
I propose logging should be viewed as another user interface, and thus needs its’ own set of acceptance and unit tests. This makes for more tedious and up front work for development teams — however I want to survive in production without a pager going off, and with fewer late night scrambles to ship patches.
Imagine a class that has logic associated with logging. Below you will see a unit test verifying logging statements are correct. Often logging uses statics, and as Misko has said, statics are a death to testabilty. With Guice you can easily inject loggers automatically for the class under construction. This method gets around most of the issues with static loggers, although I still despise statics everywhere.
This is a basic example, but the point is to understand how to hook into appenders and add/change one to use a test appender.
package com.jawspeak.common.testing; import com.google.common.collect.Lists; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.spi.LoggingEvent; import java.util.List; /** * Use me for spying on test logs and making asserts against them. * * Example how to use: * final SpyLoggerAppenderForTesting spyAppender = new SpyAppenderForTesting(); * final Logger logger = Logger.getLogger(MyClass.class.getName()); * try { * logger.addAppender(spyAppender); * // do something * assertEquals(Lists.newArrayList("Attempted to read such-and-such, but could not: oops"), spyAppender.getMessagesLogged()); * } finally { * logger.removeAppender(spyAppender); // clean up global state * } */ public class SpyLoggingAppenderForTesting extends AppenderSkeleton { private List messages = Lists.newArrayList(); protected void append(LoggingEvent loggingEvent) { messages.add(loggingEvent.getRenderedMessage()); } public List getMessagesLogged() { return messages; } public boolean doMessagesContain(String snippet) { boolean isFound = false; for (String message : messages) { if (message.indexOf(snippet) >= 0) { isFound = true; } } return isFound; } public void close() { } public boolean requiresLayout() { return false; } }
Here’s an example test where we make use of it. Note that we didn’t assert the lists are exactly the same, because in this project we were also using aspects to do logging, and depending on if you ran with or without the aspects enabled, a different number of logging messages would be created.
package com.jawspeak.common.utility; import com.google.common.collect.Maps; import com.jawspeak.common.testing.SpyLoggingAppenderForTesting; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import java.util.LinkedHashMap; import java.util.List; public class SessionSizeLoggingTest { private SpyLoggingAppenderForTesting spyAppender = new SpyLoggingAppenderForTesting(); private Logger logger = Logger.getLogger(SessionSizeLoggingTest.class.getName()); private Level oldLoggingLevel = logger.getLevel(); private SessionSizeLogging sessionSizeLogging = new SessionSizeLogging(); @Before public void setUp() { logger.addAppender(spyAppender); logger.setLevel(Level.TRACE); // set the level in case a log4j.properties or log4j.xml disables this level of logging } @After public void tearDown() { logger.setLevel(oldLoggingLevel); logger.removeAppender(spyAppender); } @Test public void logBytesWhenUnprintable() throws Exception { LinkedHashMap map = Maps.newLinkedHashMap(); map.put("key", new String(new byte[] { 1, 31, 127, -97}, "ISO-8859-1")); String sessionId = "abc123"; sessionSizeLogging.logSessionSize(logger, sessionId, map); List messagesLogged = spyAppender.getMessagesLogged(); assertTrue(spyAppender.doMessagesContain("Session Size for session id: " + sessionId + " (approx. total " + (7 + 3 + 1 + 4 + 1) + " bytes)")); // or use assertTrue(messagesLogged.contains(" key[ 3 bytes] key --> value[ 4 bytes] '\\u0001\\u0031\\u0127\\u0159'")); } // .. many more tests }
This is a trick that I don’t see written about too much, but I recommend it often. And, I’d love to have some readers post enhancements, links, and take testability further with respect to logging.
Wrestling the Untestable Into Testable Code: Example with Test Driven SimpleTagSupport for custom JSP Tag
Reading time: 3 – 5 minutes
Let’s say app servers must be stateless. There is no affinity for a user pinned to a particular app server, so two requests will likely be handled by different Tomcats, Jetty’s, etc. This means nothing can go in HttpSession (we also can’t use clustering). And when it’s ecommerce, we can’t require cookies or that might cost millions in lost revenue. Given these constraints, you have one valid option left: custom url rewriting over all our links (GET’s) and with hidden form fields (POST’s).
You can edit every link and every form to pass some unique id around. But what if you have two or three id’s that need to pass around for legacy reasons? Sounds like a custom tag would be nice. Something you can put in your jsp’s (oh yeah, let’s say we’re using jsp’s too).
This introduces me to the testability challenge. Write your own tag extending SimpleTagSupport that would ensure parameters were always in a link, and write another tag to write out the three hidden input fields inside every form.
But, SimpleTagSupport is part of the good old servlet and jsp API, so it’s very bloated with context objects, deep inheritance, callbacks, and cruft that makes for difficult unit testing. Just look at the public interface, one method: public void doTag() throws JspException, IOException.
Here’s my test driven test case (with 100% coverage, through the public API), which takes advantage of Spring MVC’s MockHttpServletRequest and MockHttpServletResponse objects (which are really fakes). I’m also using Mockito, which I prefer over EasyMock and JMock.
package com.jawspeak.dotcom.tag; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.*; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockPageContext; import javax.servlet.jsp.tagext.JspFragment; import java.io.StringWriter; import java.io.Writer; public class StatefulLinkTagTest_SettingSessionId { private StatefulLinkTag statefulLinkTag = new StatefulLinkTag(); private MockHttpServletRequest request = new MockHttpServletRequest(); private MockHttpServletResponse response = new MockHttpServletResponse(); private static final String SESSION_ID = "ADFHE13"; @Before public void given() throws Exception { request.setAttribute("sid", SESSION_ID); statefulLinkTag.setJspContext(new MockPageContext(null, request, response)); JspFragment jspBodyFragment = mock(JspFragment.class); doAnswer(new FakeJspBodyAnswerer()).when(jspBodyFragment) .invoke((Writer) anyObject()); statefulLinkTag.setJspBody(jspBodyFragment); } @Test public void shouldRenderLinkWhenThereIsNoParameter() throws Exception { statefulLinkTag.setHref("/myPage.html"); statefulLinkTag.doTag(); String contentAsString = response.getContentAsString(); assertEquals("<a href=\"/myPage.html?sid=" + SESSION_ID + "\">link text body</a>", contentAsString); } @Test public void shouldRenderLinkWhenThereIsAlreadyAParameter() throws Exception { statefulLinkTag.setHref("/myPage.html?my_param=foo"); statefulLinkTag.doTag(); String contentAsString = response.getContentAsString(); assertEquals("<a href=\"/myPage.html?my_param=foo&sid=" + SESSION_ID + "\">link text body</a>", contentAsString); } /** Mockito Answer implementation to manipulate the parameters we pass * into JspFragment.invoke() due to the ugly servlet API. */ private static class FakeJspBodyAnswerer implements Answer { public Object answer(InvocationOnMock invocationOnMock) throws Throwable { StringWriter writer = (StringWriter) invocationOnMock.getArguments()[0]; writer.write("link text body"); return null; } } }
As for the implementation, it’s pretty straightforward after writing the tests. It doesn’t show covering multiple ID’s appended to the link, but it is now easy to test drive implementing them.
package com.jawspeak.dotcom.tag; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; import java.io.StringWriter; public class StatefulLinkTag extends SimpleTagSupport { private String href; public void setHref(String href) { this.href = href; } @Override public void doTag() throws JspException, IOException { PageContext pageContext = (PageContext) getJspContext(); getJspContext().getOut().print(createTagText( (HttpServletRequest) pageContext.getRequest())); } private String createTagText(HttpServletRequest request) throws IOException, JspException { StringWriter stringWriter = new StringWriter(); stringWriter.append("<a href=\""); stringWriter.append(href); if (href.indexOf("?") > 0) { stringWriter.append("&sid="); } else { stringWriter.append("?sid="); } stringWriter.append((String)request.getAttribute("sid")); stringWriter.append("\">"); getJspBody().invoke(stringWriter); stringWriter.append("</a>"); return stringWriter.toString(); } }
Questions, comments? Want to bash Java and tell me why I should be using Ruby, Erlang or Scala? For more about the SimpleTagSupport interface check here.
Reminder: OOPSLA Submissions Due March 19th
Reading time: 2 – 3 minutes
I’m involved in helping review the tutorial. Do you have something others would be interested in learning about? Please consider submitting a proposal, but do it fast since they are due March 19th. Here’s what the Tutorials are described as:
OOPSLA tutorials are half-day classes, taught by experts, designed to help software professionals rapidly come up to speed on a specific technology or methodology. Tutorials can be lecture-oriented or participatory.
OOPSLA tutorial attendees deserve the highest standard of excellence in tutorial preparation and delivery. Tutorial presenters are typically experts in their chosen topic and experienced speakers skilled in preparing and delivering educational presentations. When selecting tutorials, we will consider the presenter’s knowledge of the proposed topic and past success at teaching it.
If you’re interested, it’s not too late — and every submission helps ensure the quality of what is selected is the best possible. Do please consider a submission.
Below is the more generic announcement for all OOPSLA things:
OOPSLA 2009 Call for Submissions
http://www.oopsla.org/submit
OOPSLA solicits contributions that explore all facets of programming, systems, languages, or applications. Topics span a range of issues at the intersection between programming languages and software engineering. Moreover, OOPSLA is a key forum for introducing and discussing key programming models, programming methods, and related software engineering ideas, technologies, tools, and applications.
So OOPSLA is seeking contributions that address current software challenges, such as programmer productivity, security and reliability, ultra-large scale systems, and evolving hardware platforms. Of particular interest are those contributions addressing OOPSLA 2009’s focus on:
- Scaling: Multi-Core to Cloud
- Mashups of Models, Data and Code
- Tools for Reliability and Evolution
- Enterprise Agile Management
Here are the important dates:
Call for Papers
March 19, 2009
Due date for Research Program, Onward!, Practitioner Reports,
Educators’ Symposium, Essays, and proposals for Tutorials, Panels,
Workshops, and DesignFest
July 2, 2009
Due date for Posters, Demonstrations, Student Research Competition,
Doctoral Symposium, Onward! Films, and Student Volunteers
OOPSLA 2009
Oct 25-29, Orlando
For more information go to http://www.oopsla.org
Using (These) Anonymous Inner Classes is Probably Too Clever for Your Own Good
Reading time: 3 – 5 minutes
Sometimes it is tempting to have less verbose Java code and be clever. Say you have an object you need to build and set several properties on it, then use it. This way looks clever, but is a bad idea – especially in production code. Read on for why.
TripChoice myTrip = new TripChoice() {{ // look at these clever initialization blocks! setDestination("San Francisco"); setAvailableRoutes(new HashSet() {{ add("LAX-SFO"); add("BUR-SFO"); add("ONT-SFO"); }); }};
This is a huge problem because it can cause a NotSerializableException or create a memory leak. How? Because with that clever anonymous class and initialization block, there is an implicit reference to the outer class’ instance. That outer class will not be garbage collected so long as there is one reference to the anonymous class. Worse, if we ever
Here’s the typical way to do it.
// blah blah, this is typical, and a rather boring looking great big block of text. // (That's also probably scattered over several places in your code when you build these objects). TripChoice myTrip = new TripChoice(); myTrip.setDestination("San Francisco"); Set availableRoutes = new HashSet(); availableRoutes.add("LAX-SFO"); availableRoutes.add("BUR-SFO"); availableRoutes.add("ONT-SFO"); myTrip.setAvailableRoutes(availabileRoutes);
Here’s why this improved version is even not the best:
- It uses setters. Setters allow your object to be constructed in an inconsistent state. There are some situations setters are fine (i.e. form backing objects) but often your code is more clear without setters. In this particular case the setters aren’t egregious, but I still consider them a smell and much more verbose way that constructor injection. Read more about the problem with setter injection here
- It is verbose.
- It is also mutable (often a negative), again a problem due to the use of setters.
So what’s the best way to do it? I have found constructor injection and in our particular example use of Google Collections. As for seeing an implementation of the best solution – just leave a comment.
Below is a full example you can run that illustrates the hard to catch serialization bug.
package com.jawspeak; import com.google.common.collect.Lists; import static org.junit.Assert.*; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; /** * Understands the danger of anonymous subclasses for lists. */ public class TooCleverForOurOwnGoodTest { @Test(expected = NotSerializableException.class) // UPDATE: Thanks for the reminder from Dennis, below public void serializableDangerBugFromPatricksCleverness() throws IOException { // you think a List would be serializable, which it is. And so are Strings. final String myString = "3"; List strings = new ArrayList() { add("one"); add("two"); // However, because there is an anonymous subclass of ArrayList created, // there is an implicit reference to the outer class, which is **not serializable**. // This is a nice feature, which lets us have closure-ish syntax in java, such as // the following reference to the outer myString. add(myString); // It will throw the exception even without this reference. }}; // call your method that requires args to be serializable ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(strings); // The particular bug I had was even worse, because we were creating leaking a reference // through that List's implicit reference to the outer object. } @Test public void serializableDangerBugSafeButNotClever() throws IOException { // A List is serialiazable. And so are Strings. List strings = new ArrayList(); strings.add("one"); strings.add("two"); // No longer is there a reference to the outer class. // call your method that requires args to be serializable ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(strings); } @Test public void serializableDangerBugSafeAndNiceLooking() throws IOException { // A List is serialiazable. And so are Strings. List strings = Lists.newArrayList("one", "two"); // call your method that requires args to be serializable ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(strings); } }
One Unit Test should have Prevented Google from Categorizing the Entire Internet as Malware
Reading time: 2 – 3 minutes
The google wide massive glitch which this morning, categorized nearly every search result as malware could have been prevented by unit testing. This is a wonderful example why even “silly little scripts” should be test driven.
This is what happened. A file was checked in with a ‘/’ in it. This file listed some or all of the sites Google warns to be dangerous malware sites. When it rolled out to different data centers it it caused search results to be rendered with warning messages next to almost every search result.
One could have written unit tests to assert that typos (such as ‘/’) are not parsed, accidentally causing the entire web to be miscategorized. I really hope to read more about this on the Google Testing Blog, it’s a prime example for this company to take leadership and further promote Unit Testing, and even the opportunity for Test Driven Development. Miško, care to take that post up?
They handled it well, and Marissa Mayer made a post on the Official Google Blog:
We periodically update that list and released one such update to the site this morning. Unfortunately (and here’s the human error), the URL of ‘/’ was mistakenly checked in as a value to the file and ‘/’ expands to all URLs.
I say let’s use this as a publicity moment for testing. I am certain that testing has literally prevented many disasters in complex systems, however because the tests did their work — they got no publicity. Let’s see promotion of “lessons learned,” Google!
Where have you been saved by tests? Or, where was your big blunder that a test could have fixed?
PayPal Sellers’ Chargebacks and the Temporary Hold Account
Reading time: 4 – 6 minutes
I was on the phone today with Paypal Disputes trying to understand how they deal with disputes from sellers. Here’s my notes from the phone conversation for anyone curious:
These first two refer to the following screenshots:
Paypal txn XXXYYYZZZ, chargeback
Paypal txn AAABBBCCC, dispute
Q: What does the Status column mean in Txn details? Is this the status as of “today” (when we are looking at the website), or as of the date for that line item?
A: This is very confusing. The status column actually changes based on the status of the Hold. So if I were to have looked at this line item on Dec 22nd, it would not have shown “Removed”. I think this is a flawed representation of line items. (They should instead never change, but just have different “as of dates’” opinions of the status. See http://martinfowler.com/eaaDev/timeNarrative.html).
Q: Two example transactions: XXXYYYZZZ and AAABBBCCC. The first was net $ -10 due to a chargeback settlement. (All told, the sale cost me $10 bucks). The second appeared to be net $0. (I was even after a sale and full refund). Both resulted in the original purchase getting fully refunded. The first had a line item “Chargeback Settlement” the second had that same last line item as “Reversal.” What does this mean?
A: One was a chargeback, the other was a PayPal dispute. Only the chargeback had the $10 fee. The other was just a reversal.
Q: What does “update to reversal” mean?
A: Means a hold is released. Need every record step by step recorded. So PayPal first is notified of the dispute (either from their website via a PayPal dispute or from their bank via a credit card dispute). Immediately the amount of funds for the net value of the account are put on hold. (At this point the PayPal fee is refunded). The funds on hold are unavailable (frozen) until the dispute is finished. When the dispute is resolved, there is a transaction to unfreeze the funds on hold. If the dispute is not in your favor, then you will also see a net outflow of funds (possibly with or without a $10 chargeback fee).
Q: What is difference if I get a chargeback from a Bank Account versus a Credit card?
A: Well, you can’t actually get a chargeback on a bank account. Bank accounts typically do not have a capability for the account holder to “dispute” a charge. When you see a reversal on a bank account, this is probably because they contacted PayPal and directly initiated a Buyer’s dispute. One exception is for bank accounts with Visa or MasterCard check cards. Those are processed as credit cards, and thus could create a chargeback.
Q: How do I know if a dispute is a chargeback or a paypal dispute, by looking at the Transaction Details page?
A: You may or may not be able to. Chargebacks settled against the seller will have a “Chargeback Settlement” transaction type at the end of the Related Transactions. But ultimately, you will get know the difference based on the email they send you upon the initial dispute.
Q: What are the fees for chargebacks? I see sometimes an extra $10 and other times no extra fee.
A: Chargebacks have a $10 fee, always. This fee is incurred at the time of resolution. When the claim is first made, the paypal fee (i.e. $3.17) is refunded and your net amount (i.e. $95.87) is placed into a Temporary Holds account. (Which you can track as a current liability in your accounting system and handle this with a journal entry).
Q: How do I know which way the chargeback was settled? In my company’s favor or against us?
A: It should say in the Resolution Center on that dispute’s details page.
Q: I sell downloadable goods online, how can I get Seller Protection?
A: You probably can not. This link (must log in) has details about physical product requirement. Seller protection is great though for physical products, because it prevents you from ever getting chargebacks.
Hopefully this is helpful to some of you.
Introducting JAW’s Very Simple GWT Html Template
Reading time: 2 – 4 minutes
Update 2009/7/29: This is a great way to see how GWT generators and deferred binding works, but for real work I recommend Google’s newish UiBinder (formerly called the Declarative UI). See this thread in the google group.
At a recent client of ThoughtWorks’, I was writing complex GWT views. If you’ve ever worked with Google Web Toolkit, you know the pain that this can involve. Instead of creating HTML files of templates, you need to build the DOM programatically with your own widgets, 3rd party widgets, or the basic widgets GWT gives you. I wrote a simple templating system to meet my needs. Maybe it will help you too, please feel free to request features and share if it helps you.
If you try JAW’s Very Simple GWT Template, all you need to do is follow a few conventions and you get the following.
- Create a html file with your complex layout. For instance a really fancy 12×12 html table with all sorts of colspans and rowspans for displaying detailed tabular data.
- Create a value object (in Java, on the GWT side) that you want to automatically use to dump some attributes into the template.
- In the html template, use ${valueObject.someProperty} style notation where you want automatic setting of values into the template.
- In the html template, use $${specialDoubleDollarSign} notation where you want to manually bind the template values.
Really, it is very simple and no frills. It solved my need of presenting data in a visually rich way, into html that a designer could produce without any knowledge of GWT. Also, you can embed it into other widgets, or other widgets into it.
I think it’s cool in two ways:
- Automatic data binding from your value object, into the ${myObj.property} template slots.
- Ability to manually attach complex widgets (with GWT defined event behavior), into the $${doubleDollarSignSlot} template slots.
I’ve created a Google Code project with the source code and some examples (as tests). Please take a look and leave criticism and feedback.
If you’re curious how this is implemented, it’s all with defered binding and generators in GWT. As all code I actually want to work, I’ve test driven it and you can look at the tests for details.
Linking to Miško’s, Russ’ and my Testability Guide
Reading time: 4 – 6 minutes
I had the great pleasure of collaborating with Miško Hevery and Russ Rufer in creating the Guide for Writing Testable Code. Please feel free to check it out, and leave comments here or on his blog.
Here’s a peek at the different flaws to watch out for, and warn your co-workers about. If you see this in code that is getting checked in, bring it to the attention to your team. See Miško’s post for the full list.
Flaw #1: Constructor does Real Work (link)
- If you have a constructor that is doing “work” you’ve established a contract that everyone who wants to create this object also is forced to wait for that “work” to happen. This becomes a huge problem in small unit tests. Frequently unit tests create many, many instances of the object under test – and any work you do in the constructor slows down tests.
- The solution? Break up the responsibility into two objects: a builder of factory to do all the heavy lifting to construct the object, and whatever the original object was that had the heavy constructor. When you split the responsibilities up you will have a better object oriented design, and make it easy for more flexible construction. If you’re tempted to create an init() method and put the work in there – avoid this siren song. It’s a smell of mixed responsibilities and a poorly behaving object that isn’t really ready when the constructor completes.
- Warning signs are:
- new keyword in a constructor or at field declaration
- Static method calls in a constructor or at field declaration
- Anything more than field assignment in constructors
- Object not fully initialized after the constructor finishes (watch out for initialize methods)
- Control flow (conditional or looping logic) in a constructor
- Code does complex object graph construction inside a constructor rather than using a factory or builder
- Adding or using an initialization block
Flaw #2: Digging into Collaborators (link)
- Jumping from one object to another to another to get what you want makes for hard to test and hard to refactor code. This is commonly viewed as the Law of Demeter violation, however you can dig into collaborators without breaking the letter of the law. This is hard to work with in tests, because your tests need to do a great deal of setup stuffing objects in objects into other objects, or else you’ll get null pointers.
- Warning signs are:
- Objects are passed in but never used directly (only used to get access to other objects)
- Law of Demeter violation: method call chain walks an object graph with more than one dot (.)
- Suspicious names: context, environment, principal, container, or manager
Flaw #3: Brittle Global State & Singletons (link)
- Global state (usually made possible through the static keyword in Java) creates hard to test and modify code. Parallelizing tests is often impossible, and tests that forget to clean up the global state after running interact undesirably with other tests (causing unexpected failures).
- Warning signs are:
- Adding or using singletons
- Adding or using static fields or static methods
- Adding or using static initialization blocks
- Adding or using registries
- Adding or using service locators
Flaw #4: Class Does Too Much (link)
- Object oriented design allows you to split responsibilities into individually tested objects. Using an object oriented language does not prevent people from writing procedural code. In fact, most times when someone does not want to write tests it is because their code is hard to test.
- Warning Signs:
- Summing up what the class does includes the word “and”
- Class would be challenging for new team members to read and quickly “get it”
- Class has fields that are only used in some methods
- Class has static methods that only operate on parameters
There’s typically no magic wand to wave and make hard to test code instantly testable. Engineers need to have an open mind and learn how to write code designed for testability. (In my experience 90% of the time this involves test driven design and test driven development.) These ideas above, and many of Miško’s other posts are a fantastic starting point for adopting that new way of thinking.
Please link it up with your favorite testability mindset readings.


