Bad Code – Bad API, Bad Configuration

July 15, 2009

Was trying to use an library/jar file in my project today. The jar was a wrap around to call a webservice (lets call the interface Service and the implementation ServiceImpl), the code has interface and all that and even had a factory class (ServiceFactory) built in to initialize the Service for you. There was no source code, I only had the class files, so i browsed the classes through NetBeans to see how to best use it.

I am a big fan of dependency injection, I thought i could just use ServiceImpl to initialize the service and inject into the classes that need it, but there was something wrong. Look at the code below.


public class ServiceImpl{
private ServiceImpl(){}

public String methodOne(String string){}
public String methodTwo(String string){}
}

Did you see the problem? The constructor is marked private! There is no way to initialize the class! Except through ServiceFactory. Take note that this is suppose to be a class that calls a webservice, so I am still looking for a place where to put in the webservice url.

When I went to another colleague to ask how do I use it, he showed me sample code below.


Service s=ServiceFactory.getInstance();
s.methodONe(someString);

I asked how do I set the URL for the webservice? He told me the one (and only way) was to use the configuration file in the jar itself.

These are the problems as i see it.

  1. ServiceImpl constructor is private. That means I can’ test it by constructing a new object., i can’t inject it into my code since the only way to construct it is through ServiceFactory. I can’t mock it too since everything is done in the factory. This is not good, hard to test and hard to mock.
  2. There is only one way to configure the Service and that is through ServiceFactory and the config file. That means I can’t programatically configure it through code, that makes testing hard, that makes using other forms of configuration hard (like you own custom config file, Spring applicationContext and so on).  Singletons are Evil use DI frameworks if you can.
  3. The API is unclear, from the api you can’t really tell what is needed to use it. Except that you know you need to get it through a Factory. But since all the confguration and setting up is done in the factory, you can’t tell by looking at the API what is needed to set it up.

The last point is the main one i guess, the API is not clear, we can’t tell how to use except though some internal knowledge. It didn’t help that there were no javadocs, some of the parameters were names arg0, arg1, string1 (you get the drift).

For people who are writing apis for other people to use, perhaps take a look at Spring and Hibernate’s configuration design.

In short, if you allow your objects to be instantiated programatically , you allow the possibility of using properties files, xml files or custom files, look at Spring and Hibernate. This is especially important when writing apis/libraries that are going to be used by different projects.

Make the apis clear, if it needs a URL put the need somewhere in the constructor of the class. So that people know what is needed to instantiate it, the api can be the documentation especially with modern IDE like Eclipse and NetBeans.

Some links

Singletons are Evil

Singletons are not Evil


Securing Tomcat Manager to localhost access

July 9, 2009

Needed to secure my tomcat manager to localhost access only.

This is what you need to do.
In your /conf/catalina/localhost, create or edit a file call manager.xml.

Inside put the following.


<Context path="/manager" debug="0" privileged="true">

      <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1"/>

      <!-- Link to the user database we will get roles from
      <ResourceLink name="users" global="UserDatabase"
type="org.apache.catalina.UserDatabase"/>
        -->
</Context>

This should only allow localhost to connect to the manager application on tomcat.tom


Network connections folder empty ! After installing Win 2003 SP2!

July 9, 2009

After installing Win 2003 Service Pack 2 on a few machines, some started having this problem where the Network Connections folder is empty! My network connections still work (I still can connect and so on), just that I can’t see the network connections and hence can’t change the settings. WTF a service pack did this. Surprisingly only one of my servers was not affected.

Look around the net, didn’t really help, until I came to a post from Crapola. Apprantly his AD had problems after install Sp2. The solution was actually quite simple.

  1. Change Network Connection service to “Automatic” (Don’t know why it was set to manual)
  2. Look for the RPC service and changed the Log on user to “Local System Account”

And all should work. Dumb service pack…


Ivy Problems

June 23, 2009

My build server using Cruise Control and Ivy to manage project dependencies encountered an error today. Our original Project (lets call it WEB) only had one dependency call DB, so we used IVY to managed the dependency.  Now WEB depends on another new library called FILE, and i started seeing errors  like “impossible to publish artifacts …. ivy destination already exists” whenever i publish a new version.

Our ivy settings file was like this.


<ivysettings>
  <settings defaultResolver="libraries"/>
  <resolvers>
    <filesystem name="libraries">
      <artifact pattern="D:/ivyrepository/libs/[artifact]/[artifact]-[revision].[ext]" />
    </filesystem>
  </resolvers>
</ivysettings>

The reason is that both FILE and DB are writing ivy.xml files to the same directory,D:/ivyrepository/libs/ivy. Seems like you need to seperate the ivy files for both modules into different directory.

I changed the settings file to below, note the new “<ivy pattern=” part, it now puts the respective ivy files in the correct directory under each module.


<ivysettings>
  <settings defaultResolver="libraries"/>
  <resolvers>
    <filesystem name="libraries">
	  <ivy pattern="D:/ivyrepository/libs/[module]/ivy/ivy-[revision].xml"/>
      <artifact pattern="D:/ivyrepository/libs/[artifact]/[artifact]-[revision].[ext]" />
    </filesystem>
  </resolvers>
</ivysettings>

Hope this helps those who are setting up their own private ivy repository.


Cross Domain boundaries – Silverlight

June 10, 2009

Found this page on MSDN that shows you what you need to do to allow cross domain calls from Silverlight.

Probably will do a post on what I think about Silverlight in a few more weeks. Aim would be try to have a feel of how Silverlight, ASP.NET type of application would contrast with a Ajax (Ext.JS) frontend and Spring MVC kind of application.

Links:
Making a service available across Domain Boundaries


Installing Silverlight tools offline

June 8, 2009

Was trying to install Silverlight tools at work, but my development machine has no internet connection and silverlight_tools.exe just wont install. It seems like it was trying to download something which I later found out was the silverlight developer runtime.

Even if you already installed the developer runtime separately the installation will still attempt to download the latest version of it. Found this page from Tim Heur which documents how to install silverlight offline.

I personally think that Microsoft’s approach to distributing the Silverlight tools is wrong. It just makes it difficult for people to work. They should just bundle one copy of the developer runtime in and save a lot of people some time trying to google for the answer.

Links
Installing Silverlight offline


Hashmaps and JSTL

June 3, 2009

Learnt a few things about how to use HashMaps in JSTL.

To access a hashmap with a key in JSTL.

${map.key} or ${map[key]}

If your key is from some other variable or you need to set the key dynamically


//Create a variable call keyName and set the value to something
<c:set var="keyName" value="${someObject.id}"/>
<c:out value="${map[keyName].id}/>

SLIME, SBCL and Windows

June 1, 2009

I was having lots of problems setting up SBCL 1.0.22 and the latest SLIME CVS in Emacs 22.3.1. I had lots of help from the SLIME mailing list and this is my final .emacs files.

I am assuming that you have installed/unzip everything into a directory called c:\lisp on your system. WIth SLIME in c:\lisp\slime and SBCL in c:\lisp\sbcl.

(add-to-list ‘load-path “C:/lisp/slime”);Your slime directory
(setq inferior-lisp-program “sbcl -core c:/list/sbcl/sbcl.core”); your lisp system
(require ’slime)
(eval-after-load “slime” (slime-setup ‘(slime-repl))) ;This is different from the documentation


Lessons from Robert Martin Keynote (What killed Smalltalk could kill Ruby too)

May 24, 2009

Robert Martin gave the keynote at this years Rails Conf. Beside learning about some programming history and other interesting bits of knowledge , there are a few lessons that most developers can take away from the talk.

1. Clean Code has zero WTF/min

Most interesting  way of measuring if the code is clean. All programmer should take note of this. Even when i read my own code after some time, I tend to think “WTF, what made me write that crap”.

Peer review and refactoring helps in this aspect but many development teams don’t do it. It takes quite a lot to make programmer’s write tests when we are always faced with deadlines.

One reason is that during school,  TDD isn’t really emphasized when doing software projects. Perhaps, universities and polytechnic should start teaching people what are good practices, things like Design pattern’s, TDD, source control and so on. Grade projects not only on the functional and design aspects but also on the practices aspect. See if they write tests and see if their tests are maintained still work when the project is done.

2. Rules/Laws of TDD
The laws

  1. You may not write production code until you have written a *failing* unit test.
  2. You may not write more of a unit test than is sufficient to fail, and not compiling is failing.
  3. You may not write more production code than is sufficient to pass the current failing test.

3. Professionalism
Robert also talks about what being professional means. Simple to say it means not bowing down to fear and not taking corners when the going gets tough.

Links

RSpec
Ward Cunningham on Wikipedia
Ward Cunningham on Twitter
Robert Martin’s Page at Object Mentor
Robert Martin Page at Wikipedia
Rules of TDD


Using Ruby and ERB for code generation

May 20, 2009

In my current project (using Java, Spring MVC and ExtJS), we have a lot of modules for data entry and since there were similarities in all the modules (and the fact is we had like 20 of these to code) we decided to take a closer look at code generation.

But what tool to use? Stumble upon ruby in the book Code Generation in Action and found a chapter on code templates and the example uses Ruby and ERBs. I thought wasn’t ERB’s used in Rails like JSP’s? I thought i needed to write web programs in order to generate the code. But boy was i wrong, we could actually use ERBs from any Ruby programs.

Sample of the ruby file – test.rb


require 'erb'

erb=ERB.new(File.open("test.erb").read());
name='Stephen';
code=erb.result(binding);
print code;

Sample of the ERB file – test.erb


public class <%=name%>{
}

What’s happening here, the name variable that you defined in test.rb is passed to the erb file when erb.result(binding) is execute and it returns the results of the erb file. You can pass in arrays, hashes from the code to the erb file easily just by calling the erb.result(binding) method.

Our experience – Great ! We wrote generators to generate our javascript menus, spring MVC views (which are in ExtJS) to Spring Controller to Hibernate DAOs. It does save us sometime in do repertitive work.

If your project has lots of similar components that you need to code. Why not take a look at code templating using Ruby and ERB.