Thursday, April 9, 2009

Installing SQL Server 2008 with Visual Studio 2008 SP1

When I brought up my most recent Windows development machine (on Vista Ultimate), I installed Visual Studio 2008 Professional with SP1 embedded. Later, I went to install SQL Server 2008 including the "Management Tools" option so that I could have SQL Profiler and the other tools. That's when the problems started. The installation was blocked failing this rule:

Rule "Previous releases of Microsoft Visual Studio 2008" failed

Imagine my surprise when I found this article indicating that the problem was that I didn't have VS 2008 SP1 installed. I'm sure that I was running SP1, because I was seeing SP1 bugs manifested (requiring hotfixes). These bugs were only present in SP1 as of the time of this writing. It seems that a required registry key or something didn't get set when I installed Visual Studio. I really didn't want to get into hacking on the registry.

Solution



I downloaded the Visual Studio 2008 SP1 installer and ran it. This took quite a while, and I'm now up much later than I planned. However, I can report that this got me past the installation block. I'm not sure if I'll have to reinstall those hotfixes or not...

Happy coding!

Wednesday, March 11, 2009

Standing on the Side of Right

Anyone that has worked with me will tell you that I am passionate about getting things right. I like to fix things that are broken. I like to improve my skills. I like to challenge others around me to improve and I expect them to do the same for me. I rarely miss the opportunity to improve myself or to encourage others to prove. I love teachable moments.

This morning, after reading Alan's thoughtful post on sexual harassment in the IT industry, I wonder where I have missed those teachable moments in the non-technical areas of my career. Though I don't have any women on my current team, I have worked with them in the past at other jobs. Though I have never done anything as egregious as what Alan describes, I hope that I have treated them with respect and dignity. I believe that I have. However, I am sure that I have also missed opportunities to help men around me be respectful, considerate, and just plain decent.

Though the original article was about sexual harassment, this is an issue that transcends gender. Sexual harassment is merely a single form of being a jerk. At my company, like many others, there are rules against being a jerk about certain taboo areas: gender, religion, age... We shouldn't be relying on corporate policy to define decency.

True confession time. I'm an ass. I hope that today I am less of an ass than I was ten years ago. But, truth be told, I still have some ass-like tendencies that pop up when I least expect them. I hate that.

Some of you know me well enough to know my beliefs. I am happy to say that I am a follower of Jesus Christ and that I have trust in Him alone to guide me through this life and the next. If my beliefs are to be consistent with my actions, then I must continue to fail forward in this area of how I treat those around me. To be consistent, I must treat everyone with respect and encourage others to do the same. To be consistent, I must be willing to admit when I am wrong (often). To be consistent, I must build other up rather than tearing them down. To be consistent, I must treat people like... people.

That brings me back to the original topic of this post. We must treat our female peers with the respect that they deserve, and we must insist that others do as well. Look around you. Are you standing up for others? Are you defending the sanctity of the lives around you? Where, dear reader, do you need to improve?

Saturday, January 31, 2009

When Collections Are Configuration - binding Collections in Guice

Classes that create their own internal domain objects and simple objects are typically not a problem for testability. The problem comes when classes are creating their own dependent services internally. Then, you've got a problem cutting the testing seams. Creating these dependent services is what Dependency Injection is best at. Using your IoC container to create everything constitutes container abuse.

However, I will use my IoC container of preference to create populated collections if the contents of those collections are inherently configuration. For instance, assume we have the following class:


public class Validator<T> {
private Collection<Validation<T>> validations;
private ValidationProblemReporter reporter;

public Validator(Collection<Validation<T>> validations,
ValidationProblemReporter reporter) {
this.validations = validations;
this.reporter = reporter;
}

public validate(Collection<T> elements) {
for(Validation<T> validation : validations) {
for(T elements : elements) {
if (!validation.isValid(element)) {
String m = element.toString() + " fails " + validation.toString();
reporter.reportProblem(m);
}
}
}
}
}


we frequently use a validation pattern that calls for a Collection<Validation<T>>. These validations vary from project to project, but the Validator<T> class is the same from project to project. The actual validations used varies depending on the validation requirements of the project and the type of the object that is being validated. Each instance of Validation<T> is pure business logic, and each is properly unit tested.

Determining what to put in the Collection<Validation<T>> is simply a configuration concern. This is where it is easy to use the IoC container. Since Guice is what I typically use, that's what I'll show.

Example: Say, we are dealing with Customer objects that we are importing into the system. These customers are being imported from someone else's system into ours. So, we are not sure if each customer object is valid and we only want to import the objects that are valid. There are multiple ways to bind up the collection of validations, among them are using TypeLiteral and using a marker class. For this, I will show the marker class, but I've also used TypeLiteral.

So, since I want to validate Customer, I create a class like:


public class CustomerValidations extends ArrayList<Validation<Customer>> {
//marker class
}


Now, I'll write a marker for the validator:


public class CustomerValidator extends Validator<Customer> {
@Inject
public CustomerValidator(CustomerValidations validations,
ValidationProblemReporter reporter) {
super(validations, reporter);
}
}


To get Guice to inject the dependencies into the CustomerValidator, we'll need to bind CustomerValidations and ValidationProblemReporter. So, I would have a Guice Module that looks something like:


public MyModule extends AbstractModule {
public void configure() {
bind(ValidationProblemReporter.class).to(ConsoleReporter.class);
bind(CustomerValidations.clas).to(CustomerValidationsProvider.class);
}
}


We'll have to write the provider for the CustomerValidations:


public class CustomerValidationsProvider implements Provider<CustomerValidations> {
public CustomerValidations get() {
validations = new CustomerValidations();
validations.add(new CustomerShouldHaveAName());
validations.add(new CustomerShouldHaveAnEmailAddress());
...

return validations;
}
}


This cuts a very nice seam to configure which validations we want to run over our customers. I can easily write a unit test that asserts what validations we have configured. In fact, if order is important, then I can check that as well.


public class CustomerValidationsTest {
@Test
public void we_should_do_the_right_things_in_the_right_order() {
CustomerValidationsProvider provider = new CustomerValidationsProvider();
CustomerValidations validations = provider.get();
Iterator<Validation<Customer>> iterator = validations.iterator();

assertEquals(CustomerShouldHaveAName.class, iterator.next().getClass());
assertEquals(CustomerShouldHaveAnEmailAddress.class, iterator.next().getClass());
assertFalse("Should not have any more", iterator.hasNext());
}
}


Now, we have locked down our configuration such that if we change the validations, we have to change this test. I wouldn't always lock the configuration like this, but I often do.

Guice allows you to unit test your configuration (since it's all Java). Figuring out what needs tested and what doesn't can be an art form. You'll get a better feel for it with experience.

Thursday, January 22, 2009

Hudson Default Ant

Most Hudson configuration is self-explanatory and easy to find in the web configuration. Many props go to the developers of Hudson because it is quite easy to setup and use. However, there are a couple of things that I've found lately that don't seem to be documented in the Hudson docs.

Configuring Ant


From the Hudson dashboard, click on
  Manage Hudson -> Configure System
or you can simply navigate to
  http://your-server-here/hudson/configure

Look for the section labeled "Ant" and add your Ant installations by clicking "Add" and providing a name and the absolute path for ANT_HOME. This couldn't be simpler.

Default Ant


When you are configuring a build, you can tell Hudson which Ant you want to use. You may either use one of the named Ant installations that you previously added, or Hudson gives you the option of using the "Default Ant."

For some reason, I was thinking that I had somehow set the only Ant installation that I added as the default (since it was indeed the only one). But, this was not the case, and my build failed with this console output:

FATAL: command execution failed.Maybe you need to configure the job to choose one of your Ant installations?
java.io.IOException: Cannot run program "ant" (in directory "/home/tomcat/hudson/jobs//workspace/build")


Then, I got to looking at how to set the default Ant, and I could not for the life of me find the setting anywhere. This is because, there is NO default that can be changed from within Hudson.

If you tell Hudson to use the default Ant for a build, then it will use whatever ant it finds on the PATH. Note that I did not say that Hudson will use whatever ANT_HOME points to. Hudson must be able to find the ant command on the PATH.

In our case, Hudson runs as the user 'tomcat.'

So, if I wanted to use the default Ant for a build, I would typically solve this by setting both the ANT_HOME and PATH environment variables for the tomcat user. I would set ANT_HOME to the Ant installation that I wish to use as default, and I would then add $ANT_HOME/bin to the PATH environment variable.

What I Actually Did


Since I really didn't care to go to all that trouble of setting environment variables, I just used the named Ant instance that I had already configured in Hudson. We do not have a default Ant available to Hudson, and it's not a problem.

Wednesday, January 21, 2009

Hudson Gets an AccessControlException when starting on Ubuntu Tomcat

With fresh install of Ubuntu 8.10 I grabbed Tomcat 6 from Synaptic. Then, I dropped the hudson.war into the Tomcat webapps directory, and was greeted with an AccessControlException and a Hudson that would not start.

This is because on Ubuntu, Tomcat default installs with the Tomcat Security Manager enabled. This is probably a good thing for many installs of Tomcat, but it interferes with Hudson. When we finally found the problem, we took the lazy road and disabled the Tomcat Security. Depending on your install, this may be an unsafe decision. I would check the Tomcat documentation before doing this if your server is externally exposed. In our environment, the build server is on a completely trusted network. So, we didn't care much.

Here is the stack trace that is displayed when first trying to browse to the Hudson app:


HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Error instantiating servlet class org.kohsuke.stapler.Stapler
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.lang.ExceptionInInitializerError
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

root cause

java.security.AccessControlException: access denied (java.util.PropertyPermission org.apache.commons.logging.LogFactory.HashtableImpl read)
java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
java.security.AccessController.checkPermission(AccessController.java:553)
java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
java.lang.System.getProperty(System.java:669)
org.apache.commons.logging.LogFactory.createFactoryStore(LogFactory.java:320)
org.apache.commons.logging.LogFactory.(LogFactory.java:1725)
org.apache.commons.beanutils.ConvertUtilsBean.(ConvertUtilsBean.java:130)
org.kohsuke.stapler.Stapler.(Stapler.java:659)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:532)
java.lang.Class.newInstance0(Class.java:372)
java.lang.Class.newInstance(Class.java:325)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:636)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.



This was fixed by changing:

/etc/default/tomcat6


And setting the following property:

# Use the Java security manager? (yes/no, default: yes)
# WARNING: Do not disable the security manager unless you understand
# the consequences!
#TOMCAT6_SECURITY=yes
TOMCAT6_SECURITY=no


Note that we left the commented example in place for future reference. I hope this helps someone else. Mostly, I'm hoping that by writing this down, I will remember this in the future or at least be able to find the solution quicker.

Go forth and write tests...

Wednesday, January 14, 2009

Cool Code Snippet Tool

Simple post for my own memory:

The best online code snippet posting tool that I've found is at http://pastebin.com/. It has great syntax highlighting for a variety of languages (including Groovy) and it is very easy to use.

Wednesday, January 7, 2009

Tests Drive Good Design

Test-first development leads to better design in the production code. Specifically, you get much lower coupling (both internally and externally), and you get much higher cohesion.

For those of you unfamiliar with those two terms, Coupling is tying one class to another. For instance, if ClassA relies on ClassB to do some work in such a way that a break in ClassB causes unit tests for ClassA to break, that's coupling. We try to limit coupling so that individual classes are isolated. We will always be coupling our classes to a degre (if java.lang.String breaks, everything breaks), but we try to keep it to a minimum. We want classes with low coupling because it is easier to isolate change.

Cohesion is how well the responsibilities within a class relate to each other. Highly cohesive classes tend to be small chunks that are easy to understand because they have a single responsibility. If you are tempted to answer the question, "What does this class do?" by using the word "and" a bunch, then you have a class with low cohesion. We want classes with high cohesion because they are easier to understand and thus easier to change.

When you write good unit tests, especially when you write them first, its easy to detect classes that are NOT highly cohesive and have low coupling. Tests become much more difficult to write when you stray from sound coding practices. If you weren't writing unit tests, you might be tempted to simply "new up" a dependency. Testing drives one to inject dependencies to create better seams and better class isolation.

The bottom line is that testable code is better code. It is easier to change, easier to understand, and overall easier to support.