<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2532776359713754015</id><updated>2012-01-10T13:20:14.015-08:00</updated><category term='Culture'/><category term='Code'/><category term='Ivy'/><category term='Craft'/><category term='Play Java Lombok'/><category term='GWT'/><category term='Passion'/><category term='Gradle'/><category term='Java'/><category term='Eclipse'/><category term='Builds'/><title type='text'>Technically Possible</title><subtitle type='html'>Thoughts about software, business and technology</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-6272796079831014681</id><published>2011-04-26T20:40:00.000-07:00</published><updated>2011-05-13T21:01:48.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Play Java Lombok'/><title type='text'>Getting Lombok to Play!</title><content type='html'>&lt;i&gt;The approach in this post works, but I created a Play! module that makes is easier. You can find it here:&amp;nbsp;&lt;/i&gt;&lt;a href="https://github.com/aaronfreeman/play-lombok"&gt;https://github.com/aaronfreeman/play-lombok&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Recently I've been getting back in to using &lt;a href="http://www.playframework.org/"&gt;Play!&lt;/a&gt; for web development. I've built something small with it before, and it definitely is my favorite Java web framework. But there are still some things about Java that bug me. One of them is a complete lack of type inference. Static typing can be useful, but becomes a real annoyance if the compiler doesn't help you out a lot. In C# they have some basic type inference using the 'var' keyword and I have long wished Java would have something like that.&lt;br /&gt;&lt;br /&gt;Then today I came across &lt;a href="http://projectlombok.org/"&gt;Project Lombok&lt;/a&gt;. It makes use of the AST transformations in the Java compiler to add features to Java. It can do some pretty cool stuff, and even integrates into your IDE so everything works as expected. And one of the features it has... yep, a 'val' keyword that does basic type inference. Nice! So you can do things like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: scala;"&gt;val aList = Arrays.asList("Hello", "World");&lt;br /&gt;for(val s : aList)&lt;br /&gt;  System.out.println(s);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Behind the scenes Lombok turns the first 'val' in to "final List&amp;lt;String&amp;gt;" and the second into "final String". This is great!&lt;br /&gt;&lt;br /&gt;One my first thoughts after seeing this was, can I get it to work with Play! Since most frameworks simple compile with javac Lombok is pretty simple to get working, you just have to have it on the compile class path. But Play! is a little different. It actually has a built in compiler (it uses the Eclipse compiler) and it compiles your code at runtime. This is great in development because it mean you and change Java code and just refresh our window and Play! will recompile the code and run the updated code. So no more restarting the server, or having to run in debug mode (which doesn't work for a lot of code changes anyway). It really makes things so much easier. But it also means in order to get Lombok to work, you have to get the Play! compiler to know about it. I couldn't find anyone saying how to do this, which is why I'm writing this.&lt;br /&gt;&lt;br /&gt;I'll spare you the&amp;nbsp;gory&amp;nbsp;details of how I figured it out, because it took quite a while, but once I figured it out it's pretty simple to do.&lt;br /&gt;&lt;br /&gt;First what you have to do it get Lombok into you Play! project. If you're using Play! 1.2, it's pretty simple (if you aren't yet using 1.2, you should really consider upgrading, lots of good stuff there). Just go to your dependencies.yml file and add Lombok. Like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;require:&lt;br /&gt;  - play&lt;br /&gt;  - org.projectlombok -&amp;gt; lombok 0.9.3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now this will work just fine, but if you're like me and you want the val keyword, you have to use the beta version of Lombok, which is in the maven repo. So you'll have to down load it and put it in your project. Easy enough, I put it in a jars folder under my project root and changed the dependencies.yml file to look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;repositories:&lt;br /&gt;  - local:&lt;br /&gt;    type:       local&lt;br /&gt;    artifact:   "${application.path}/jars/[module]-[revision].[ext]"&lt;br /&gt;    contains:&lt;br /&gt;      - org.projectlombok -&amp;gt; *&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we've got the jar, we just have to let Play! know about it when it compiles. I figured this out by reading what Lombok says it does to Eclipse to get it to work, and then duplicated it with Play! In order for Lombok to work, it has to be registered as a java agent, and be on the boot classpath. This can be done using JVM arguments -javaagent and -Xbootclasspath/a. The difficulty is in figuring out how to add these JVM arguments to the Play! startup process. The only way I know of is by making use of the jvm.memory config param in the applicaiton.conf file. This param just gets appended to the call to start the JVM, so you can really put any JVM arguments in there. So I added this line to my application.conf:&lt;br /&gt;&lt;br /&gt;jvm.memory=-javaagent:lib/lombok-0.10.0-BETA2.jar -Xbootclasspath/a:lib/lombok-0.10.0-BETA2.jar&lt;br /&gt;&lt;br /&gt;That almost does the trick. The only problem now is you'll get an error at startup saying it can't find the Eclipse compiler. That's because Lombok is now referencing it, but it's not at the right level in the classpath to be accessed. So we just need to add it to the bootclasspath, too. So now the arguments look like this:&lt;br /&gt;&lt;br /&gt;jvm.memory=-javaagent:lib/lombok-0.10.0-BETA2.jar -Xbootclasspath/a:lib/lombok-0.10.0-BETA2.jar -Xbootclasspath/a:/opt/play/1.2/framework/lib/org.eclipse.jdt.core-3.6.0.jar&lt;br /&gt;&lt;br /&gt;Now when you run Play! from the command line it will have Lombok available when it compiles your app. If you are using Eclipse and the eclipse launch configurations generated by Play!, you just need to add the parameters above to the VM arguments of the launch configuration and it should work fine.&lt;br /&gt;&lt;br /&gt;Now go and use some type inference!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-6272796079831014681?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/6272796079831014681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2011/04/getting-lombok-to-play.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6272796079831014681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6272796079831014681'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2011/04/getting-lombok-to-play.html' title='Getting Lombok to Play!'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-7908931664748498231</id><published>2011-04-20T12:11:00.000-07:00</published><updated>2011-04-20T19:38:15.637-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Craft'/><category scheme='http://www.blogger.com/atom/ns#' term='Culture'/><title type='text'>Overemphasizing technical practices</title><content type='html'>I've been wondering lately if overemphasizing technical practices might be detrimental to a company in the long run. I'm not saying you don't need talented people, I certainly believe you do. I mean as a company (or department), making a big deal about whether a team/person does TDD, CI, or some other good practice. In the short run you'll probably get an increase in good habits among your developers.&amp;nbsp;However, my concern here is that in the long run I think you're likely to create a culture that cares more about whether you're doing those practices than whether you're creating great products. Once a company switches to caring more about &lt;i&gt;how&lt;/i&gt; it's doing things than &lt;i&gt;what&lt;/i&gt; it's doing, problems start&amp;nbsp;escalating&amp;nbsp;rapidly. (Incidentally this one of the points that Jim Collins makes in &lt;a href="http://www.amazon.com/How-Mighty-Fall-Companies-Never/dp/0977326411"&gt;How The Mighty Fall&lt;/a&gt;, great book!)&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We have to remember that customers don't pay for or care about stories, TDD, CI, and many other good software development practices. They want, and pay for, awesome products! (Or &lt;a href="http://www.globalnerdy.com/2009/10/17/its-about-helping-your-users-become-awesome-or-being-better-is-better-by-kathy-sierra/"&gt;as Kathy Sierra would say&lt;/a&gt;, products that make them awesome) I'm not saying you can't encourage good practices. You can! I just think you need to first make it clear that the goal is to build awesome products, and then let/help people gravitate to the practices that best allow them to&amp;nbsp;achieve&amp;nbsp;that goal. That way they are never confused about what is really important.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-7908931664748498231?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/7908931664748498231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2011/04/overemphasizing-technical-practices.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/7908931664748498231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/7908931664748498231'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2011/04/overemphasizing-technical-practices.html' title='Overemphasizing technical practices'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-8515414943178919579</id><published>2010-06-08T22:58:00.001-07:00</published><updated>2010-06-08T22:58:56.145-07:00</updated><title type='text'>On Design</title><content type='html'>&lt;p&gt;The most important thing to learn about design is that it’s all about trade-offs. There are no perfect designs. Every design has a down side, some draw drawback that will cause difficulties. The is true for all kinds of design whether it’s a building, an organization, a user interface, or software.&lt;/p&gt;  &lt;p&gt;Since all designs have problems, the designers job is not to get rid of all problems in the design, it’s to decide which problems are the least costly to have, or which problems are most likely to cause the least damage to the goal of the product. So, to do design well you have to be able to understand what the options are, what the issues are with each option, and in the particular context you are operating in, which issues are the least harmful.&lt;/p&gt;  &lt;p&gt;It’s important to understand this when it comes to software design patterns. Design patterns are just common ways of trading one set of problems for another, with the belief that the new set of problems is better than the old. The only time it makes sense to use a pattern is when you have the particular set of problems it was designed to fix, &lt;em&gt;and&lt;/em&gt; you’re better off with the new set of problems it leaves you with. But, in order to make good decisions on this, you’ve got to understand what the problem sets are, and how they affect your particular context.&lt;/p&gt;  &lt;p&gt;This is not easy! And it takes experience to do it well. Often, the only way to know what the issues are with a particular design choice is that you’ve done it that way before, and seen what issues came from it. However, studying, practicing, and learning from others can take you a long way. The important thing is to never to be fooled into thinking that there are no drawbacks to a particular design decision.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-8515414943178919579?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/8515414943178919579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/06/on-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/8515414943178919579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/8515414943178919579'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/06/on-design.html' title='On Design'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-2038662727875956006</id><published>2010-06-01T22:04:00.001-07:00</published><updated>2010-06-01T22:15:23.879-07:00</updated><title type='text'>Auto injection in jUnit</title><content type='html'>&lt;p&gt;After doing Java for many years, and TDD for several, I’ve settled into a fairly consistent way of designing and testing my classes. Any time you start to following a pattern in your code, if you’re paying attention, you’ll notice you’re writing the same code over and over. Now, it usually isn’t exactly the same or you’d easily just move it into a class and use the class. No, it’s usually code that is different every time, but it’s essentially doing the same thing, just with different classes. This is one example of what is generally referred to as &lt;a href="http://en.wikipedia.org/wiki/Boilerplate_(text)#Boilerplate_code"&gt;boilerplate code&lt;/a&gt;. It’s aso one of the subtle forms of &lt;a href="http://technicallypossible.blogspot.com/2010/05/code-duplication-is-evil.html"&gt;code duplication&lt;/a&gt;, and it’s something you want to avoid as much as possible.&lt;/p&gt;&lt;p&gt;I recently noticed that due to how I write my classes and tests, around 95% or more of my setup methods in my tests consisted of creating the class to be tested, creating some mocks, stubs, or fakes, and then injecting them into the class. Sure, technically every setup method was different, but this was boilerplate code for sure. And it was starting to get on my nerves. The setup usually looked something like this:&lt;/p&gt;&lt;pre class="brush: java;"&gt;public class TestFoo {&lt;br /&gt;   private Foo foo;&lt;br /&gt;   private DependencyOne dependencyOne;&lt;br /&gt;   private DependencyTwo dependencyTwo;&lt;br /&gt;&lt;br /&gt;   @Before&lt;br /&gt;   public void setup() {&lt;br /&gt;      foo = new Foo();&lt;br /&gt;      dependencyOne = new DependencyOneMock();&lt;br /&gt;      dependencyTwo = new DependencyTwoMock();&lt;br /&gt;      foo.setDependencyOne(dependencyOne);&lt;br /&gt;      foo.setDependencyTwo(dependencyTwo);&lt;br /&gt;   }&lt;br /&gt;   ... then all the tests&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;One of the best ways to attack boilerplate code is by using the concept of convention over configuration. Basically all my setup methods were just configuration of the class I was testing, so what I needed to do is come up with a convention that made the configuration unnecessary, and some way to act upon the convention.&lt;/p&gt;&lt;p&gt;The convention starts with the &lt;em&gt;@Target &lt;/em&gt;annotation. The idea is that you put this annotation on a field to signify that the field is the target of the test class that will need to have dependencies injected into it. You can also put &lt;em&gt;@Target&lt;/em&gt; on a method, and whatever is returned from the method will be used as the target for injection.&lt;/p&gt;&lt;p&gt;Secondly, when you define a field on the test class if it matches a setter method on the target class, then it will be injected into the target using the setter. If no setter is found, but there is a field with the same name on the target, then the value will be copied to the field on the target.&lt;/p&gt;&lt;p&gt;In order to actually act on this convention I used the jUnit &lt;em&gt;@Rule&lt;/em&gt; annotation. I called my rule AutoMockAndInject. If you aren’t familiar with how this annotation works, you can read about it &lt;a href="http://blog.mycila.com/2009/11/writing-your-own-junit-extensions-using.html"&gt;here&lt;/a&gt;. I will put the code for my rule and the target annotation at the bottom of this post.&lt;/p&gt;&lt;p&gt;So, following the convention and using the rule my test class now looks like this:&lt;/p&gt;&lt;pre class="brush: java;"&gt;public class TestFoo {&lt;br /&gt;@Rule public AutoMockAndInject autoInject = new AutoMockAndInject();&lt;br /&gt;@Target private Foo foo = new Foo();&lt;br /&gt;private DependencyOne dependencyOne = new DependencyOneMock();&lt;br /&gt;private DependencyTwo dependencyTwo = new DependencyTwoMock();&lt;br /&gt;&lt;br /&gt;   ... then all the tests&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;One thing to remember here is that jUnit creates a new instance of the test class for each test method it runs. Otherwise, doing it this way could cause some problems.&lt;/p&gt;&lt;p&gt;I also use &lt;a href="http://code.google.com/p/mockito/"&gt;Mockito&lt;/a&gt; when I don’t want to make a hand written mock. The AutoMockAndInject rule works with the &lt;em&gt;@Mock&lt;/em&gt; annotation from Mockito. It will create the mock object and inject it into the target. So if I want to use Mocito for my dependencies instead of hand written ones, the test class would look like this:&lt;/p&gt;&lt;pre class="brush: java;"&gt;public class TestFoo {&lt;br /&gt;@Rule public AutoMockAndInject autoInject = new AutoMockAndInject();&lt;br /&gt;@Target private Foo foo = new Foo();&lt;br /&gt;@Mock private DependencyOne dependencyOne;&lt;br /&gt;@Mock private DependencyTwo dependencyTwo;&lt;br /&gt;&lt;br /&gt;   ... then all the tests&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;I just started doing this a couple weeks ago, and so far I like it. It’s cut down on a lot of boilerplate code. But, in my experience, it usually takes at least a few months of doing something before you really see if it was a good idea or not. So, we’ll see if in the long run it really makes thing better.&lt;/p&gt;&lt;p&gt;Here is the code for my annotation and the jUnit rule I used for doing this. &lt;/p&gt;&lt;pre class="brush: java;"&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;public @interface Target {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class AutoMockAndInject implements MethodRule {&lt;br /&gt;   private static final String specialFields = &amp;quot;$VRc,serialVersionUID&amp;quot;;&lt;br /&gt;   private Object target;&lt;br /&gt;&lt;br /&gt;   public final Statement apply(final Statement base, FrameworkMethod method, final Object target) {&lt;br /&gt;      return new Statement() {&lt;br /&gt;         @Override public void evaluate() throws Throwable {&lt;br /&gt;            before(target);&lt;br /&gt;            base.evaluate();&lt;br /&gt;         }&lt;br /&gt;      };&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   protected void before(Object source) throws Throwable {&lt;br /&gt;      createMockitoMocks(source);&lt;br /&gt;      if (hasTargetAnnotation(source))&lt;br /&gt;      autoInject(source);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void createMockitoMocks(Object source) {&lt;br /&gt;      MockitoAnnotations.initMocks(source);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean hasTargetAnnotation(Object source) throws Exception {&lt;br /&gt;      return hasTargetFiled(source) || hasTargetMethod(source);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean hasTargetMethod(Object source) throws Exception {&lt;br /&gt;      for (Method method : source.getClass().getMethods()) {&lt;br /&gt;         if (method.getAnnotation(Target.class) != null) {&lt;br /&gt;            target = method.invoke(source);&lt;br /&gt;            return true;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean hasTargetFiled(Object source) throws Exception {&lt;br /&gt;      for (Field field : getAllFields(source.getClass())) {&lt;br /&gt;         if (field.getAnnotation(Target.class) != null) {&lt;br /&gt;            target = getFieldValue(source, field);&lt;br /&gt;            return true;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private Object getFieldValue(Object target, Field field) throws Exception {&lt;br /&gt;      field.setAccessible(true);&lt;br /&gt;      return field.get(target);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private Set&amp;lt;Field&amp;gt; getAllFields(Class&amp;lt;?&amp;gt; clazz) {&lt;br /&gt;      return getAllFields(new HashSet&amp;lt;Field&amp;gt;(), clazz);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private Set&amp;lt;Field&amp;gt; getAllFields(Set&amp;lt;Field&amp;gt; fields, Class&amp;lt;?&amp;gt; clazz) {&lt;br /&gt;      for (Field field : clazz.getDeclaredFields())&lt;br /&gt;         if (notSpecialField(field))&lt;br /&gt;            fields.add(field);&lt;br /&gt;      if (clazz.getSuperclass() != null)&lt;br /&gt;         getAllFields(fields, clazz.getSuperclass());&lt;br /&gt;      return fields;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean notSpecialField(Field field) {&lt;br /&gt;      return !specialFields.contains(field.getName());&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void autoInject(Object source) throws Exception {&lt;br /&gt;      ensureTargetExists();&lt;br /&gt;      Set&amp;lt;Field&amp;gt; targetFields = getAllFields(target.getClass());&lt;br /&gt;      for (Field field : getAllFields(source.getClass()))&lt;br /&gt;         if (!callSetterIfExists(source, field))&lt;br /&gt;            setFieldIfExists(source, targetFields, field);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void ensureTargetExists() {&lt;br /&gt;      if (target == null)&lt;br /&gt;         throw new RuntimeException(&amp;quot;Target value is null, did you forget to create it?&amp;quot;);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private boolean callSetterIfExists(Object source, Field field) throws Exception {&lt;br /&gt;      Method method = getMethod(target, getSetterName(field));&lt;br /&gt;      if (method != null) {&lt;br /&gt;         method.invoke(target, getFieldValue(source, field));&lt;br /&gt;         return true;&lt;br /&gt;      }&lt;br /&gt;      return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private Method getMethod(Object target, String setterName) {&lt;br /&gt;      for (Method method : target.getClass().getMethods())&lt;br /&gt;         if (method.getName().equals(setterName))&lt;br /&gt;            return method;&lt;br /&gt;      return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private String getSetterName(Field field) {&lt;br /&gt;      return &amp;quot;set&amp;quot; + StringUtils.capitalize(field.getName());&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void setFieldIfExists(Object source, Set&amp;lt;Field&amp;gt; targetFields, Field field) throws Exception {&lt;br /&gt;      Field destField = getField(field.getName(), targetFields);&lt;br /&gt;      if (destField != null)&lt;br /&gt;         setField(target, destField, getFieldValue(source, field));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private Field getField(String name, Set&amp;lt;Field&amp;gt; fields) {&lt;br /&gt;      for (Field field : fields)&lt;br /&gt;         if (field.getName().equals(name))&lt;br /&gt;            return field;&lt;br /&gt;      return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private void setField(Object target, Field destField, Object fieldValue) throws Exception {&lt;br /&gt;      destField.setAccessible(true);&lt;br /&gt;      destField.set(target, fieldValue);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-2038662727875956006?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/2038662727875956006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/06/auto-injection-in-junit.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2038662727875956006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2038662727875956006'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/06/auto-injection-in-junit.html' title='Auto injection in jUnit'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-6927315187543704569</id><published>2010-05-27T21:16:00.001-07:00</published><updated>2010-05-28T06:30:21.024-07:00</updated><title type='text'>Code duplication is evil</title><content type='html'>&lt;p&gt;As you’re programming, have you ever had the sense that a great evil was lurking in your code base? Well, most likely there is, and it’s name is: code duplication! This monster will sneak it’s way into your code with the promise of “fast” implementation and a “simple” solution. But make no mistake, once it has a foothold in your code base, what you thought was your friend will turn on you with a vengeance and destroy you. The code will rot in it’s place, and you’ll be cursed with recurring bugs that come back because you only fixed them in one place. Then your friends will laugh at your plight and make up nick names for you like “Mr. Duplication” or “Copy and paste Man.” In the end you’ll be left homeless and penniless. Then you will rue the day that you ever gave in to the subtle and poisonous promises of code duplication. &lt;/p&gt;&lt;p&gt;I’m not sure everyone sees it this way, though. I’ve said for a while now that the best way I know of to get to a well factored system is to have an acute aversion to code duplication. Both the obvious and subtle forms of it. However, despite the fact that the &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY principle&lt;/a&gt; is well known, I find that many developers (perhaps most) not only often repeat themselves in their code, but they also seem to be unconcerned when they find duplicated code and have to modify it. Personally I think the latter is the biggest issue. &lt;/p&gt;&lt;p&gt;We all write bad code some times, and we do stupid things like giving in to the temptation to duplicate. Many strange and terrible things can be done in the heat of the moment while programming and trying to implement a feature (even if you are pairing). To ere is human and it’s perfectly understandable. However, to come across blatant duplication and not only do nothing about it, but to be unmoved by it, that my friends is inexcusable.&lt;/p&gt;&lt;p&gt;Of all the &lt;a href="http://c2.com/cgi/wiki?CodeSmell"&gt;code smells&lt;/a&gt; there are, code duplication is one of the most telling. So much can be learned from it, if you’re paying attention. Some times it can tell you that your design is not quite right. Or that you’re missing an abstraction. Or that you’re thinking about the problem in the wrong way. Often a lot of code duplication can be removed by solving the coding problem from a different angle.&lt;/p&gt;&lt;p&gt;There’s more that can be learned than just the few things I mentioned, but you will see none of these things if, when you encounter code duplication, you merely make the required changes in multiple places. You have to learn to hate it! You should be outraged by it. Don’t stand for it! When you see blatant code duplication, leap out of your chair, grab your keyboard and start slamming in on the table while yelling at your monitor, “NO! NO! NO! NO!” Sure, everyone will think you’re crazy, and I suppose you might even get fired, but after an out burst like that you’ll be determined to do something about the duplication. And, who knows, after a few of them, maybe others will be more careful about it, being frightened by what you might do next time.&lt;/p&gt;&lt;p&gt;When you see the evil of code duplication, don’t let yourself be unmoved by it. Be outraged if it helps, but do something about it. How long will we allow this great evil of our time to endure? As the saying goes: all that is necessary for the triumph of evil is that good programmers do nothing. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-6927315187543704569?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/6927315187543704569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/05/code-duplication-is-evil.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6927315187543704569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6927315187543704569'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/05/code-duplication-is-evil.html' title='Code duplication is evil'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-2978702387922246040</id><published>2010-02-24T21:41:00.001-08:00</published><updated>2010-02-24T21:41:11.187-08:00</updated><title type='text'>Good article on Gradle</title><content type='html'>&lt;p&gt;I happen to come across this great introductory article about Gradle:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.javaexpress.pl/article/show/Gradle__a_powerful_build_system"&gt;http://www.javaexpress.pl/article/show/Gradle__a_powerful_build_system&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It’s a lot better than &lt;a href="http://technicallypossible.blogspot.com/2010/01/gradle-building-with-bliss.html"&gt;the one I wrote&lt;/a&gt;, and should get you going in no time.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-2978702387922246040?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/2978702387922246040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/02/good-article-on-gradle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2978702387922246040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2978702387922246040'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/02/good-article-on-gradle.html' title='Good article on Gradle'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-4587698927362197417</id><published>2010-02-23T21:47:00.000-08:00</published><updated>2010-02-24T22:18:26.829-08:00</updated><title type='text'>Gradle: building with bliss</title><content type='html'>&lt;p&gt;I’ve used &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; for years, and though the XML can get annoying, it’s a great tool. It’s so flexible, and once you understand it, you can do anything with it. &lt;a href="http://gant.codehaus.org/"&gt;Gant&lt;/a&gt; addresses the XML issue by introducing a Groovy syntax for writing Ant scripts. But one of the biggest issues with Ant, in my opinion, is the amount you have to write just to get a basic build that compiles some classes, runs some test, and builds a JAR or WAR.&lt;/p&gt;&lt;p&gt;One solution to this is &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;. Another nice tool, though it uses XML also. With Maven you can have a build up and running in minutes. But Maven takes a rather radical approach. With Maven, you don’t have a build file, you have a Project Object Model (POM). You use the POM to declaratively describe your project. Then all the Maven plugins use that information and fallow a build lifecycle to do the actual build. So, you don’t have a build file anymore, the build is just something that happens based on what you have in your POM. The Maven people are pretty big on the whole declarative POM describing your project. This line of thought is illustrated by a quote from the &lt;a href="http://maven.apache.org/plugins/maven-antrun-plugin/"&gt;Maven AntRun Plugin page&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;It is &lt;i&gt;not&lt;/i&gt; the intention of this plugin to provide a means of polluting the POM, so it's encouraged to move all your Ant tasks to a &lt;tt&gt;build.xml&lt;/tt&gt; file and just call it from the POM using Ant's &amp;lt;ant/&amp;gt; task&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In other words, “don’t defile our beautifully declarative POM with your dirty procedural Ant scripts.”&lt;/p&gt;&lt;p&gt;The declarative concept is really neat in theory, but builds are a procedural process. So at times it feels to me like Maven is forcing something unnatural. And any time you want to add just a bit of logic to your build, you have to go through the effort of writing your own Maven plugin or do it in Ant and use the AntRun plugin. Seems like it should be easier than that, to me.&lt;/p&gt;&lt;p&gt;So, what I really want is a tool as powerful as Ant, as easy to add logic to as Gant, and as quick to setup as Maven. That’s exactly what &lt;a href="http://www.gradle.org/"&gt;Gradle&lt;/a&gt; is. It has tight integration with Ant, so anything you can do in Ant you can do in Gradle. It uses Groovy for the build scripts like Gant, so adding a bit of logic is easy and natural. And it has a build by convention concept (via plugins) like Maven that allows you to have a build running with a minimal amount of effort.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The most basic build&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Here is the most basic Gradle build file you can have for a Java project. In your project root directory create a file called build.gradle and put this line in it&lt;/p&gt;&lt;pre class="brush: groovy;"&gt;usePlugin 'java'&lt;/pre&gt;&lt;p&gt;If you follow the Gradle convention (meaning you put your source code in src/main/java), this one line build file will allow you to compile and JAR your project. By default the name of your project that Gradle uses (and the name on the JAR) is the name of the folder that contains the build.gradle file. To learn how to actually run the build, check out the &lt;a href="http://www.gradle.org/0.8/docs/userguide/userguide.html"&gt;Gradle user guide&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Running some test&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;To actually run some tests, we’ll have to add some more too our build. Again, we’ll follow the Gradle convention of putting test in the src/test/java folder and change the build file to look like this:&lt;/p&gt;&lt;pre class="brush: groovy;"&gt;usePlugin 'java'&lt;br /&gt;&lt;br /&gt;repositories {&lt;br /&gt;   mavenCentral()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;dependencies {&lt;br /&gt;   testCompile 'junit:junit:4.4'&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;With this build file we can now compile our code, compile our tests, run the jUnit tests, and create a JAR. Not bad for just a few lines of Groovy.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Changing the source locations&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If you don’t want to follow the Gradle conventions, you can change the locations of your source files and test files. To do this you use the Source Sets concept from the Gradle Java plugin. Adding this code to the build file will change you source location to the src folder under the project root, and the tests to the test folder under the project root:&lt;/p&gt;&lt;pre class="brush: groovy;"&gt;sourceSets {&lt;br /&gt;   main {&lt;br /&gt;      java {&lt;br /&gt;         srcDir 'src'&lt;br /&gt;      }&lt;br /&gt;      resources {&lt;br /&gt;         srcDir 'src'&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   test {&lt;br /&gt;      java {&lt;br /&gt;         srcDir 'test'&lt;br /&gt;      }&lt;br /&gt;      resources {&lt;br /&gt;         srcDir 'test'&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;There’s a lot more to learn about Gradle, and I may post more about it in the future. If you want to learn more, check out the &lt;a href="http://www.gradle.org/0.8/docs/userguide/userguide.html"&gt;user guide&lt;/a&gt;. But honestly the best thing I can say about Gradle is that I barely spend much time working with it. It’s so flexible and easy to work with that most of the time when I need to add something to a build file I can get in there add the logic I need quickly and get it all working in a few minutes, then get back to working on my software. Which is really what you want from a build tool because customers don’t care about builds! So you want a build tool that allows you to accomplish what you need as quickly and easily as possible, so you can get back to doing the work that your customers actually care about. To me, that’s where Gradle really shines.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-4587698927362197417?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/4587698927362197417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/gradle-building-with-bliss.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/4587698927362197417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/4587698927362197417'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/gradle-building-with-bliss.html' title='Gradle: building with bliss'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-2427330252124853001</id><published>2010-01-20T21:32:00.001-08:00</published><updated>2010-01-20T21:32:41.416-08:00</updated><title type='text'>Mercurial and Eclipse</title><content type='html'>&lt;p&gt;I’m not opposed to using the command line. Some times it’s the best way to get things done. But when it comes to source control I think having good IDE integration really helps with productivity. I’ve been in situations before where there wasn’t good integration, and, though you can certainly get things done like that, I end up fighting with the VCS more often. I think this is especially true when you are working in a team.&lt;/p&gt;  &lt;p&gt;So one of the first things I want to know when looking at a VCS is how good the IDE integration is. Thankfully VecTrace has created a good &lt;a href="http://www.vectrace.com/mercurialeclipse/"&gt;Eclipse plugin for Mercurial&lt;/a&gt;. It’s designed to use an external Mercurial executable. So you’ll have to install something like &lt;a href="http://tortoisehg.bitbucket.org/"&gt;TortoiseHg&lt;/a&gt; to do the actually Mercurial work. TortoiseHg is great and on the rare occasion where you can’t get the Eclipse plugin to do what you need, you can always use it, or the command line.&lt;/p&gt;  &lt;p&gt;If you are familiar with either the CVS or SVN plugins for Eclipse, the Mercurial one should feel pretty familiar. It’s pretty much the same for the common things like marking a file that needs to be committed, the commit dialog, synchronizing with the main repository, and showing history.&lt;/p&gt;  &lt;p&gt;One thing I really like about he Mercurial plugin is the intelligence it uses in marking a file as needing to be committed. With most plugins I’ve used in the past if a file is modified in any way, the IDE flags it has needing to be committed. Even if you undo the changes that you made, it will usually still flag it as needing to be committed. With the Mercurial plugin a file will only be flagged as needing a commit if it’s actually different from the latest version in the repo. So if you change a file, save it, then change it back, it will not show as needing a commit. It’s a small feature, but one I appreciate.&lt;/p&gt;  &lt;p&gt;A lot of the time when you have to merge two change sets, the Mercurial will be able to merge them automatically. When there are conflicting changes, however, you’ll have to use the plugin’s merge manager. For the file comparisons it uses the same windows as the other plugins, but there is another view to show the merge status:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_NHUhlj9iZ0A/S1fm7SyCoyI/AAAAAAAAAPo/pcsNEDgID7g/s1600-h/mercurial_merge_manager%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="mercurial_merge_manager" border="0" alt="mercurial_merge_manager" src="http://lh5.ggpht.com/_NHUhlj9iZ0A/S1fm78iWTKI/AAAAAAAAAPs/c2CJ5Zvk6sM/mercurial_merge_manager_thumb%5B3%5D.png?imgmax=800" width="583" height="224" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this view you can double click the file with merge conflicts to resolve them. Then you can click ‘Mark resolved’ to mark the file resolved. You can also abort the merge from this view, or mark a file as no resolved.&lt;/p&gt;  &lt;p&gt;The last nice view that the plugin has is the History view. Here is picture of the history from my &lt;a href="http://code.google.com/p/easyb-junit/"&gt;Easyb jUnit&lt;/a&gt; project:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_NHUhlj9iZ0A/S1fm8uDhd9I/AAAAAAAAAPw/NNbg5SZQ7ZM/s1600-h/easyb_junit_history%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="easyb_junit_history" border="0" alt="easyb_junit_history" src="http://lh5.ggpht.com/_NHUhlj9iZ0A/S1fm9I3lqEI/AAAAAAAAAP0/kDK84XzfrnU/easyb_junit_history_thumb%5B2%5D.png?imgmax=800" width="584" height="205" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The history here shows each change set, who committed it, when it was committed along with the comment for the change set. From this view you can choose to update your code to any change set in the list.&lt;/p&gt;  &lt;p&gt;One the left side of the view is the Graph column. This shows how each change set relates to the others. The graph for this project isn’t very interesting since I’m the only developer on this one. So, here’s one from a project with multiple developers:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_NHUhlj9iZ0A/S1fm9qKTFUI/AAAAAAAAAP4/8R19f28WWPI/s1600-h/change_set_history%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="change_set_history" border="0" alt="change_set_history" src="http://lh6.ggpht.com/_NHUhlj9iZ0A/S1fm-F-mniI/AAAAAAAAAP8/HCXJ6mIO-PE/change_set_history_thumb%5B3%5D.png?imgmax=800" width="585" height="288" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This graph shows the branching and merging that went on in each change set.&lt;/p&gt;  &lt;p&gt;One more nice thing with Mercurial that’s not related to the Eclipse plugin is &lt;a href="http://bitbucket.org/"&gt;bitbucket.org&lt;/a&gt;. This is the Mercurial equivalent of GitHub. We are currently using it for hosting our repository, and we’re pretty happy with it. It has a lot of nice features, good pricing plans, and allows you to see everything about the project through the web site. There’s also some nice integration with Hudson (which also has a Mercurial plugin) that allows the change descriptions for a Hudson build to link directly to the Bitbucket diff page. Which makes it really easy to se what changed in a particular build and who change it. Good stuff!&lt;/p&gt;  &lt;p&gt;To sum it up, I’m really happy with Mercurial. It’s got speed, ease of use, good IDE integration, and a good repository hosting site. I highly recommend it!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-2427330252124853001?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/2427330252124853001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/mercurial-and-eclipse.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2427330252124853001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/2427330252124853001'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/mercurial-and-eclipse.html' title='Mercurial and Eclipse'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_NHUhlj9iZ0A/S1fm78iWTKI/AAAAAAAAAPs/c2CJ5Zvk6sM/s72-c/mercurial_merge_manager_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-3905505933321988112</id><published>2010-01-12T22:42:00.000-08:00</published><updated>2010-01-13T07:00:29.676-08:00</updated><title type='text'>Mercurial: the basics</title><content type='html'>&lt;p&gt;The first thing you have to understand when looking at Mercurial is what a Distributed Version Control System (DVCS) is, how it's different then things like Subversion or CVS, and why you would want to use it. So, let me start with a brief answer to those questions.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What and Why&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Centralized version control systems like CVS, Subversion, Perforce, and the like operate by having a centralized repository server. Then each client does a checkout of the code from the centralized repository, makes changes, and commits their changes back to the server. A DVCS like Mercurial and Git differ from these in two main ways.&lt;/p&gt;&lt;p&gt;One, when a person wants to get the code form a repository, they don't just checkout the latest version. They actually copy (or clone) the entire repository. They actually pull down every revision of every file in the repo. This only has to be done once, from then on they just have to do an update to pull down any new changes to the repo. Then the person works with their local repo until they are ready to push their changes back to the main repo.&lt;/p&gt;&lt;p&gt;Two, the fact that everyone has a full copy of the repo means this is more of a peer-to-peer technology than a client-server technology. That is, with centralized version control it is clear that the server is the master repo, since it alone holds all the data. But with DVCS everyone holds all the data, so the only thing that makes one repo the master repo is that everyone working on the project decided it would be the master repo. But there is technically no difference between the master repo and all the cloned repos on other peoples machines. We'll talk about the effects of this more as we continue, but lets move on for now.&lt;/p&gt;&lt;p&gt;So, why would you want to use a DVCS? One of the things that I like about it is since it's peer-to-peer there's no server to run. If you want fancy things like web access to a repository, then you'll have to run some kind of server, but if all you want is a repository on your local machine or on your network, then all you need is a directory. All of the logic for a DVCS is in the program that runs on the client. So if you're working on something alone, but you want version control, DVCS is the easiest thing to setup. And if your on a large team of developers, it just so happens that DVCS will work really well for that, too.&lt;/p&gt;&lt;p&gt;With DVCS merging just becomes a way of life. But because of the way it works, merging is usually a lot easier than it can be with centralized version control systems. Also, since each peer has a full copy of the repository, it's like a bunch of automatic backups of your repo. Server crashed? Can't get your main repository back? Not a problem! Just have one of the peers copy their repository to a central location, and have everyone start pushing their changes to it.&lt;/p&gt;&lt;p&gt;Before I started using Mercurial I had heard a lot about DVCS and never understood why everyone thought it was so great. Now I've been using Mercurial for a couple months and there is no way I would ever want to use something like Subversion or CVS again. It is so much faster and better to work with. If you'd like to read more about why DVCS, check out Chapter 1 of Mercurials' definitive guide called &lt;a href="http://hgbook.red-bean.com/read/how-did-we-get-here.html" target="_blank"&gt;How did we get here?&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Mercurial vs GIT&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Before I say anything on this, let me say that I agree with many others who have said that the important thing is moving from centralized version control to distributed version control. Deciding which DVCS to use is really just a matter of preference. Bot Mercurial and Git are great.&lt;/p&gt;&lt;p&gt;So, why did I go with Mercurial? To be quite honest it's mostly because I tried to get Git working on my machine once, and couldn't figure it out (probably because I didn't understand it). Then, a while later I tried to get Mercurial working, and got it working right away. I'm not sure if my problems with Git were normal, or just plain ignorance on my part, but the end result was I just stuck with Mercurial since then.&lt;/p&gt;&lt;p&gt;Git does seem to have more momentum around the development community, and it looks as though Eclipse might be embracing it as the sanctioned DVCS for Eclipse. But right now the Mercurial plugin for Eclipse seems much farther along that the one for Git. Also, the support for Git on Windows is fare behind that of Mercurial, and with the 139 Git commands it seems quite a bit more complex.&lt;/p&gt;&lt;p&gt;On a very technical side, the Mercurial definitive guide points this out, and I'm sure this is totally unbiased ;)&lt;/p&gt;&lt;blockquote style="clear: both;"&gt;While a Mercurial repository needs no maintenance, a Git repository requires frequent manual “repacks” of its metadata. Without these, performance degrades, while space usage grows rapidly. A server that contains many Git repositories that are not rigorously and frequently repacked will become heavily disk-bound during backups, and there have been instances of daily backups taking far longer than 24 hours as a result. A freshly packed Git repository is slightly smaller than a Mercurial repository, but an unpacked repository is several orders of magnitude larger.&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;But, as I said, the important thing is moving to DVCS, not which one you choose.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Change Sets&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;One of the most important concepts with Mercurial is the Change Set. A change set is a set of files who's modifications where committed to the repo all at once with a commit command. Every change set has a globally unique identifier assigned to it so that Mercurial can always tell one change set from another no matter what machine it came from.&lt;/p&gt;&lt;p&gt;A change set usually has one parent, but will have two when you are doing a merge. A change set can never have more than two parents, though, which helps to limit the complexity of branches and merges in the version tree.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Commands&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;You use the clone command to &lt;strong&gt;clone&lt;/strong&gt; a repository from the main location like this:&lt;/p&gt;&lt;blockquote style="clear: both;"&gt;hg clone http://mysite.com/myRepo [destination folder name]&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;Once you have done this you now have a full copy of the repository. Under the folder you specified there will be a .hg folder. This folder contains all the repo history and information. Everything else under the main folder is called the working directory. (If you want to disconnect the folder from the Mercurial repo, you just have to delete the .hg folder.)&lt;/p&gt;&lt;p&gt;Once you have made some changes you execute the &lt;strong&gt;commit&lt;/strong&gt; command to commit them to your local repository (this creates a change set). Then, once you are ready to share everything with the rest of your team, you do a &lt;strong&gt;push&lt;/strong&gt;. This will push all of the change sets you have committed to your repo out to the main repo that you cloned from.&lt;/p&gt;&lt;p&gt;In order to update your repo with other people's changes you do a &lt;strong&gt;pull&lt;/strong&gt;. This will pull in all change sets in the main repo that you do not have in your local repo. It's important to remember that this &lt;em&gt;will not&lt;/em&gt; update your working directory. All this does is pull change sets into the .hg folder. In order to update your working directory to the latest version, you have to do an &lt;strong&gt;update&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;If you do an update and the change sets you pulled are not descendants of the change set in your working directory, the update will fail, and it will tell you that you have to do a &lt;strong&gt;merge&lt;/strong&gt;. Doing the merge creates another change set that represents the merging of two change sets. You now commit the merge and push the new change set back to the main repo.&lt;/p&gt;&lt;p&gt;That's the basics of how Mercurial works, but there's a lot more to learn. I recommend reading &lt;a href="http://hgbook.red-bean.com/read/" target="_blank"&gt;Mercurial: The Definitive Guide&lt;/a&gt; if you want to know more.&lt;/p&gt;&lt;p&gt;My next Mercurial post will be about using with Eclipse.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-3905505933321988112?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/3905505933321988112/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/mercurial-basics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3905505933321988112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3905505933321988112'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/mercurial-basics.html' title='Mercurial: the basics'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-3682374166169516441</id><published>2010-01-11T22:58:00.000-08:00</published><updated>2010-01-12T07:30:03.955-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>GWT and virtual toString methods</title><content type='html'>&lt;div style="clear: both;"&gt;I ran into something very mysterious today with GWT 2.0. It took me quite a while to track down exactly what the root cause was, but I've narrowed it down to one specific thing. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;Let's say you create an object like this: &lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java;"&gt;public class TestObject {&lt;br /&gt;  private Object value ; &lt;br /&gt;     &lt;br /&gt;  public void setValue(Object value) { &lt;br /&gt;    this.value = value; &lt;br /&gt;  } &lt;br /&gt;     &lt;br /&gt;  @Override public String toString() { &lt;br /&gt;    return value.toString(); &lt;br /&gt;  } &lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;div style="clear: both;"&gt;Then in your entry point you do this:&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java;"&gt;public class Gwt_test implements EntryPoint {&lt;br /&gt;  public void onModuleLoad() { &lt;br /&gt;    RootPanel panel = RootPanel.get(); &lt;br /&gt;    HTML html = new  HTML(); &lt;br /&gt;    panel.add(html); &lt;br /&gt;        &lt;br /&gt;    TestObject object = new TestObject(); &lt;br /&gt;    object.setValue(new  Object()); &lt;br /&gt;    object.setValue("Hello there"); &lt;br /&gt;        &lt;br /&gt;    html.setHTML("&amp;lt;h1&amp;gt;" + object + "&amp;lt;/h1&amp;gt;");&lt;br /&gt;  } &lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style="clear: both;"&gt;You would expect when you do the GWT compile and run your server and navigate to the page, you would see "Hello there" on the screen. Well, if you use Google Chrome, you'd be right. But if you use IE, Safari, or FireFox you'll just see a blank page.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;Why is this? Well, it turns out to be quite complicated, and I only understand it up to a point. But this is what I have figured out so far.&lt;br /&gt;&lt;br /&gt;You'll notice in the onModuleLoad method of the Gwt_test class after I create an instance of TestObject I set the value to 'new Object()' and then to a String. This is there so that when the GWT compiler generates code for the TestObject toString method, it has to take into account that the 'value' field may be an Object or a String. Which means it has to do a call to toString__devirtual$ in order to generate a string for the 'value' field. If you have GWT generate readable JavaScript you can look at it. The toString method for TestObject looks like this:&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: js;"&gt;function toString_7(){&lt;br /&gt;  toString__devirtual$(this.value); &lt;br /&gt;} &lt;/pre&gt;&lt;div style="clear: both;"&gt;Now, this is the part that I don't understand. For some reason this code causes a JavaScript error in browsers other than Chrome. If you go to the page in FireFox and open Firebug, you'll see it has a JavaScript error that says, 'can't convert object to primitive type'. Kind of strange. I really don't get why this is happening, or why it works in Chrome, but I do have a fix.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="clear: both;"&gt;The easiest way to fix this is to just change the toString method on the TestObject class. Instead of calling the toString method on the value field, just do a string concatenation. So now TestObject looks like this:&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: java;"&gt;public  class  TestObject {&lt;br /&gt;  private Object value ; &lt;br /&gt;     &lt;br /&gt;  public void setValue(Object value) { &lt;br /&gt;    this.value = value; &lt;br /&gt;  } &lt;br /&gt;     &lt;br /&gt;  @Override public String toString() { &lt;br /&gt;    return value + ""; &lt;br /&gt;  } &lt;br /&gt;} &lt;/pre&gt;&lt;div style="clear: both;"&gt;And the generated JavaScript for the method looks like this:&lt;br /&gt;&lt;/div&gt;&lt;pre class="brush: js;"&gt;function toString_7() {&lt;br /&gt;  return this.value + ''; &lt;br /&gt;} &lt;/pre&gt;&lt;div style="clear: both;"&gt;Now it will work in all browsers. I wish I could understand why the other code doesn't work. I looked at the toString__devirtual method, but didn't really understand where the problem was coming from. But at least I have a workaround.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-3682374166169516441?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/3682374166169516441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/gwt-gotcha.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3682374166169516441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3682374166169516441'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2010/01/gwt-gotcha.html' title='GWT and virtual toString methods'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-8613137951153079813</id><published>2009-12-19T14:17:00.001-08:00</published><updated>2009-12-19T14:17:35.394-08:00</updated><title type='text'>An easyb jUnit runner</title><content type='html'>&lt;p&gt;I intended my next post to be about Mercurial, and I will get to it, but I had something else to write about. As I mentioned before, we are using &lt;a href="http://www.easyb.org/"&gt;easyb&lt;/a&gt; for our unit testing framework. It’s pretty nice, and I like it so far. It has an &lt;a href="http://code.google.com/p/easyb/wiki/InstallingEclipsePlugin"&gt;Eclipse plugin&lt;/a&gt;, but it just outputs to the console. Also, we are using Hudson for our CI server, and there isn’t really any Hudson integration for easyb either. Not having good integration was starting to bother me, so I decided to do something about it.&lt;/p&gt;  &lt;p&gt;I don’t have an endless amount of time to spend on it, so I figured the path of least resistance was to create a jUnit runner that would run the easyb behaviors. That way the output would integrate into Eclipse and Hudson automatically.&lt;/p&gt;  &lt;p&gt;It was a little tricky to get it to work properly because easyb tests are written in Groovy, and you can’t easily determine the makeup of a story or specification without actually running it. But I have something that works pretty well, and gives nice feedback, with good integration with Eclipse and Hudson.&lt;/p&gt;  &lt;p&gt;I created a project on Google Code to host it, so you can check it out here: &lt;a href="http://code.google.com/p/easyb-junit"&gt;http://code.google.com/p/easyb-junit&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I describe how to use it on the project site. I hope this is useful to other people. If you have any issues with it, or ideas to make it better, please let me know.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-8613137951153079813?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/8613137951153079813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/easyb-junit-runner.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/8613137951153079813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/8613137951153079813'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/easyb-junit-runner.html' title='An easyb jUnit runner'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-1175562352678261274</id><published>2009-12-14T21:55:00.001-08:00</published><updated>2009-12-14T21:55:08.497-08:00</updated><title type='text'>Technologies we are using</title><content type='html'>&lt;p&gt;My current project has given my team a great opportunity to use some newer web technologies. Prior to starting this project there were several things I had been looking at for a while and was interested in using. So, I’m going to list all the technologies we are using in this post and say a little about them. Then I’ll follow that up with a post about each one, and some details on what we are doing with them and things I’ve learned. These are in the order that we decided on using them.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Mercurial&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In previous jobs I’ve use PVCS, ClearCase, CVS, and Subversion. I don’t really have anything to say about PVCS, except that I was glad when we quit using it. ClearCase was too heavy handed, and a pain to deal with. CVS works well, but has some major performance issues and is missing a lot of nice features of more modern VCS systems. Subversion does fix some of the issues with CVS, but every project I’ve worked on with Subversion, everyone ran into major issues when trying to merge code. Add to that some other oddities we ran into with Subversion, and I wasn’t very happy with it either.&lt;/p&gt;  &lt;p&gt;I’d read a decent amount about the new distributed version control systems like &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; and &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt;. Although I never really understood why people liked them so much. I didn’t really get it until I read the &lt;a href="http://hgbook.red-bean.com/read/how-did-we-get-here.html"&gt;first chapter&lt;/a&gt; of the &lt;a href="http://hgbook.red-bean.com/read/"&gt;Mercurial guide&lt;/a&gt; about distributed version control. I ended up deciding to go with Mercurial. The main reason I went with it over Git was the Eclipse plugin for Mercurial seemed a lot better. Git seems to be too tied to the command line. Not that I hate the command line, some times I use it with Mercurial, but I like good IDE integration with a VCS.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Gradle&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I used Maven 2 back when it hadn’t been out very long. It was really cool how quickly you could get a build up and running with it. However, my team at the time had a bad experience with it. It cost me a few days of work a couple times, fixing weird build errors caused by plugins that got automatically updated. All those things that Maven just does for you can be a real headache when they aren’t working right. In the end, the issues we kept having with Maven lead us to switch to Ant and Ivy.&lt;/p&gt;  &lt;p&gt;So, for the last four years or so I’ve been using Ant for builds and Ivy for dependency management. Ant is great because you can literally do anything with it, and I really like the way Ivy does dependency management. But it can take a lot of work just to get a build working. And all the XML can be a pain. GANT is a nice solution to the XML, but it still takes a lot of effort to get the build running.&lt;/p&gt;  &lt;p&gt;A while ago I came across a new build tool called &lt;a href="http://www.gradle.org/"&gt;Gradle&lt;/a&gt;. It uses Groovy for writing the build instead of XML, so adding a bit of logic to your build is simple and straightforward. It also uses some of the build by convention concepts that Maven has, so getting a simple build running is a snap. It also has tight integration with Ant, so calling ant tasks is simple. It uses Ivy under the covers for dependency management, too. All in all, it looked like a nice option, so we decided to try it out.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GWT&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’ve kept track of &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; since it first came out. I’ve played around with it a few times, but never really got a chance to build anything with it. I really like the idea behind GWT. It’s not that I dislike JavaScript, I like it just fine, and jQuery is fun to work with. But I can’t really imagine building the entire front end of a rich internet application using JavaScript. It’s just too hard to test and debug, in my opinion. And I don’t really want to develop for Flash or Silverlight. So that leaves GWT. Which, to me is a great option.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Grails&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’ve done a couple small projects with &lt;a href="http://www.grails.org/"&gt;Grails&lt;/a&gt;, and been pretty impressed. You can really get things done quickly with it. It takes some getting used to, and doing TDD feels different than Java. But once you get the hang of it, it’s a nice environment to develop in. We looked at a couple different options for the backend of our system, but decided Grails would be the best choice.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SOFEA&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;With the back end and front end in place, there was still a decision to make about how they would communicate with each other. A friend of mine told me I should read about SOFEA. It stands for Service-Oriented Front-End Architecture. The concept is that the front end is completely client side and controls the flow of the application. The back end is simply a bunch of stateless services that the front end calls.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://raibledesigns.com/rd/entry/sofea_also_known_as_soui"&gt;Matt Raible is really big on this&lt;/a&gt; right now. He’s been using this architecture with GWT as the front end and Grails as the back end. We liked the idea of a clean separation between the front and back end that SOFEA presented, and had already decided to go with GWT and Grails. So it seemed natural to go with SOFEA also.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Easyb&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The last thing we decided to use was &lt;a href="http://www.easyb.org/"&gt;Easyb&lt;/a&gt;. We were definitely going to be doing TDD, but we liked the concepts that the BDD style had. Although you can do BDD in jUnit, it doesn’t really feel all that natural of a thing to do, and it’s really easy to fall back into some bad testing habits. I was hoping there was a better solution out there. &lt;/p&gt;  &lt;p&gt;I looked at JDave, but felt like it looked too verbose. I had heard of Easyb before, but never really looked at it. Once I checked it out I found that I really liked it. It uses Groovy instead of Java. Which adds some flexibility, and since we are using Groovy with Grails, it wasn’t another language to learn.&lt;/p&gt;  &lt;p&gt;I found writing Easyb specifications is pretty similar to how I was doing TDD in jUnit, just nicer. I still use &lt;a href="http://mockito.org/"&gt;Mockito&lt;/a&gt; for mocking, and my tests are structured very similar to how they were before. They are just easier to read, and you aren’t tempted to fall back into the non BDD tests like you can be with jUnit. Also, Easyb has a nice HTML report that it outputs as part of our build. It’s a great tool! Well worth a look, if you haven’t seen it before.&lt;/p&gt;  &lt;p&gt;Well, that’s it. That’s a lot of new stuff, but I think it’s already coming together pretty nicely. As I said at the beginning, I will be blogging about each of these technologies in the coming weeks. Until next time…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-1175562352678261274?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/1175562352678261274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/technologies-we-are-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/1175562352678261274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/1175562352678261274'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/technologies-we-are-using.html' title='Technologies we are using'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-1791352608756388076</id><published>2009-12-06T19:49:00.001-08:00</published><updated>2009-12-07T21:56:21.634-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>One line of code</title><content type='html'>&lt;p&gt;One is the magic number. At least it is for two things when it comes to writing code. &lt;/p&gt;&lt;p&gt;&lt;font size="3"&gt;&lt;strong&gt;The value of really small methods&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;The first thing one is the magic number for is the number of lines of code in a method. I first heard this from &lt;a href="http://www.agileprogrammer.com/oneagilecoder/"&gt;Brian Button&lt;/a&gt; in a TDD class he gave a couple years ago. He was talking with someone else and asked them what they thought the optimal number of lines of code in a method was. I think the other person answered something like 10 or 15. “Nope,” Brian said, “it’s one!”&lt;/p&gt;&lt;p&gt;One line of code per method! That sounds crazy! It sounded pretty far fetched to me at that time, too. But Brian is a smart guy, so I thought I would give him the benefit of the doubt and really try it out. That was a couple of years ago, and I’d have to say that I’m definitely a believer now!&lt;/p&gt;&lt;p&gt;Now, like pretty much everything in programming this is not a hard and fast rule. You have to consider context and use judgment like with everything else. So, I’m not saying every single method should have only one line. That wouldn’t work. I just mean it’s an ideal to shoot for. The closer you get to it, the better off you’ll be.&lt;/p&gt;&lt;p&gt;I’ve worked with people in the past who said they believed in “self documenting code.” What they really meant by that is: “I don’t write comments.” They didn’t actually write self documenting code, they just didn’t document the confusing code they wrote. If a class is 500 lines long and made up of a bunch of 20 to 80 line methods, it’s not self documenting. Just because you don’t comment it and say it’s self documenting doesn’t make it so. Creating self documenting code takes intentionality, thought, and effort.&lt;/p&gt;&lt;p&gt;One of the biggest things you can do to make your code self documenting is to break it down into small methods. Methods whose size approach one line of code. If you do this, you will understand your code better. The next person that has to read it will understand it faster. And with good method names, you will have real self documenting code.&lt;/p&gt;&lt;p&gt;As I’ve worked at coding this way over the last few years, I’ve noticed a few things. One is that when I have to go back to a class that I wrote with really small methods, I rarely have to spend much time at all remembering how it works. I find that I can understand how it works much faster than I could when I wrote classes with big methods. &lt;/p&gt;&lt;p&gt;I’ve also noticed my definition of a big class or a big method has really changed. I used to work on a system that had classes that where thousands of lines long with methods frequently being hundreds of lines long. Now when a class gets to 100 lines, I start really feeling like I need to break it up. And I am rarely willing to put more than about 5 lines in a method. Quite a change.&lt;/p&gt;&lt;p&gt;Another thing that I’ve noticed is that shooting for one line methods helps reveal a lot of code duplication. The other day I was writing a class, and I had all the tests written and the functionality complete. Now it was time to refactor. So I started breaking the logic down into smaller methods. As I did this I noticed that two of the methods actually had a lot more in common than I realized. I was pulling several of the same small methods out of each. Then I realized that if I implemented another method they both used a little differently, I could collapse both methods into just one line of code. This change lead to a 10% reduction in the size of the class due to code duplication. Duplication that I wouldn’t have even noticed, if I hadn’t been creating all those little methods.&lt;/p&gt;&lt;p&gt;So, writing one line methods may sound extreme, and it is just an ideal, not a rule. But if you adopt it, I think you’ll find your code is easier to understand, easier to modify, and contains less duplication. That’s a nice combination.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;But wait, there’s more&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There’s another thing for which one is the magic number. I read a blog post a while back that I wish I could find, but I search around and couldn’t find it. In the post the guy was saying that if you are creating a new class, API, or feature you should not consider it done until it can be used/called with one line of code! This is something I wish people would think about more.&lt;/p&gt;&lt;p&gt;When you are writing something, think about the code that will have to be written to call your code. Is there too much setup for even simple uses? Can it be called with one line of code? Again, this isn’t a hard and fast rule, but it’s something you should shoot for. Especially for simple things that people may want to do with your code.&lt;/p&gt;&lt;p&gt;For instance, say you have a file and you want to read the lines of the file into a list of strings. Now, that’s a pretty simple thing and should only require one line of code. Well, this is how it would look using java.io:&lt;/p&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public List&amp;lt;String&amp;gt; readFile() throws IOException {   BufferedReader in = new BufferedReader(new FileReader("myFile.txt"));   List&amp;lt;String&amp;gt; contents = new ArrayList&amp;lt;String&amp;gt;();   while(in.ready()) {      contents.add(in.readLine());   }   return contents;}]]&gt;&lt;/script&gt; &lt;p&gt;I suppose that’s not too bad. It’s only about 6 lines, but that’s a lot more than one. This is a simple and common operation, there’s no reason it should take more than one line of code. Of course, if you have Apache IO Utils on the class path, it is only one line:&lt;/p&gt;&lt;script class="brush: java" type="syntaxhighlighter"&gt;&lt;![CDATA[public List&amp;lt;String&amp;gt; readFile() throws IOException {   return IOUtils.readLines(new FileReader("myFile.txt"));}]]&gt;&lt;/script&gt; &lt;p&gt;That’s the way it should be. I don’t really understand what the designers of this API where thinking on this one. I guess they got so caught up in making a flexible API that can do anything, that they forgot to make it easy to use for simple things. They forgot to make sure it could be used with one line of code.&lt;/p&gt;&lt;p&gt;And don’t even get me started on JDBC! Oh man, what a pain!! Look, if I want to query the database with a couple parameters and get a string out, that’s pretty basic, that should only require one line of code. If it takes more than one line of code with your database framework, then get a new one. I don’t even want to think about how many lines of code it would take to do it with raw JDBC.&lt;/p&gt;&lt;p&gt;So, the moral here is, when you’re writing a class or an API, think about the calling code. Refactor and add helper methods if you have to, but strive to make your code as easy to use as possible for clients. Don’t make them write the same 3 or 5 lines of code every time they want to do something basic and common with your code. Aim for one line of code.&lt;/p&gt;&lt;p&gt;After all, one is the magic number!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-1791352608756388076?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/1791352608756388076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/one-line-of-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/1791352608756388076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/1791352608756388076'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/one-line-of-code.html' title='One line of code'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-3574295547290072991</id><published>2009-12-03T11:47:00.001-08:00</published><updated>2010-01-11T23:19:17.324-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Builds'/><category scheme='http://www.blogger.com/atom/ns#' term='Ivy'/><category scheme='http://www.blogger.com/atom/ns#' term='Gradle'/><title type='text'>Using an ivy.xml with Gradle</title><content type='html'>I’ve been using &lt;a href="http://www.gradle.org/"&gt;Gradle&lt;/a&gt; on my current project. So far I really like it. It follows the ‘build by convention’ idea that &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; uses and is even easier to extend and add to than &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;. One of the main reasons is the build file is actually just a Groovy file. So adding logic is simple.&lt;br /&gt;&lt;br /&gt;One of the problems with any new tool, though, is wide spread support. Usually the IDE department is the biggest issue here. Gradle uses &lt;a href="http://ant.apache.org/ivy/"&gt;Ivy&lt;/a&gt; for dependency management, but it does it under the covers. You specify your dependencies in the build.gradle file using the Groovy syntax. It’s actually nicer than XML. The issue is getting your IDE to recognize the dependencies declared in your build file. There aren’t any plug-ins for this yet. This is no good as far as I’m concerned, because it makes adding jars to your project way too hard.&lt;br /&gt;&lt;br /&gt;Today I decided I needed to add &lt;a href="http://mockito.org/"&gt;Mockito&lt;/a&gt; to my project, and ran into this issue of trying to figure out how to have it in my Gradle build file and on my Eclipse classpath. It annoyed me enough that I considered just dropping Gradle and going with Maven. Then I realized that since the build file is just Groovy, it should be pretty simple to have an ivy.xml file and just read it in the build file and insert the dependencies programmatically. It turns out this was pretty simple. Here’s how it worked.&lt;br /&gt;&lt;br /&gt;In Gradle you specify your dependencies by declaring a dependency section in the build file like this:&lt;br /&gt;&lt;script class="brush: groovy" type="syntaxhighlighter"&gt;&lt;![CDATA[dependencies {  compile(    [group: 'com.google.gwt', name: 'gwt-user',   version: '2.0.0-rc1'],    [group: 'com.google.gwt', name: 'gwt-dev',    version: '2.0.0-rc1'],    [group: 'commons-io',     name: 'commons-io', version: '1.4']  )  testCompile group: 'junit', name: 'junit', version: '4.+'}]]&gt;&lt;/script&gt;  &lt;br /&gt;You can also represent a dependency as a list of strings like this:&lt;br /&gt;&lt;script class="brush: groovy" type="syntaxhighlighter"&gt;&lt;![CDATA[dependencies {compile(  ['com.google.gwt:gwt-user:2.0.0-rc1',   'com.google.gwt:gwt-dev:2.0.0-rc1',   'commons-io:commons-io:1.4'])  testCompile('junit:junit:4.+')}]]&gt;&lt;/script&gt;  &lt;br /&gt;It’s important to note that all that is happening here is you are passing a list of strings to a method called ‘compile’ and ‘testCompile’. So, I realized all I have to do is write a function to build these strings off of the ivy.xml file.&lt;br /&gt;&lt;br /&gt;Using the XML processing power of Groovy this is actually really easy. I changed the dependency section to look like this;&lt;br /&gt;&lt;script class="brush: groovy" type="syntaxhighlighter"&gt;&lt;![CDATA[dependencies {  compile(ivyDependencies('compile'))  testCompile(ivyDependencies('test'))}def ivyDependencies(conf) {  def dep = []  def ivyModule = new XmlParser().parse(file("ivy.xml"))  ivyModule.dependencies.dependency.each {    if(it.@conf == null || it.@conf == conf)      dep.add(it.@org + ':' + it.@name + ':' + it.@rev)  }  return dep}]]&gt;&lt;/script&gt;  &lt;br /&gt;This code just parses the ivy.xml file and looks for dependencies that match the conf you specified (or have no conf at all) and adds them to the list of dependencies. It ignores some of the advanced features of Ivy, but it works for what I needed it to. Now I can just use IvyDE in Eclipse and have the same dependencies in my IDE as Gradle uses when it builds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-3574295547290072991?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/3574295547290072991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/using-ivyxml-with-gradle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3574295547290072991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/3574295547290072991'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/12/using-ivyxml-with-gradle.html' title='Using an ivy.xml with Gradle'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-6100478564649964069</id><published>2009-11-28T08:25:00.000-08:00</published><updated>2009-12-07T07:49:46.059-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Customizing an Eclipse distribution</title><content type='html'>When I do Java development I usually use Eclipse. When you’re working with a team, I’ve found it’s really helpful to make sure everyone is using the same version of Eclipse with the same plug-ins and settings. In order to do this you can just package up a few more things with the Eclipse distribution.&amp;nbsp;Since I’ve done it several times now I thought I would document what you have to do. I thought others might find this useful, also.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Setting up the workspace&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first thing I like to do is to build a workspace that goes with Eclipse so I can setup all the settings in the workspace. Doing this for things like code formatting and templates ensures everyone’s code will look as similar as possible. There’s also a lot of other settings you may want to setup so no one else on your team will have to.&lt;br /&gt;To do this just download the distribution of Eclipse you want to start with and unzip it (for this example I’m using Eclipse IDE for Java EE Developers version 3.5.1). Then start Eclipse. Since this is the first time you will be opening Eclipse it will prompt you for where you want your workspace to be. Just clear out want it in the box by default and type ‘workspace’ and check the box at the bottom that says ‘Use this as the default and do not ask again’. It should look like this:&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_NHUhlj9iZ0A/SxCx914aNwI/AAAAAAAAAPQ/l5fr7maapg4/s1600-h/create-workspace%5B7%5D.gif"&gt;&lt;img alt="create-workspace" border="0" height="255" src="http://lh3.ggpht.com/_NHUhlj9iZ0A/SxCx-RuF9HI/AAAAAAAAAPU/A-UXhthu8qo/create-workspace_thumb%5B3%5D.gif?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline;" title="create-workspace" width="551" /&gt;&lt;/a&gt; &lt;br /&gt;Click OK. Eclipse will then create a folder called ‘workspace’ under your Eclipse folder. From now on when you open this Eclipse it will automatically use this folder as the workspace. Now you can install all the plug-ins you want and setup all the settings you want and they will be carried with this distribution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Packaging the JDK&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another thing you may want to do is package a JDK up with the distribution so you know for sure that everyone is using the same one. Also, this means that Eclipse will run even if the person does not have any version of Java installed on their machine (this does introduce a platform dependency, though).&lt;br /&gt;The easiest way to do this is to find a JRE you have already installed on your machine and just copy it into a folder called ‘jre’ under the Eclipse folder. When you run the eclipse.exe file it looks for a ‘jre’ folder in the Eclipse folder, if one is found, then it will launch using that JRE. However, this is often not preferable because some Eclipse plug-ins (like the Maven 2 plug-in) require you to be running Eclipse on a JDK not just a JRE. So it’s best to use a full JDK. You could just take a JDK and copy it into a folder named ‘jre’ under the Eclipse folder, but that could be misleading, and there’s another way.&lt;br /&gt;Take a JDK you have on your machine and copy it to a folder called ‘jdk’ under your Eclipse folder. Also in that folder there is an eclipse.ini file that is used for setting certain parameters to the exe and the Java VM. Open that file and put these two lines at the top:&lt;br /&gt;&lt;blockquote&gt;-vm      &lt;br /&gt;jdk/bin&lt;br /&gt;&lt;/blockquote&gt;This will tell Eclipse to use the VM you put in the ‘jdk’ folder.&lt;br /&gt;Now you can just zip up the Eclipse folder and give it to your team.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Bonus: Bundling Gradle with the distribution&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For my current project we are planning to use &lt;a href="http://www.gradle.org/"&gt;Gradle&lt;/a&gt; for our builds. I wanted to be able to bundle it with the Eclipse distribution and setup an external tool configuration so it would be easy to use for anyone else.&lt;br /&gt;To do this I downloaded the latest version of Gradle and put it in a folder called ‘gradle’ under the Eclipse folder. Then, in Eclipse, I created an external tool configuration like this:&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_NHUhlj9iZ0A/SxCx-4YCwBI/AAAAAAAAAPY/bOv5yTtG30w/s1600-h/external-tool%5B4%5D.gif"&gt;&lt;img alt="external-tool" border="0" height="462" src="http://lh4.ggpht.com/_NHUhlj9iZ0A/SxCx_en2ByI/AAAAAAAAAPc/E4oFtxgIMRM/external-tool_thumb%5B2%5D.gif?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline;" title="external-tool" width="575" /&gt;&lt;/a&gt; &lt;br /&gt;This will work fine as long as the person that uses it has their JAVA_HOME set to a valid JRE. But we’d rather have this work without that variable set. The gradle.bat file specifically looks for the JAVA_HOME variable to be set and will error out if it’s not. You can set this value to something using the Environment tab in Eclipse, but I couldn’t find any way to get this to work in a way that would function properly on everyone’s machine. So I ended up just modifying the gradle.bat file and adding a line that sets the JAVA_HOME variable to the ‘jdk’ folder under the Eclipse folder. The modified file looks like this (the added line is in bold):&lt;br /&gt;&lt;blockquote&gt;...      &lt;br /&gt;set DIRNAME=%~dp0       &lt;br /&gt;if "%DIRNAME%" == "" set DIRNAME=.\       &lt;br /&gt;&lt;strong&gt;set JAVA_HOME=%DIRNAME:~0,-12%\jdk&lt;/strong&gt;       &lt;br /&gt;... &lt;br /&gt;&lt;/blockquote&gt;It’s a bit of a hack, but it works. If anyone has any better ideas, I’m surely open to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-6100478564649964069?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/6100478564649964069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/11/customizing-eclipse-distribution.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6100478564649964069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/6100478564649964069'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/11/customizing-eclipse-distribution.html' title='Customizing an Eclipse distribution'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_NHUhlj9iZ0A/SxCx-RuF9HI/AAAAAAAAAPU/A-UXhthu8qo/s72-c/create-workspace_thumb%5B3%5D.gif?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2532776359713754015.post-77047991994295470</id><published>2009-11-19T20:42:00.000-08:00</published><updated>2009-11-20T21:33:04.665-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Craft'/><category scheme='http://www.blogger.com/atom/ns#' term='Passion'/><title type='text'>Passion for your craft</title><content type='html'>&lt;span style="font-family: inherit;"&gt;I've been thinking about starting a blog about technology and business for while, but never actually took the time. I decided now was a good time to do it. However, for my first post, I'm really just going to direct you over to the Software by Rob blog. If you don't read it already, you should consider it. He had an excellent post today about &lt;/span&gt;&lt;a href="http://www.softwarebyrob.com/2009/11/19/passion-as-a-competitive-advantage/"&gt;&lt;span style="font-family: inherit;"&gt;Passion as a Competitive Advantage&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt;.&amp;nbsp;I thought it was great and truly believe in the importance of being passionate about what you do.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;In the article Rob says:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: inherit;"&gt;Passion translates into being insulted when people don’t care about things as much as you do and are willing to hack a crappy solution together. It’s an insult to you, your product and your craft.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;One thing that passionate people love is other passionate people. When you really care about what you do, you want to work with people who also care about what they do. The last thing you want is to have to work with someone who is just trying to put in their forty hours a week. And, as&amp;nbsp;Rob puts it:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: inherit;"&gt;If you don’t have passion for your code/product/startup everyone will know. It’s obvious you aren’t that into it, and people will not take you seriously. Without passion it’s impossible to convince people to believe in your vision.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;I started out in college in Chemical Engineering. I made it through my third year and was only 30 hours away from graduating. Toward the end of my third year I was sitting in a principles of chemical engineering class, and the professor was chewing us out for not putting much effort into our latests&amp;nbsp;assignment. We were doing a design and&amp;nbsp;analysis&amp;nbsp;of a&amp;nbsp;distillation&amp;nbsp;column, and a lot of us (myself included) didn't do a&amp;nbsp;thorough&amp;nbsp;job and just turned in a half baked solution. Not surprisingly the professor, who was passionate about his field, was&amp;nbsp;practically&amp;nbsp;insulted by our lack of effort.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;Then the professor said something that changed my path in school. Actually, he asked a question. He asked, "Why would you turn in something poorly done, if you care about what you're working on? And if you don't care, why are you getting this degree?" I sat there and thought, "That's a good question! Why am I getting this degree?" The was effectively the end of my career as a Chemical Engineer.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;The summer before that I had taken a C++ class that was required to complete my ChemE degree. I really loved it. I did more than the class required, and would often just program things for fun. In one of my ChemE classes we had to write a program to solve a problem. The professor actually supplied a mostly complete program in some strange math environment and said we just had to complete it, if we wanted to do it that way. Everyone else did that, but I wrote my own from scratch in C++. I thought it would be more fun that way. Incidentally, mine was the only one that worked correctly.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;So, when that professor asked us why we were getting a degree in ChemE if we didn't care about it, I decided that Computer Science made more sense. This was something I did really care about, and something I loved doing. And the rest, as they say, is history.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;I graduated in 2001 with my CompSci degree and still love programming. It's been great getting paid to do something I love to do. And I've enjoyed all the time I've spent reading, practicing, and learning more about software development.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;span style="font-family: inherit;"&gt;After eight years I believe even more in the importance of passion for what you do. I love working with passionate people, and I'm always baffled by people who don't seem to care. They should have had a professor like I did and had to face the question, "if you don't care, why are you getting this degree?" If you aren't doing something you are passionate about, then do yourself and everyone else a favor and go find something you are passionate about. You'll be glad you did.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2532776359713754015-77047991994295470?l=technicallypossible.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://technicallypossible.blogspot.com/feeds/77047991994295470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://technicallypossible.blogspot.com/2009/11/passion-for-your-craft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/77047991994295470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2532776359713754015/posts/default/77047991994295470'/><link rel='alternate' type='text/html' href='http://technicallypossible.blogspot.com/2009/11/passion-for-your-craft.html' title='Passion for your craft'/><author><name>Aaron</name><uri>http://www.blogger.com/profile/01043016791025113940</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_NHUhlj9iZ0A/SwX80jdI8kI/AAAAAAAAAOo/JOyFGml_9n8/s1600-R/Me.jpg'/></author><thr:total>0</thr:total></entry></feed>
