Servlet Event Listeners: Did you know?

… you could automatically register any number of servlet event listeners (ServletContextListener, HttpSessionListener, ServletRequestListener, and more …) without any additional web.xml line?

The Java Server Pages 2.0 specification dictates that all .tld files inside META-INF directories, from jars in the web application classpath (WEB-INF/lib), must be read and parsed by the Servlet Container (JSP.7.1.9 – Event Listeners).

Fortunately, .tld files accept the <listener> element. What about creating reusable jars (web frameworks?) and do their setup inside such listeners, as Sun JSF RI (Mojarra) is doing:

<!-- jsf-impl.jar!/META-INF/jsf_core.tld -->
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
  version="2.1">

  <description>
    The core JavaServer Faces custom actions that are independent of
    any particular RenderKit.
  </description>
  <tlib-version>1.2</tlib-version>
  <short-name>f</short-name>
  <uri>http://java.sun.com/jsf/core</uri>

  ...

  <!--
    This ServletContextListener initializes the runtime environment
    of the JavaServer Faces Reference Implementation when a web
    application including it is initialized by the container.
  -->
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>

  ...
</taglib>

That said, why am I still having to add <listener> from web frameworks in my web.xml?

RejectConf SP’07 and Conexao Java 2007

RejectConf SP'07

It was a great time last weekend, spending part of my holiday at RejectConf SP’07 in Brazil, “our first relevant conference”, as said by Fabio Akita.

Attendees

The lectures were really great and the coffee-break (thanks Caelum) really came on the right time. During his RSpec talk, Danilo Sato created a web application to rate the presentations. As you can see there, the coffee-break shined. It was a pleasure to meet new people from our community and to see old friends.

I talked about the most fantastic project nowadays and fortunately people seemed very interested about it. Get the slides.

RejectConf SP'07

One week before (10 Nov 2007), I was at Conexao Java 2007 and gave a mini-course (~6 hours) about JSF, Ajax and Richfaces. Great time too, thanks to all attendees!

You can get the slides and code here. More info at the Caelum Blog (pt-BR).

Comments to Gavin King about DDD and Repositories

I was replying the Gavin King’s question about Repositories and DDD, but the comment started to become really big and I wasn’t sure if the code snippets would be well formatted. So, I decided to reply it here.

I had similar questions about Repositories. I’m from Brazil and we have discussed it many times here (see at GUJ and at my post in the Caelum Blog – unfortunately – in pt-BR; perhaps, translation tools can help). I have a personal and pragmatic conclusion that may help.

I won’t discuss if DDD is good or not, but I will suppose it is. The root problem is the way that DAOs are being used. In the classic Client --@OneToMany--> Order, if it is given a client (id=1) how could we get his orders since 10/10/2006?

Almost everyone would do dao.findOrdersFor(client, since), but that is clearly procedural (actually, not always a bad thing). What I wanted to do is client.getOrdersSince(date).

Now, suppose I love DDD and really want to do client.getOrdersSince(date). The client should be able to give its orders, that’s the “DDD-way”. How could I implement it? Load all orders in memory (maybe a regular @OneToMany mapping) and then filter what I want (bleh!) isn’t an option. One option would be as below:

class Client {
  private final ClientDao dao;
  Client(ClientDao dao) {// ioc here...}
  public List getOrdersSince(Date date) {
    return this.dao.findClientOrdersSince(this, date);
  }
}

Hmm… what about separation of concerns? DAOs are related to persistence, and persistence is infrastructure, not domain (or business related).

This is what repositories try to solve. They are a domain concept, from where we can get other domain objects. To be “DDD-compliant”, I would do:

class Client {
  private final OrderRepository orderRepository;
  Client(OrderRepository repository) {// ioc here...}
  public List getOrdersSince(Date date) {
    return orderRepository.findForClientSince(this, date);
  }
}

But err… what’s the difference? Just the name? YES! But the names are important, right? πŸ˜‰

Actually, some people would rather Repositories as interfaces, and Daos might be their implementations. What really matters is that domain objects shouldn’t have to deal with infrastructure things like persistence. A Repository has nothing to do with persistence, it’s a domain concept. Lists and Maps (any container) are repositories too.

I also rate the idea to have more layers (completely agreed with you):

Client -> OrderRepository(just an interface) -> OrderDao -> Hibernate -> ...

I would just drop the indirection and make the Repository concrete:

Client -> OrderRepository -> Hibernate -> ...

Duh. You can ask: “have you just renamed the Dao?” I would say: “yes, but aren’t the names important?” πŸ˜‰

Remember why I did it. I wanted to do client.getOrdersSince(date) and the client shouldn’t know anything about persistence. He doesn’t care if the repository is just a plain list or use hibernate. Repositories are domain objects, daos aren’t.