Google Guice: IoC revisited

2007-03-08  |   |  ioc   java  

Google has made public his IoC container. It's all annotations based, no more strings, no more XML.

Some key concepts:

  • Avoid string based injection which are error prone and hard to refactor
  • @Inject actually inject :-)
  • @ImplementedBy(ServiceImpl.class). A service can have a default implementation, use by default when no wiring is explicit. The actual implementation is easily identified, including by your IDE...
  • Injection through custom annotations (even parameterized): useful when you need to bind 2 services implementations and use one or the other. Also useful to bind constants: Guice allows you to bind a constant to an annotation.
  • Scoping: injections are scoped, and you can create you own scope (transaction). Inner scopes can see outer scopes.
  • Because it's Bob Lee: Guice has integration with AOP Alliance is supported
Here are some examples:
Basic injection
public class Client {
private final Service service;

@Inject
public Client(Service service) {
this.service = service;
}

public void go() {
service.go();
}
}


Default for autowiring
@ImplementedBy(ServiceImpl.class)
public interface Service {
void go();
}

Custom annotations
bind(Service.class)
.annotatedWith(Blue.class)

.to(BlueService.class);

...

@Inject
void injectService(@Blue Service service) {
...
}


What I really like:
  • Annotation based, easy to read and concise
  • Injection on methods (not only setters)
  • @ImplementedBy: Most services, they are implemented one and only one time.

I remember the old days of Pico vs Spring vs Avalon. I'm happy to see innovation flowing again in this field. Some took for granted that Spring was the only way, then come annotations. JBoss Seam and its annotation based stateful injection / outjection, and now Google Guice: both share some of the interesting concepts I described earlier. Component injection is revisited and it's good.

Now remember, IoC is not application development, it's at best a part of it :-). To me, the programmation model with the biggest/homogeneous picture is JBoss Seam.


Hibernate + Seam team meetup in San Fransisco

2007-02-28  |   |  hibernate  

This is a pretty rare event, (almost) all the Hibernate + Seam team will be together in San Fransisco end of this week.

We organize a meetup on Friday (March 2nd) at 7 PM

Levende Lounge
1710 Mission St. @ Duboce
San Francisco, CA 94103
Phone: 415.864.5585

http://www.levendesf.com/

Please drop me an email (emmanuel # hibernate.org)
if you intend to come to this event. There is usually a cover charge for this place on a Friday night, so we need to get people's names on the door list.


SVN: false promises

2007-02-06  |   |  tool  

I've had to do a massive project refactoring. To be more specific, I had to split Hibernate Annotations in several pieces and make Hibernate Validator and Hibernate Search independent projects (stay tuned). Of course, I wanted to keep track of my changes history.
Supposedly, SVN is greater than CVS in this area, it can keep track of object renaming and copying without loosing tracks.

I've never had such troubles in a long time. A few tricks:
- IntelliJ package renaming is great but don't try to do too much in one commit: nothing is more annoying than a cryptic version control error after a complex refactoring.
- svn move of complex structure does not seems to work properly in local move: prefer using the svn move url1 url2. For the record, SVN ended up moving part of my tree without any complaints :-(
- don't expect to update a directory and move/rename it, SVN will actually prevent you to do so (at least the complex one I had)

So I ended up branching, committing my package renaming, doing server side svn move of my packages around the different projects. I wish I could have done that in an atomic way with no branching.

I'm not a SVN expert, but I usually don't expect my tools to require a PhD in version control, and a driver license to use them. There are huge rooms for improvements here. Think users :-)

For me SVN is not really better than CVS (except the local diff/revert).


Groovy Annotations

2007-01-24  |   |  groovy  

I have been hammering (nicely) Guillaume for a long time now to get Annotations support in Groovy.
Thanks to Alexandru Popescu, this is now an official work in progress, and one that progress well :-)
I am thrilled by the possibilities to combine JavaEE (or any modern annotation based framework) and Groovy. If you wondered about the dynamic language you wanted to use, don't anymore.

Like the Hibernate team when we worked on the Java Persistence certification, the Groovy team must have been very frustrated to focus on Groovy 1.0 and not being able to innovate as fast as they did. They are now back on track.

Give a try to Groovy SVN trunk and enjoy.


To copy a file in ...

2007-01-12  |   |  groovy  

... Java

private static void copyFile(File srcFile, File destFile) 
throws IOException {
FileInputStream is = null;
FileOutputStream os = null;
try {
is = new FileInputStream(srcFile);
FileChannel iChannel = is.getChannel();
os = new FileOutputStream( destFile, false );
FileChannel oChannel = os.getChannel();
oChannel.transferFrom( iChannel, 0, srcFile.length() );
}
finally {
if (is != null) is.close();
if (os != null) os.close();
}
}

... Groovy
static void copyFile(File source, File destination) {
def reader = source.newReader()
destination.withWriter { writer ->
writer << reader
}
reader.close()
}

... Groovy with a salt of Ant
static void copyFile(File source, File destination) {
new AntBuilder().copy(file:'$source.canonicalPath',
tofile:'$destination.canonicalPath')
}

... in shell
cp source destination


ActiveRecord pattern, so what?

2007-01-07  |   |  grails   java   persistence  

The Active Record pattern has a lot of publicity recently thanks to the Ruby On Rails and Grails wave. A definition could be: an object that encapsulates both data and behavior (ie a database row and it's data access logic).

A bit of history
I was asked recently my thoughts about this pattern. First of all, if someone still remembers EJB 1.0 and 2.x Entity Beans, this was a perfect example of the Active Record Pattern... and a successful failure. Some of the reasons for this failure was the tight link between the data and it's access logic: Serialization issue, data tight to a persistent technology etc etc.

Statically typed languages
To me the ActiveRecord pattern is not well suited for statically typed languages like Java, hence the raise of another pattern : DAO (aka DAL in the .net world). It prevents the hard link between the persistence technology and the actual data representation.

Dynamic languages
Dynamic languages (and to a certain extend AOP) have the nice ability to decorate an object with additional features on the fly, without linking it "the hard way": you can then easily reuse your domain classes out of the persistence context.
Grails uses such a behavior to add CRUD operations transparently to your domain model (with quite complex Querying capabilities).
One still face a problem, what if the application developer needs to add a more complex persistence operation (esp a query), he will end up "hard-coding" the function to the domain object and we're back to the issue faced by statically typed languages... unless you create a DAO object. But then, your persistence operations will be split between your implicit domain model methods and your DAO: another code smell.

Dynamic DAO
As you can see, I'm not keen on the ActiveRecord pattern (out of simple applications), but I really love the simplicity of GORM (the Grails way). The solution is a dynamic DAO. JBoss Seam already generates very simple yet powerful DAOs benefiting from Java Generics. If you combine that with a dynamic language, you can have the best of both worlds.

class UserProcess {
@In UserDao userDao;

void create(String firstname, String lastname) {
if (userDao.countByFirstnameAndLastname(firstname, lastname) == 0) {
def user = new User( "Emmanuel", "Bernard" )
userDao.save user
}
else {
throw new UserAlreadyExistException()
}
}
}


Note that countByFirstnameAndLastname and save can be dynamic methods à la GORM.

Conclusion
I'm not a big fan of the ActiveRecord. For static languages, I would use the DAO approach. For dynamic languages, I did not make up my mind but a DAO on steroids seems very promising.


Name: Emmanuel Bernard
Bio tags: French, Open Source actor, Hibernate, (No)SQL, JCP, JBoss, Snowboard, Economy
Employer: JBoss by Red Hat
Resume: LinkedIn
Team blog: in.relation.to
Personal blog: No relation to
Microblog: Twitter, Google+
Geoloc: Paris, France

Tags