jueves, enero 27, 2011

Ay Ay Ay Amor Yo Soy Satélite y Tú Eres Mi Sol






Tomcat 7 comes with a lot of new features, like Servlet 3.0 specification, filter for preventing CSRF attacks, and more and more features. One feature that I really like is the simplicity that has acquired embedding a Tomcat into an application.

First of all you are not required to download all archives; there is a separated link for downloading only required jars

Second one is how easy is to create a tomcat instance and add the directory where web application is deployed.

String webApp = ...;
String tomcatDir = ...;

Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(tomcatDir);
tomcat.setHostname("localhost");

tomcat.addWebapp("/", webApp);
tomcat.start();
tomcat.getServer().await();


Only three sections:
  • Configure Tomcat. The base directory for temp files.
  • Adding information about where web application is deployed and which context path should serve it.
  • Starting server and waits until application is closed.


I have not found in Tomcat documentation something like Jetty that you can set a War file and container is the responsible for unpacking it. I think that in case of Tomcat some actions should be taken by developer for unpacking it.

I am not going to discuss about what embedded server is better, if Jetty or Tomcat, each one have their features, and their advantages and disadvantages, this post is only written as a resource for teaching how to embed tomcat into an application.

sábado, enero 08, 2011

No Me Digas Más Y Márchate, No Llames Amor A Tú Hipocresía

I am a huge fan of Clean Code Book written by Robert Martin Clean Code: A Handbook of Agile Software Craftsmanship. I think it is a 'must have' that every developer should read at least one time. Someof recurrent themes in the book is following a rule called KISS (Keep It Simple, Stupid) [Tangling] and DRY (Don't Repeat Yourself) [Scattering], and a full chapter about naming. Now I am going to explain how to apply this principle when developing Aspects with Spring AOP.

AOP enables a clean and simple solution for Tangling and Scattering problem. Assuming you have developed one aspect using Spring AOP, I will explain how to make your aspects look cleanly.

I suppose that a typical Aspect is written like (SpringSource example):


@Aspect
public class BeforeExample {

  @Before("execution(* com.xyz.myapp.dao.*.*(..))")
  public void doAccessCheck() {
    // ...
  }

}


First of all, a naming problem is encountered. We are mixing the pointcut with the advice. Moreover when you are reading this aspect, if you have not written the pointcut expression, you have the problem of interpreting the pointcut, for knowing which classes/methods does apply the doAccessCheck logic.
How about creating a method with an expressive name, that allows us to know when doAccessCheck() happens?


@Aspect
public class BeforeExample {
  @Before("daoMethods()")
  public void doAccessCheck() {
    // ...
  }
  @Pointcut("execution(* com.xyz.myapp.dao.*.*(..))")
  public void daoMethods(){} //Empty Method
}

Read now when is executed doAccessCheck() .

"Before [@Before] dao methods ["daoMethods()"]  do access check [doAccessCheck()]"

Yes! now this aspect is readable and understandable. Also without knowing AOP language, you can understand what this code does.

Moreover of using Named Pointcuts, some Best Practices should be followed:


  • Use the simplest possible advice. Avoid using @Around.
  • Use strongly-typed context when possible. Avoid getting data from join point object.

@Pointcut("execution(void com.xyz.myapp.Server+.start(java.util.Map)) && args(input)")
public void serverStartMethod(Map input){}

@Before("serverStartMethod(input)")
public void logServerStartup(Map input) {
...
}


  •  Create complex pointcut expressions from simple ones.



@Pointcut("execution(public * *(..))")
public void anyPublicOperation(){}

@Pointcut("within(com.xyz.someapp.trading..*)")
public void inTrading() {}

@Pointcut("anyPublicOperation() && inTrading()")
public void tradingOperation() {}

  • Use scoping designators (within, withincode) for fast matching. Avoid using kinded designators (execution)  or contextual designators (this, target) alone.

Now you can write your Spring AOP Advices cleanly and for optimal performance.

miércoles, enero 05, 2011

Deep Inside, You Cry Cry Cry, Don’t Let Your Hopes, Die Die Die

JPA2 is present in major ORM vendors (EclipseLink, Hibernate, OpenJPA). Main features are present like multiple levels of embedded objects, ordered lists, support for validation, new criteria query API.

Now it time to talk (with an example) about new criteria query API. For this example I will use Hibernate and its Hibernate Metamodel Generator.

New Criteria API allows criteria queries to be constructed in a strongly-typed manner, using metamodel objects to provide type safety. As is mentioned in Hibernate site: "For developers it is important that the task of the metamodel generation can be automated".

And that's is what Hibernate Metamodel Generator does. This metamodel generator is an annotation processor that is run each time an annotated @Entity bean is compiled, and generates its metamodel class.

Let's see an example:

A class like:

@Entity
public class Pizza {

@Id
@GeneratedValue
private Integer id;
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}


@Column
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@OneToMany(cascade= CascadeType.PERSIST, mappedBy="pizza")
private Set ingredients = new HashSet();
public Set getIngredients() {return ingredients;}
public void setIngredients(Set ingredients) {this.ingredients = ingredients;}

//Constructor, Transient Methods, ...
}

generated metamodel will look:

@StaticMetamodel(Pizza.class)
public abstract class Pizza_ {

public static volatile SetAttribute ingredients;
public static volatile SingularAttribute id;
public static volatile SingularAttribute name;


Easy to understand, each persistent attribute has its type and which entity belongs. For example field "name" belongs to Pizza and is a "String", and thats so important because precisely that will allow Criteria API to be typesafely.

Ok, now we know that new Criteria API is typesafely and this is acquired with metamodel programming. How about starting from the start?

First of all is configuring Eclipse for compiling using Annotation Processor (in Hibernate site is explained for using in other IDEs or Maven).


Only configure annotations processor output directory and which annotation processor is required, in our case hibernate-jpamodelgen and hibernate-jpa-2.0.

Next step is create our entity class:

@Entity
public class Pizza {

@Id
@GeneratedValue
private Integer id;

public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}

@Column
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@OneToMany(cascade= CascadeType.PERSIST, mappedBy="pizza")
private Set ingredients = new HashSet();
public Set getIngredients() {return ingredients;}
public void setIngredients(Set ingredients) {this.ingredients = ingredients;}

public Pizza(String name) {
super();
this.name = name;
}

protected Pizza() {
}
}

Nothing different here. Same is applied for Ingredient entity (not showed here).

But wait go to target/metamodel, refresh the directory and what you see there? The metamodel classes. Ok if you have arrived successful here, then no problem you have done the complicated thing. Now let's write our first new Criteria query.



CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery pizzaQuery = criteriaBuilder.createQuery(Pizza.class);
SetJoin ingredientsNode = pizzaQuery.from(Pizza.class).join(Pizza_.ingredients);
pizzaQuery.distinct(true).where(criteriaBuilder.equal(ingredientsNode.get(Ingredient_.name), ingredient));
TypedQuery typedQuery = this.entityManager.createQuery(pizzaQuery);
return typedQuery.getResultList();


This method returns all pizzas that are produced with given ingredient. If you analyze line per line, first of all is created the query about pizza, then is created the join relationship ingredientsNode and "woop" metamodel class starts the game, we are making a join with Pizza_.ingredients, this is the representation of ingredients class. Also we are telling to filter ingredients where the name is the given one criteriaBuilder.equal(ingredientsNode.get(Ingredient_.name), ingredient), and you see that Ingredient_.name is used. This information is crucial because we are telling to Criteria API that the field is the one defined as Ingredient.name. If name attribute is deleted, metamodel class is modified too and our code does not compile.

Take a look the same criteria query but in Hibernate Criteria:


Criteria criteria = session.createCriteria(Pizza.class);
criteria.createAlias("ingredients", "i")
.add(Restrictions.eqProperty("id", "i.pizza"))
.add(Restrictions.eq("i.name", ingredient));
return (List)criteria.list();

For me it is easy to understand first one than second one, it is like more natural, and does not required any cast.

In Hibernate site more examples of new Criteria API can be found. I encourage you to start using JPA2, not only for new Criteria API but for using all new features.