Showing posts with label picocontainer. Show all posts
Showing posts with label picocontainer. Show all posts

Tuesday, March 15, 2011

Developing PicoContainer 3.0 in Eclipse with the Maven Plugin

 

Problem

When you first import the PicoContainer project into the Eclipse IDE, the base project will compile fine, but any additional project will contain the error:
“The project was not built because its build path is incomplete.  Cannot find the class file for com.googlecode.jtype.Generic.
You might also see a similar message refering to a class in: javax.inject.* or com.thoughtworks.paranamer.*
However, if you drop to the console and try to build it manually, everything works peachy.
What’s going on?

Explanation:

To keep 3rd party dependencies to a minimum, PicoContainer’s core build process uses the maven-shade-plugin to wire in a couple of utility jars in picocontainer.jar.  That’s all fine and dandy, but Eclipse doesn’t understand what’s going on in the build processes and complains.
There are three jars that are getting shaded that Eclipse isn’t finding:
<dependency>
    <groupId>com.thoughtworks.paranamer</groupId>
    <artifactId>paranamer</artifactId>
</dependency>
<dependency>
     <groupId>javax.inject</groupId>
     <artifactId>javax.inject</artifactId>
     <version>1</version>
</dependency>
<dependency>
    <groupId>com.googlecode.jtype</groupId>
    <artifactId>jtype</artifactId>
     <version>0.1.1</version>
</dependency>

 


Solution:


Manually add the jar files to your build path in Eclipse and everything will work fine. 

To do this:

  1. Right click on the project, Select Properties
  2. Click on Java Build Path
  3. Click on the Libraries tab.
  4. Click on Add External Jar
  5. Repeat adding external jar until you’ve added all three jars into your project.
Hint: The jars can be located in ${userhome}/.m2/repository since Maven will have automatically downloaded them for you.
When you use Maven to create final artifacts, Maven will behave appropriately shade in the three jars into picocontainer.jar, and all applications will behave as if those jars are appropriately in the classpath.

Saturday, March 12, 2011

PicoContainer Auto-Wiring and type safety.

One of the things that people often criticize (unjustly, I might add) about PicoContainer is that it recommends Auto-wiring wherever possible: When an object is constructed, PicoContainer searches for the best possibility to serve as its dependencies.
Chariot Framework and in particular, the front controller, Chariot Command relies heavily on PicoContainer autowiring, because even though you can use Pico’s ‘parameter’ ability to specify constructors, method argument matching is impossible if it isn’t autowireable. 
(Note, this original post was written before javax.inject annotations became available – however, I still haven’t gotten hugely into the annotation markup.)
But it has had an interesting side effect:
Instead of having all sorts of HashMaps scattered around the code base, I have been creating lots of little maps that derive from AbstractMap. One map for each type of ‘map’. Examples in Genesis Command are:
RequestAttributeMap
SessionMap
ParameterSource
None of these classes have been hard to create – in fact, they’re pretty simplistic. But it allows me to use autowiring to its fullest capability. (And frankly, I HATE having to use the specific parameters – I avoid them if at all possible.)
The thing that has become clear after using this technique since 2003: it is highly beneficial to code maintenance for a couple of reasons:

1 – The intent of the map is evident by its type, not just the variable name.

I can easily find where this type is being used thanks to IDE searching facilities, and the purpose of those functions that use the type is quite evident.

 

2 – I don’t lose any capabilities

If I need a generic algorithm, I can still use them because each of the above maps still implement the Map interface, so I don’t lose any capabilities there.

 

3 – I can better tie in behavior with the objects.

One day I needed to be able to determine if a ‘command parameter’ was present in the parameters my Web command object was receiving. With the design I had chosen to avoid autowiring, the solution was simple – add the query behavior to ParameterSource.
I had a clean, encapsulated implementation whereas the other way around, most would have used functions to examine the map and decide if a command parameter was present.
So hats off to PicoContainer and its auto-wiring capabilities. My program structures are significantly improving because of it!