tag:blogger.com,1999:blog-49604328567028700942024-03-13T06:03:25.474-04:00Jeff Storey's Software Development BlogJeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.comBlogger46125tag:blogger.com,1999:blog-4960432856702870094.post-72434388943915992822015-08-03T01:06:00.002-04:002015-08-03T01:06:49.607-04:00AWS autoscaling groups for a fixed number of instancesAWS autoscaling groups are a way to scale capacity up and down when it is needed. However, autoscaling groups are a great way to just keep a fixed number of instances alive. Let's say we have an app that we always want two instances of running. If one of them dies, it would nice to automatically restart it.
To do this, simply create an autoscaling group with a fixed size:
<pre>
"myautoscalinggroup" : {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"Properties" : {
"DesiredCapacity" : 2,
"MinSize" : 2,
"MaxSize" : 2,
}
</pre>
Now Amazon does the heavy lifting for us, and we'll always have a pool of two instances.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com4tag:blogger.com,1999:blog-4960432856702870094.post-60435098907428408052015-03-27T19:38:00.000-04:002015-03-27T19:39:38.890-04:00JavaScript console objectMany of us have used the JavaScript console object for logging
<pre>
console.log("some debug message");
</pre>
But for a lot of us, that's the extent. Maybe we use <code>console.info</code> or <code>console.error</code>, but there is so much more to the console.
For example, <pre>console.group</pre> lets you nest statements in a group. The following snippet:
<pre>
console.log('hello, I am outside the group');
console.group();
console.log('I am in the group');
console.log('me too');
console.groupEnd();
console.log('I am also outside the group');
</pre>
Produces an output of
<pre>
hello, I am outside the group
I am in the group
me too
I am also outside the group
</pre>
While the console should only be used for debugging (and there are better libraries for just printouts like <a href="https://www.npmjs.com/package/debug">debug</a>) and is not necessarily standard across browsers, it can be a really powerful tool. Check out the console docs at <a href="https://developer.mozilla.org/en-US/docs/Web/API/Console">https://developer.mozilla.org/en-US/docs/Web/API/Console</a> for a full list of functions.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com4tag:blogger.com,1999:blog-4960432856702870094.post-7474211147954711922014-12-08T00:06:00.000-05:002014-12-08T12:15:48.937-05:00Mocking non-injected services with groovySometimes we'll come across a piece of code that we want to test, but we're not able to inject a mock because the service is hard coded into the class. Consider this:
<pre>
<code>
class Client {
private final Service databaseService = new DatabaseService();
def find(long id) {
databaseService.find(id)
}
}
</code>
</pre>
Testing the <code>find</code> method would be difficult because the database service is not injected.
<br/><br/>
Groovy mocks and stubs can be used as categories for this case.
<pre>
<code>
class ClientTest {
@Test
private testFind() {
MockFor mock = new MockFor(DatabaseService)
mock.demand.find { id -> someObject }
mock.use {
Client client = new Client()
client.find(1L) // this will use the mock and return someObject
}
}
}
</code>
</pre>
While injecting dependencies is easier, this is an alternative method when injection isn't available. See <a target="_blank" href="http://groovy.codehaus.org/Using+MockFor+and+StubFor">Using MockFor and StubFor</a> for more details in the groovy docs.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-9047854776152175172014-10-13T13:25:00.000-04:002014-10-13T13:25:49.123-04:00Building fault tolerant applications with HystrixIn any distributed system, failures will happen. Remote calls will fail, servers will go down and database calls will return errors. When these calls fail, it is important that the failures stay isolated and don't cascade throughout the system. With this in mind, Netflix built and open sourced their <a href="https://github.com/Netflix/Hystrix">Hystrix</a> library. They do a pretty good job of describing what it is:
<blockquote>Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.</blockquote>
In particular, Hystrix allows you to easily employ the <a href="http://skife.org/architecture/fault-tolerance/2009/12/31/bulkheads.html">bulkhead pattern</a> to isolate calls to different 3rd party systems and to use a <a href="http://martinfowler.com/bliki/CircuitBreaker.html">circuit breaker</a> to prevent too many repeated calls to a failing system.
Here's an example of a simple command that does a surprisingly number of complex things:
<ul>
<li>This call will be executed using a thread pool to isolate it. All hystrix commands with the group <i>MyCommandGroup</i> will use this pool.</li>
<li>This command will use a circuit breaker in case it fails. In this example, returning "Hello world" is not going to fail, but if it was a remote command it could.</li>
<li>If the command fails, it will automatically use the fallback method.</li>
</ul>
<pre>
public class RemoteCommand extends HystrixCommand<String> {
public RemoteCommand() {
// "MyCommandGroup" determines which thread pool to use to execute the commands
// Use a different group to separate logically different groups of commands
super(HystrixCommandGroupKey.Factory.asKey("MyCommandGroup"));
}
@Override
protected String run() {
return "Hello world";
}
@Override
protected String getFallback() {
return "fallback to me if run() fails";
}
}
</pre>
The properties of the command (timeouts, circuit breaker threshold, etc) are highly configurable and can be tuned to your needs.
<br><br>
If you need a battle tested library for implementing these patterns, check out Hystrix.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-88084245857254219502014-07-14T23:54:00.000-04:002014-07-14T23:54:42.301-04:00Jenkins Job DSL PluginJenkins has a ton of plugins available to it, some of which are more well known than others. One particular one that I've recently found to be very useful is the <a href="https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin" target="_blank">Job DSL Plugin</a>. It allows you to use a groovy DSL to script the creation of your Jenkins jobs. This is beneficial because it makes your jobs recreatable and avoids the pattern where you create a bunch of similar jobs and then they slowly diverge. It also allows you to easily rebuild the jobs in the event of data loss.
<br><br>
As an industry we're getting better at automating the creation of our deployment environments with tools like docker, puppet, ansible and chef, but tools such as the DSL plugin allow for a nice way to automate the creation of your Jenkins jobs. For actually configuring your build environment using docker and ansible, check out this post <a href="http://blog.sequenceiq.com/blog/2014/05/09/building-the-build-environment-with-ansible-and-docker/" target="_blank">http://blog.sequenceiq.com/blog/2014/05/09/building-the-build-environment-with-ansible-and-docker/</a> by the team at SequenceIQ.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-70811791749157140822014-05-20T21:34:00.002-04:002014-05-20T21:34:52.455-04:00Debugging gradle jettyRun in IntelliJI was trying to figure out how to attach a debugger to the jetty server launched by running an app from <code>gradle jettyRun</code>. It turned out not to be so straight forward, but here's what I did.<br />
<br />
Step 1 - Upgrade to IntelliJ 13 if you're not there already. The gradle support has significantly improved.<br />
<br />
Step 2 - Create a new Jetty Server (Remote) configuration. Gradle uses an embedded jetty server, but you need to point IntelliJ at the home folder of a Jetty installation. I downloaded Jetty 6.125 (Gradle 1.10 uses Jetty 6, this may change with newer versions) and pointed at that.<br />
<br />
Step 3 - Configure the Jetty Server. I used the following values, but your may change them as needed.<br />
<br />
Server tab:<br />
- Application Server: Jetty 6.125<br />
- JMX port: 2099<br />
- Remote Staging type and host are both Same file system<br />
- Remote connection (where your app is running) defaults to localhost:8080<br />
<br />
Startup/Connection tab (Select Debug configuration):<br />
- Port: 52252 (default)<br />
- Transport: Socket (default)<br />
- The window will show the parameters you will need to pass to GRADLE_OPTS (or however you get properties to gradle, such as through gradle.properties). These properties are in addition to other properties in gradle.<br />
<br />
Step 4 - Create (or modify your existing one if you have) a jetty config file and point your jetty tasks at it as shown in <a href="http://blog.james-carr.org/2011/12/20/enabling-jmx-in-gradles-jetty-plugin/">http://blog.james-carr.org/2011/12/20/enabling-jmx-in-gradles-jetty-plugin/</a>. I did not have a jetty-env file.<br />
<br />
Step 5 - Start your gradle process from the command line with the following opts (or again here, in gradle.properties):<br />
<br />
<code>export GRADLE_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 -Dcom.sumanagement.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -DOPTIONS=jmx -Xdebug -Xrunjdwp:transport=dt_socket,address=52252,suspend=n,server=y -javaagent:/opt/idea-IU-133.1122/plugins/Groovy/lib/agent/gragent.jar"</code><br />
<br />
<br />
Note the -Xdebug and opts after that come from the arguments in the Startup/Connection tab in Step 3.<br />
<br />
Step 6 - Once your app has started, start the jetty configuration from IntelliJ in Debug mode. Run your webapp, and your code should now stop at breakpoints in IntelliJ.
Very many thanks to the StackOverflow's @CrazyCoder (http://stackoverflow.com/questions/14825546/deploy-debug-remote-jetty-with-intellij-12) and James Carr for his blog post referenced above.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-81684506121957308962014-03-13T19:16:00.001-04:002014-03-13T19:16:59.525-04:00Avoid flag parameters in public methodsI was recently reading some code that I wrote a while back, and it looked something like this:<br />
<pre>run(true);
</pre>
And then later on in the code I saw
<pre>
run(false);
</pre>
At the time I wrote this, it was very clear what this meant, and I was saving myself time by having a single method where a flag would slightly alter the behavior. Reading this code several years later, it wasn't clear at all what it was doing. So how did I write it so it was easier to read? Instead of having the flag in the public method, just have two separate methods, and bury the flag in a private method. After refactoring, my code now looks like:
<pre>
runSynchronously();
</pre>
and
<pre>
runAsynchronously();
</pre>
Internally, there is still a run method that takes a flag for running asynchronously, but the public API is now a lot easier to understand.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com4tag:blogger.com,1999:blog-4960432856702870094.post-20789708354210944642014-03-11T18:42:00.003-04:002014-03-11T18:42:48.149-04:00Effective Code ReviewsThere are numerous ways to conduct code reviews, ranging from the very formal to a constant review with pair programming. In this post, I'll discuss techniques that I have used for code reviews and what I expect to get out of a code review. In an environment where there is not pair programming, to me, code reviews are a must. I've seen huge improvements in codebases from doing reviews, resulting in both less code being written as well as cleaner code.<br />
<br />
There are several reasons why code reviews are important...<br />
<br />
They do find some bugs - not all of them, especially if the reviewer is not particularly familiar with that area of the code - but they help to weed out some of the obvious ones. Even the best developers make mistakes and having a second set of eyes can help. You can use automated tools where possible to filter out some things, but another look at the code is invaluable.<br />
<br />
They help familiarize reviewers with areas of the code they don't know as well. As a system grows larger, not everyone will know every part of the code. By doing reviews, you can widen your understanding of the code, and you may find code that is useful for something else you're working on later on in time. For example, I've worked on larger codebases where you see similar utility methods in several different places because people didn't know they exist.<br />
<br />
They socialize conventions. As you review other people's code and vice versa, you will start to pickup conventions that other developers use. Over time, you can end up with a more consistent looking codebase, making it easier to read, regardless of the author.<br />
<br />
They are learning experiences. I've often been reviewing someone else's code and learned something I didn't know, such as a technique for doing something in whatever language you're using.<br />
<br />
Peer pressure helps produce cleaner code. If I write something poorly, such as not well tested or well documented, I know the review will be rejected. While I like to think I always write everything the best I can, this is a nice reminder that other people will be reviewing the code.<br />
<br />
How to conduct a review...<br />
<br />
We've all probably done the big formal, ceremonious review at one time or another. Several days before the review, someone sends out the code to be reviewed or even prints it out and drops it off at your desk. You're expected to come to the review having reviewed the code already. In these situations, it has been my experience that only a small percentage of the people do a thorough review, and many reviewers simply show up without having read the code ahead of time or noting very trivial things like "this comment is misspelled." I think these types of reviews are generally a waste of too many people's time.<br />
<br />
Currently I use Atlassian's Crucible to do reviews. When I am ready for my code to be reviewed, I select one or two people and add them to the review. They receive automatic notifications that they have a review waiting and they have some amount of time to complete it. The reviewers add comments to code and can optionally raise defects in JIRA. With this setup, people can review at their own pace. Similar to one benefit of code reviews, the peer pressure of having your comments publicly visible tends to make for more through and thoughtful reviews. I try to avoid long threads of comments on the review because tone can often be misconstrued. Any more than 1 or 2 comments, and I'll just have an in person discussion.<br />
<br />
These are just my experiences with code reviews, and yours may vary. Feel free to comment to add to or disagree with anything I've said here.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-2084866980002996222013-12-25T21:38:00.001-05:002013-12-25T21:38:15.948-05:00Gradle daemonThe gradle daemon is a feature in gradle that is designed to speed up build times. A daemon process will run the builds, which reduces the startup time of the build. In an environment where you are running builds many times a day, this can be a significant time saver.<br />
<br />
To enable the daemon, add the following property to your GRADLE_OPTS or gradle.properties:.<br />
<pre>org.gradle.daemon=true
</pre>
<br />
<div>
Gradle will automatically use the daemon process for the build. The daemon is killed off if it is not used for a while, but when that happens, the next build will spin up a new daemon. There are also additional options for not using the daemon, stopping it and running in the foreground that can be found in gradle's documentation <a href="http://www.gradle.org/docs/current/userguide/gradle_command_line.html">http://www.gradle.org/docs/current/userguide/gradle_command_line.html</a>.<br />
<br />
<br /></div>
<br />
<br />
<dd style="border: 0px; color: #333333; font-family: Lato, Arial, serif; font-size: 14.44444465637207px; line-height: 23.33333396911621px; margin: 0px 0px 0px 1.5em; padding: 0px; vertical-align: baseline;"></dd>Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-36317006627999740332013-11-13T21:17:00.001-05:002013-11-13T21:18:38.758-05:00People are not resourcesIt's very common for project managers to refer to employees as <i>resources</i>. The dictionary definition of resource is <span style="background-color: white;"><span style="font-family: inherit;"><i>some</i><u style="font-style: italic; font-weight: bold;">thing</u><i> that can be used for support or help</i><span style="font-size: x-small;">.</span></span></span><span style="background-color: white; font-family: Arial; font-size: 13px;"> </span><span style="background-color: white;"><span style="font-family: inherit;">People are people, not things. A chair is a resource. A computer is a resource. A person is not a resource - a person is a person.</span></span><br />
<span style="background-color: white;"><span style="font-family: inherit;"><br /></span></span>
<span style="background-color: white;"><span style="font-family: inherit;">By using the term resource, the individuality of people and the value they provide are trivialized. You can swap one similar chair for another, but can you really swap one "similar person" for another?</span></span><br />
<span style="background-color: white;"><span style="font-family: inherit;"><br /></span></span>
<span style="background-color: white;"><span style="font-family: inherit;">This may seem like a small thing, but it's really a small thing to start calling people <i>people</i>, and it can make a big difference.</span></span>Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com2tag:blogger.com,1999:blog-4960432856702870094.post-90596988476097213212013-10-20T21:29:00.001-04:002013-11-13T21:18:12.544-05:00Keep methods shortI was reading some code recently, and saw the notation of marking the beginning and end of loops (not the first time I've seen this).<br />
<br />
<pre>for ( int i = 0; i < someEndVal; i++ ) { // begin myProcessingLoop
// long set of steps here
} // endMyProcessingLoop
</pre>
<br />
Why is that information there? Usually because the processing loop is so long that it doesn't fit on a single screen, or because there are so many nested loops that it is hard to decipher. Instead of commenting on the loops like that, rewrite the loops so they are short. A common technique is to extract the loop body into its own method.
<br />
<br />
<pre>for ( int i = 0; i < someEndVal; i++ ) {
dostuff(i);
}
It removes the unnecessary comments and makes the code generally easier to read.</pre>
Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-80423953364891410822013-06-26T19:26:00.000-04:002013-06-26T19:26:58.485-04:00NoSQL is not schemalessNoSQL datastores give us a lot of flexibility when it comes to putting data in. They don't need a fixed schema to accept data, and they're pretty good about handling data with mixed attributes. Consider I insert the following data into a mongodb store (I'll use Mongo to illustrate my point, but this could apply to most NoSQL stores):<br />
<pre>[ { "first_name" : "Jeff", "last_name" : "Storey" } , { "color" : "red", "a_number" : 50 } ]
</pre>
Sure, I can do this, but imagine trying to query this data. Mongo will let me write a query that selects all documents whose "first_name" is "Jeff" or whose "color" is "red," but this doesn't make much sense at an application level. In order for the data to be easily processed, it needs to conform to some schema.<br />
<br />
Where having this flexibility is really useful is with a schema that changes over time - and what schema doesn't? Rather than having to add new columns, new constraints, etc to the database, mongo will happily allow you to add new columns. Now consider an original schema that looks like:<br />
<pre>first_name, last_name, age
</pre>
Then I realize I want to start collecting income data, and I change it to<br />
<pre>first_name, last_name, age, income
</pre>
For records that have income, just insert it. No database changes necessary!<br />
<br />
Technically, yes, NoSQL stores can be schemaless, but that doesn't mean you shouldn't have a schema.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com1tag:blogger.com,1999:blog-4960432856702870094.post-28992999069283650052013-04-06T09:43:00.001-04:002013-06-13T22:41:08.757-04:00Javascript LoggingWhen developing Javascript applications, we often need to do some logging and we usually resort to using console.log, which typically isn't a good thing to have in production code. I've been doing some research into Javascript logging frameworks, and there are quite a few of them.<br />
<br />
<a href="http://log4javascript.org/">log4javascript</a> looks to be one of the more promising ones. It is still being actively updated, and the API is pretty straightforward, especially if you've used other logging frameworks like log4j. They even provide a default logger that requires no configuration to get running:<br />
<br />
<pre>var logger = log4javascript.getDefaultLogger();
logger.debug("this is a debug message");
</pre>
<br />
There are various types of appenders, including one that sends the log message through an ajax call to the server so the log message can be saved on the server.<br />
<br />
If you're doing any sort of logging in your Javascript app, this is definitely worth a look.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com1tag:blogger.com,1999:blog-4960432856702870094.post-49836451390336491732013-03-05T22:12:00.000-05:002013-03-05T22:12:54.124-05:00Unstable builds in JenkinsWe use Jenkins for our continuous integration server, and I've never really seen the need for it to have an "unstable" build status. I actually think this build status does more harm than good. I've found that unstable can be treated in one of two ways - either it is treated like a build failure and fixed immediately or it is treated as not important and ignored. Either way, I think it loses its meaning.<br />
<br />
It's also a bit unclear as to what "unstable" actually means. Some coverage plugins for example will set the build to unstable if the coverage level falls below a certain threshold. In this case, if coverage is too low, I wouldn't feel comfortable producing a build that is production ready, so I would fail the build. It's also possible to configure Jenkins to mark a build as unstable on test failures, instead of failing the build - I'm not even sure why that option exists.<br />
<br />
I believe the build should only have two states - passed or failed. Whenever I start a new Jenkins project, I always configure any of the plugins I'm using to not use the unstable state (configuration varies from plugin to plugin). I've found keeping out the "unstable" state has led to healthier builds overall.<br />
<br />Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com2tag:blogger.com,1999:blog-4960432856702870094.post-75324053572896206602013-02-15T17:36:00.000-05:002013-02-15T17:38:51.129-05:00Why I switched to IntelliJFor the last few years, I have been an Eclipse user. It's free, and for the most part, it worked pretty will with the occasional crash. However, I've found that it performs really poorly when it comes to dynamic languages. The groovy/grails autocomplete is mediocre, but where I really had issues is with Javascript. It got to a point where every time I tried to save a Javascript file, I was getting a NullPointerException.<br />
<br />
So I decided to try out IntelliJ Ultimate based on a colleague's recommendation. Overall, I've been happy with the experience. It is very stable (I've only had one crash since I've been using it, and I was running a lot on my system at once). Deploying to Tomcat servers has been a breeze.<br />
<br />
It's not without its quirks though. For example, things that just work in Eclipse, such as auto-wrapping long comment lines, don't work in IntelliJ. I've also found that the gradle support is still new and can be buggy at times (especially with auto-synchronizing Intelli's dependencies with the gradle build's dependencies - though I've heard that's in the works).<br />
<br />
What I've been most impressed with is the support. Whether on the Jetbrains forums, bug tracker or stack overflow, the IntelliJ support team generally responds very quickly to posts.<br />
<br />
Overall, it has been a pleasant experience. If you're fed up with Eclipse, I recommend giving IntelliJ a try.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-56670028212015357902013-01-23T00:39:00.002-05:002013-01-23T00:48:05.076-05:00Spring ProfilesMuch of my web development over the past few years has been with Grails on the back end, and although Grails is built on Spring, it's still a good idea to keep up on the new Spring features - you never know when they'll come in handy.<br />
<br />
I recently found myself creating a pure Spring app and missing a feature that I really like in Grails - environment based configuration. Fortunately, Spring 3.1 introduced the concepts of profiles, which is as simple as using the @Profile annotation.<br />
<br />
First, configure an application context using the @Configuration annotation.<br />
<br />
<pre>@Configuration
public class ProductionApplicationContext {
public SomeBeanInterface myBean() {
return new MyProductionImplementationOfSomeBean();
}
}</pre>
<pre>@Configuration
public class TestApplicationContext {
public SomeBeanInterface myBean() {
return new MyTestImplementationOfSomeBean();
}
}
</pre>
Now we can specify which profile the context is associated with by adding the @Profile annotation
<pre>@Configuration
<b>@Profile("production")</b>
public class ProductionApplicationContext {
// bean defs
}</pre>
<pre>@Configuration
<b>@Profile("development")</b>
public class TestApplicationContext {
// bean defs
}
</pre>
Now when you start your app, provide the <b>spring.profiles.active</b>
system property to specify the profile(s) to use. You can also specify the default profile to use in your web.xml file by adding the following block
<pre>
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>production</param-value>
</context-param>
</pre>Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-58939316953946098272012-10-22T17:55:00.003-04:002012-10-22T18:00:40.352-04:00Using Core Groovy AST TransformsHave you ever used an Abstract Syntax Tree (AST) transform? If you're using groovy or grails, chances are you have, and maybe you just didn't know it. An AST allows code to be modified at compile time. Groovy provides the capability to write both local (annotation driven) and global (globally applied) AST transforms. They have a nice tutorial <a href="http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations">http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations</a>.<br />
<br />
Even if writing AST transforms is not something you are doing, you can benefit from the numerous built in transforms that groovy provides. Many of these help to eliminate the need for boilerplate code that we've all written before. This post does not aim to list all of them, but rather to provide you an overview of some of them. Check out all implementors of the ASTTransformation from the groovy api (<span style="color: #0000ee;"><u>http://groovy.codehaus.org/api/org/codehaus/groovy/transform/ASTTransformation.html</u></span> to see a full list.<br />
<br />
Consider a Money class that looks<br />
<br />
<pre>class Money {
int amount
String type // USD, Euro, etc
boolean equals(Money other) {
if ( other == this ) {
return true
}
if ( other instanceof Money ) {
return amount == other.amount && type == other.type
}
return false
}
int hashCode() {
return new Integer(amount).hashCode() + type.hashCode()
}
}
</pre>
<pre></pre>
This is fairly verbose at best, and at worst, it's very error prone. What if I add a new field to the Money class and update the equals but forget to update the hash code (yes, tests should catch this). What if I forget to add the field to equals and hash code all together?<br />
<br />
In Java, you might use Apache Commons' EqualsBuilder and HashcodeBuilder's reflection methods. This certainly simplifies your code, but the performance can be pretty bad if these methods are called frequently.<br />
<br />
Enter the AST transform.
<br />
<br />
<pre>@EqualsAndHashCode
class Money {
int amount
String type // USD, Euro, etc
}</pre>
<br />
The @EqualsAndHashCode annotation adds the code at compile time, so you don't take the runtime hit, but you get the benefit of not having to write the code yourself.<br />
<br />
Some other useful transforms include<br />
@ToString - Adds a toString method<br />
@Bindable - Adds property change support<br />
@Mixin - Mixes in code to classes<br />
<br />
As you can see, AST transformations can provide a lot of benefit and reduce the amount of boiler plate code you need to write. If you haven't used them before, I encourage you to at least take a look.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com3tag:blogger.com,1999:blog-4960432856702870094.post-66710188409634005702012-10-04T19:10:00.001-04:002012-10-05T09:08:01.766-04:00Build quality in from the startHave you ever joined a large project in progress only to find that the project is a bit on the messy side? There's no testing, no automated builds and really no quality control. Did you wonder how it got that way? Then you try to correct some of these problems only to realize you're only making a minor dent (better than nothing). But if the project is in that state, it's likely going to be an uphill battle.<br />
<br />
Even the largest of projects start small, and it is much easier to build the quality control into the product at the beginning of the project. At the start of a project, use "iteration 0" for setting up the test and automation infrastructure. There are a certain set of tools at a minimum that I prefer to use for projects.
<br />
<br />
Version control - this one should be obvious, but I'll include it here anyway. Whether you use a traditional VCS or distributed VCS may vary based on your needs, but use something.<br />
<br />
Unit testing framework - again here, hopefully this one is obvious also. I typically use JUnit, but other tools such as spock can be useful. Also included here are any of the other unit testing framework, such as DBUnit or XMLUnit.<br />
<br />
Acceptance testing framework - have a look at Selenium/Webdriver coupled with Spock or Cucumber. Cucumber is a little more complex but lets you write business requirements in plain language rather than in code.<br />
<br />
Automated build/Dependency Management tools - ant/ivy, maven or gradle. Pick your poison. I like maven because it is more standardized than ant and has a rich set of plugins. But the million lifecycle phases with maven and the fact that it downloads the entire internet can be a little unnerving. On my next project, I'll be trying out gradle.<br />
<br />
Continuous integration server - I really only have experience with Jenkins, but a variety of others exist. I've been quite happy with Jenkins, so I don't see myself switching any time soon.<br />
<br />
Deployment tools - This is an important, but often overlooked category of automation tools. Maybe your deployment is simple, but it should absolutely be scripted, even if you write those scripts yourself. Just as with any of the other tools, your deployment infrastructure will evolve as your project does.
<br />
<br />
Infastructure tools - Using virtual machines is a great way to make your infrastructure easier to manage. I've been using Chef for provisioning my VMs, and it makes reconfiguring and standing up new machines much easier. VMs are a great way to standup test environments as well. You may additionally want to look at infrastructure monitoring tools such as Nagios<br />
<br />
Code quality control tools - cobertura code coverage, checkstyle, findbugs, pmd, CPD (copy-paste detector), and sonar.<br />
<br />
This is just a sampling of the common tools I use. There are a seemingly endless number of solutions available in these areas.
This may seem a bit overwhelming, and even if you can't use or don't need all of these tools, that's ok. The important part is to step into automation and quality control. The more you can get in place earlier in the project, the easier it will be in the long run.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com1tag:blogger.com,1999:blog-4960432856702870094.post-65067487890299279922012-07-20T13:59:00.000-04:002012-10-05T09:07:20.931-04:00Hamcrest MatchersHamcrest matchers have been available for some time now, but I still don't see them being used regularly on projects. If you're not familiar with them, they are set of matchers that can be used with JUnit's <i>assertThat</i> syntax to make assertions easier to read and easier to diagnose when there are errors.
Consider a test where we want to test if an object is a string. A traditional JUnit assertion might look like
<br />
<pre>Object o; // assume this is set during the test)
...
assertTrue(o instanceof String);
</pre>
The default failure message is <i>AssertionError</i>. I could make the error message more meaningful by adding an error message (this still won't work if o is null).
<br />
<pre>assertTrue("expected String but was " + o.getClass(), o instanceof String);
</pre>
Hamcrest matchers take of this for us.
The assertion can be rewritten as
<br />
<pre>assertThat(o,is(instanceOf(String.class)));
</pre>
Now the error message is <i>java.lang.AssertionError: Expected: an instance of java.lang.String got: <4%gt;</i>. Note the <i>is</i> is just syntactic sugar and is optional.
Hamcrest matchers also help to resolve the ambiguity between the expected and equals parameters.
A typical assertion for comparing two strings might look like:
<br />
<pre>assertEquals(expected,actual);
</pre>
The assertEquals method is easy to get wrong and reverse the actual expected, which will produce backwards error messages.
Using the hamcrest matchers, rewrite this is
<br />
<pre>assertThat(actual, equals(expected))
</pre>
All hamcrest matchers follow this pattern of <i>assertThat(actual, matcher)</i>, which make them read fluently.
More information about hamcrest matchers can be found <a href="http://code.google.com/p/hamcrest/wiki/Tutorial" target="_blank">http://code.google.com/p/hamcrest/wiki/Tutorial</a>. If you're writing Java unit tests, these provide a nice addition to the library.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-17952246477136063482012-07-02T17:19:00.000-04:002012-07-03T12:44:11.471-04:00Writing clean codeWhen I interview developers, one question I always ask is "What do you think makes code well written?" Almost without fail, I get the answer "It has a lot of comments."
While I'm not saying that good code shouldn't have any comments, usually have a lot of comments is indicative of code that is hard to read. Take this simple example of a method that checks if a number if an even number less than 100 or an odd number greater than 200.
<pre>
boolean isValidNumber(int number) {
// number is valid if it is even and less than 100 or odd and greater than 200
return (number %2 == 0 && number < 100 ) ||(number % 2 != 0 && number > 200)
}
</pre>
Sure, with a little bit of thought I can understand what this does or by reading the comments (if I trust them, I'll get to that shortly).
This version of the code
<pre>
boolean isValidNumber(int number) {
return (isEven(number) && number < 100) || (isOdd(number) && number > 200)
}
</pre>
With just this simple change the code just reads better and without the documentation.
While the documentation is valid in the first case and reading it does make the code just as easy to understand as the second version, what if I realized there was a change in the validation method and now my code looks like
<pre>
boolean isValidNumber(int number) {
// number is valid if it is even and less than 100 or odd and greater than 200
return (number %2 == 0 && number < 100 ) ||(number % 2 != 0 && number > 201)
}
</pre>
Now the documentation doesn't match the code. Six months later, I'm reading this code, and now I have a question - which is correct? Writing cleaner code makes the code easier to read and removes the potential for ambiguity. <b>Code should be written to be read by people, the computer doesn't care what it looks like</b>.
<br><br>
I started off by saying that I think good code can still have comments, but comments that are internal to methods should say <b>why</b> the code does what it does, not what it does. The code should be easy enough to read what it does. On a side note, I do think that documentation that says <b>what</b> the code does is appropriate for the javadocs public methods (or even on private methods since IDEs typically show the documentation when hovering over a method).
<br><br>
Talking about writing clean code is easy, doing it is much more difficult (which is why so few of us actually do). Practice and think about it consciously while writing code until it becomes second nature. I also recommend that all developers read Clean Code by Bob Martin (http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) at least once.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com2tag:blogger.com,1999:blog-4960432856702870094.post-1095463796022515832012-05-21T23:02:00.001-04:002012-05-21T23:04:30.078-04:00Automated provisioning of development environmentIt's pretty common to use automated scripting tools (chef, puppet, etc) for provisioning your servers, but what about your development environment tools? It's far too common that developers are developing and testing with different versions of the software that is used in production. This also leads to each developer having different versions of tools, which often leads to "It works on my machine."<br />
<br />
I've split this problem into two parts - IDE and tooling. Most of our developers use Eclipse, so I've geared my automation efforts toward Eclipse. Using the Eclipse p2 director, it is easy to script the installation of common plugins, settings, etc. Rather than mandating that developers download a pre-packaged distribution of Eclipse (which we then need to maintain), they can download whichever one they want (though most of developers use the Java EE version).<br />
<br />
Using the p2 director application, we have a simple groovy script that does the following:
<pre>
${eclipseExecutable} -application org.eclipse.equinox.p2.director -repository ${repoString} -installIU ${featuresString} -tag InstallInitialPlugins -destination ${eclipsePath} -profile ${profile}
</pre>
Hopefully the variable names are self explanatory.
<br><br>
For tooling standardization (maven, java, etc), I've setup some simple puppet scripts to pull in those tools (I'm currently working in Windows, and Puppet seems to work better than Chef on Windows). This does not connect to a puppet server, rather we just have a directory on our server that has the necessary files. The script just installs a couple of executables and copies some zipfile distributions. Since our toolsets are not changing all that frequently, the script is run on demand, but it could be setup with a Puppet server on a polling interval if desired. For more complex environments, a virtual machine could be configured with vagrant/chef.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-73963270798545204182011-10-02T16:17:00.005-04:002011-10-02T16:35:18.114-04:00Final variables in groovy with dynamic constructors and @TupleConstructorUp until groovy 1.8, it was not possible to declare variables in final as groovy when using the named constructor. Frequently with simple groovy objects, I would have a class that looks like this:<br /><pre><br />class Person {<br /> String name<br /> int age<br />}<br /></pre><br />It always bothered me that name and age could not be final. While I could declare an explicit constructor, such as<br /><pre><br /> class Person {<br /> final String name<br /> final int age<br /> public class Person(String name, int age) {<br /> this.name = name<br /> this.age = age<br /> }<br /> }<br /></pre><br />the explicit constructor is something the groovy helps eliminate the need for, and I always felt like it was a hassle to declare.<br /><br />However, declaring variables final is generally recommended when you won't be modifying the variable, so I was torn. final ensures the variable is not set again when you didn't want it to be. When working with multiple threads, final fields guarantee visibility across threads when the object is constructed.<br /><br />So in groovy 1.7, the options were to not make the variables final or to declare the explicit constructor.<br /> <br />Groovy 1.8 introduced the <a href="http://groovy.codehaus.org/gapi/groovy/transform/TupleConstructor.html">@TupleConstructor</a> annotation. By annotating a class, another constructor is created that uses default values for all of the values.<br /><pre><br /> @TupleConstructor<br /> class Person {<br /> final String name<br /> final int age<br /> }<br /></pre><br />So in this case, a constructor<br /><pre><br /> Person(String name, int age)<br /></pre><br />is created.<br /><br />Now both groovy and java classes can use this constructor, and the fields can be marked as final.<br /><br />Note that the constructor fields are in the order the properties are declared, so be careful when reorganizing classes (and test, test and test some more).Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com2tag:blogger.com,1999:blog-4960432856702870094.post-39940870784267604582011-05-02T19:50:00.002-04:002011-05-02T19:59:48.761-04:00Implementing the Decorator pattern using Groovy's @DelegateLet's say we want to write a decorator around a List to add a creation time to the list. We've all written something like this before, and it usually looks something like:<br /><pre><br />public class ListDecorator implements List {<br /><br /> private final List delegate;<br /> private final Date creationTime = new Date();<br /><br /> public ListDecorator(List delegate) {<br /> this.delegate = delegate;<br /> }<br /><br /> public Date getCreationTime() { return createTime; }<br /><br /> public void add(...) {<br /> delegate.add(...);<br /> }<br /><br /> public int indexOf(...) {<br /> return delegate.indexOf(...);<br /> }<br /><br /> // wrap all of the list methods<br />}<br /></pre><br /><br />This is very tedious, and we still need to write tests to make sure we actually delegated to the right method.<br /><br />Enter the groovy @Decorator annotation<br /><pre><br />// notice we don't need to implement the List interface here<br />// since we can take advantage of duck typing<br />class GroovyListDecorator<br />{<br /> // all of the calls to the list methods will be delegated to this list<br /> @Delegate final List delegate<br /> <br /> private final Date creationTime = new Date()<br /> <br /> GroovyListDecorator(List delegate) {<br /> this.delegate = delegate;<br /> }<br /> <br /> Date getCreationTime() {<br /> creationTime<br /> }<br />}<br /><br />And now we can use it like this:<br />def list = new GroovyListDecorator(new LinkedList())<br />// these methods delegate to the LinkedList delegate<br />list.add("abc")<br />list.add("def")<br />println list.size() // 2 <br />println list.creationTime // Mon May 02 19:49:55 EDT 2011<br /></pre><br /><br />And it's as easy as that.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com3tag:blogger.com,1999:blog-4960432856702870094.post-65811214019719986272010-12-08T20:46:00.002-05:002010-12-08T20:50:36.615-05:00Eclipse Hot Swap DebuggingMaybe this is a well known feature, but it was news to me. The Eclipse debugger supports swapping code out at runtime when debugging (JVM 1.4 and later). Ensure Build Automatically is enabled, then run your application in debug mode. When stopped at a breakpoint, change the code you want to change and save the file. The code will be automatically swapped into your application without restarting - pretty cool.<div><br /></div><div>This article <a href="http://www.ibm.com/developerworks/library/os-ecbug/">http://www.ibm.com/developerworks/library/os-ecbug/</a> gives some more details regarding debugging with Eclipse.</div>Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0tag:blogger.com,1999:blog-4960432856702870094.post-2570281905818222942010-06-01T19:35:00.002-04:002010-06-01T19:46:58.635-04:00Anti-PatternsWhile most good software development teams have knowledge of software patterns, I still don't hear teams frequently talking about anti-patterns. I'm not really sure why that is. It seems logical to me that if patterns are a way of communicating common ways of doing things, anti-patterns should be in a programmer's language to communicate how not to do things, and to identify problematic areas of code. Anti-patterns do also extend beyond code into management, organization, etc, but I will just focus on coding anti-patterns.<br /><br />One that I see so frequently is copy-paste-mutate. That is, when a developer copies a block of code, pastes it somewhere else, and changes it slightly. Most of it is duplicated and now mistakes are duplicates and testing must be duplicated (if you are testing). If you find yourself copying and pasting, stop. Should the functionality be in an abstract class? Should it be in a utility class? Regardless of where it needs to go, it shouldn't be copied and pasted.<br /><br />Another recurring anti-pattern is see deals with poor exception handling. It's way too common to see e.printStackTrace() or LOGGER.error(e) (or even worse, an empty catch block) as a solution to error handling. If you can "handle" the exception by just printing it out, maybe it shouldn't be an exception at all. Exceptions should indicate errors (i.e. exceptional cases) and your program generally shouldn't be able to continue to operate normally when one occurs without proper handling.<br /><br />Wikipedia has a large list of anti-patterns here http://en.wikipedia.org/wiki/Anti-pattern#Software_design_anti-patterns. Take a look and see which of these traps you're falling into.Jeff Storeyhttp://www.blogger.com/profile/12962059444292358245noreply@blogger.com0