Showing posts with label jsf. Show all posts
Showing posts with label jsf. Show all posts

Saturday, May 12, 2012

Java web development: back to basics

The first post that I wrote on this blog is titled AJAX: JQuery, Google Web Toolkit or RichFaces. There, I praise RichFaces for being built on top of JSF (Java Server Faces):

"If you haven't work with JSF, I really suggest you do as it is one of the most powerful, easy to learn Web technologies, very similar to swing with heavy use of components and events. It also has a really good support for managing the state in the server using plain Java objects (POJO’s)"

What has happened since? Well, after working with Wicket and Vaadin (which I still use in one of my open source projects), I have drifted away from component based web development.

The reason is simple. It doesn't have to do with performance, number of components or the size of the community. It's just that component based web frameworks couldn't keep the promise of isolating the programmer from client side development and the request/response nature of HTTP.

A leaky abstraction

Yes, I know. Every abstraction, to some degree, is leaky. However, the problem with this specific abstraction is that it leaks way too fast. You end up investing large amounts of time understanding how the framework works underneath and how to tweak it in order to achieve what you want. It's a real pain in the ass. The productivity that they promise in their "build an app in 10 minutes or less videos" is dead in the eleventh minute or so.

The other problem is that the technology underneath is moving too fast. HTML5 introduced a lot of new features such as web sockets, canvas and new data storage options. Web development is also moving towards stateless REST services and heavy clients. The future is not clear yet, though.

Back to basics

Lately, I have been working with Ruby on Rails and Express.js (Node.js). I think that their success lies in the fact that they embraced the request/response nature of HTTP. However, I don't buy the "Ruby made programming fun again" bullshit - a topic for another post -. I still like Java.

I also tried Play! Framework for a few weeks. It's an interesting option but I don't think that the solution is to copy exactly how Ruby on Rails works in Java/Scala. It's not really about productivity, it's about maintainability.

So, I'm actually using a super simple Java request/response based framework I made, HTML5, CSS3, Javascript and JQuery.


Friday, April 9, 2010

4 areas of possible confusion in JEE 6

The JEE specification is released and maintained through the Java Community Process, which defines the different API’s that will be included in each release, and how they relate to each other. Due to the technical and political factors involved in the process, besides the time constraint, is no surprise that some areas of the specification may be confusing to new developers, especially with the rising number of annotations introduced by each API.

In this post, I will try to explain four areas where developers might find themselves confused when working with JEE 6.

1. Managed Beans and EL access

The following two annotations from the JEE 6 API are both used to access a bean from the Expression Language (i.e. using the #{} notation):

  • @javax.faces.bean.ManagedBean – Defined in the JSF 2.0 Managed Bean Annotations specification (JSR-314), it provides an alternative to the declaration of managed beans in the faces-config.xml descriptor file.
  • @javax.inject.Named – Defined in the Dependency Injection (JSR-330) specification, is one of the built-in qualifier types of CDI (JSR-299) used to provide a name to a bean, making it accessible through EL.

So, which one to use? Always use the @Named annotation, unless you are working in a JSF 2.0 environment without CDI (a very unlikely scenario). There is just no reason to use JSF Managed Beans if CDI is present. You can check this article for more information.

Furthermore, there is another @ManagedBean annotation you might also get confused with:

  • @javax.annotation.ManagedBean – Defined by the Commons Annotations specification (JSR-250), it is used to declare a managed bean as specified in the Managed Beans specification (JSR-316).

Most likely, you will never need to use this annotation. Let’s look why.

First, don’t confuse Managed Beans with JSF Managed Beans, they are different things. The Managed Beans specification, a subset of the JSR-316, is an effort to provide services like dependency injection, lifecycle callbacks and interceptors to POJO’s (Plain Old Java Objects), which is really cool! So, why not to use it?

CDI treats all POJO’s as Managed Beans! There is no need to explicitly annotate the POJO with @javax.annotation.ManagedBean. Nothing stops you from doing it though.

2. Duplicated @…Scoped annotations

The following annotations are duplicated in the JEE 6 API:

  • @javax.faces.bean.RequestScoped and @javax.enterprise.context.RequestScoped.
  • @javax.faces.bean.SessionScoped and @javax.enterprise.context.SessionScoped.
  • @javax.faces.bean.ApplicationScoped and @javax.enterprise.context.ApplicationScoped.

The @javax.faces.bean… annotations are defined in the JSF Managed Beans specification (JSR-314) and the @javax.enterprise.context… annotations are defined in the CDI specification (JSR-299). 

So, which ones to use? Always use the CDI annotations, unless you are working in a JSF 2.0 environment without CDI (a very unlikely scenario). As discussed above, there is no reason to use JSF Managed Beans if CDI is present.

One scope that is missing in CDI is the @ViewScoped of JSF. However, the problem is solved by creating a portable extension which will be included in the Seam 3 Faces Module.

3. Defining a Singleton

There are four annotations that provide very similar functionality:

  • @javax.ejb.Singleton – A new type of EJB from the JSR-318 specification, it is used to maintain a single shared instance; it’s thread safe and transactional.
  • @javax.inject.Singleton – From the Dependency Injection specification (JSR-330), marks a type the injector will only instantiate once.
  • @javax.enterprise.inject.ApplicationScoped – One of the built-in scopes from the Contexts and Dependency Injection specification (JSR-299), specifies that a bean is application scoped.
  • @javax.faces.bean.ApplicationScoped – Defined in the JSF 2.0 (JSR-314) Managed Beans specification, specifies that a JSF managed bean is application scoped.

They all guarantee a single instance of the class. But, which one to use?

We have already discussed the duplicated @ApplicationScoped annotations above, so we will just dismiss @javax.faces.bean.ApplicationScoped to move on. That leaves us with just 3 options.

@javax.ejb.Singleton is the only one that will give you out-of-the-box “enterprise” services such as concurrency and transaction management. So, if you need these features, this is the annotation to use. You can optionally add the @javax.enterprise.inject.ApplicationScoped annotation but you will not feel the difference, although, CDI will treat it differently. You can check this forum thread for more information.

Note: even though it is possible to use @javax.enterprise.inject.ApplicationScoped with a Stateful Session Bean, I can’t find any good reason to use it given that EJB 3.1 has introduced the Singleton Beans.

If you want to use POJO’s (called Managed Beans in the JEE world), instead of EJB’s, you can also annotate them with @javax.enterprise.inject.ApplicationScoped to guarantee that the class is instantiated only once. Be aware that you will lose all of the services provided by EJB’s such as concurrency and transaction management.

I would not suggest using @javax.inject.Singleton unless you are working in a JS2E environment without CDI support. You can check the Weld documentation and this forum thread for more information about how this annotation is handled in CDI.

Note: none of the annotations discussed above will guarantee a shared single instance in a clustered environment. Usually, you will have one singleton instance per JVM.

4. @Inject or @EJB

They are both used for injection. @Inject is from the Dependency Injection specification (JSR-330) and @EJB from the EJB specification (JSR-318).

So, which one to use?

In most of the cases you will use @Inject over @EJB unless you are working on an environment with EJB’s but no CDI (very unlikely since JEE 6), or if you need to define an EJB resource. You can check the this forum thread for more information.

Conclusion

  1. If you need to access a bean through EL (i.e. from a JSF page), annotate the bean with @Named.
  2. Usually, you will never need none of the @ManagedBean annotations.
  3. Always use the @…Scoped annotations from the javax.enterprise.context package (CDI).
  4. To define a singleton, use the @ApplicationScoped annotation. If you need the EJB services such as concurrency and transaction, add the @javax.ejb.Singleton annotation.
  5. Always use @Inject instead of @EJB, unless you really have a motive to do so.

Sunday, November 22, 2009

Seam and JSF

In my last post, I talked about Seam contexts and how to use them from your application. Now, I’ll show you how you can access them from JSF, especially how to use the event context correctly. At the end, I’ll give you some tips you may find useful when developing the web tier of your application with Seam and JSF.

Accessing contexts from your JSF pages

In Seam, you can access anything saved in the contexts from a JSF page using the #{} notation. For example, consider the following line of code:

<h:outputText value="#{employee.name}" />

This will search all the stateful contexts for the “employee” key using the Contexts.lookupInStatefulContexts() method as I showed you in my last post. Remember that the context search priority is: event, page, conversation, session, business process and application. If the key is not found in any of the contexts, it will return null. Otherwise, it will try to call the getName() method on the object.

JSF and the event context

The event context is the narrowest of the stateful contexts; it only lasts during a single http request. It is very useful when working with data iteration because Seam binds the iterated variable into the event context. Consider the following code fragment:

<rich:dataTable value="#{employees}" var="employee">
 <rich:column>
  <h:outputText value="#{employee.name}" />
 </rich:column>
 <rich:column>
  <h:outputText value="#{employeeSalaryResolver.netSalary}" />
 </rich:column>
</rich:dataTable>

In line 6 we are calling another component called employeeSalaryResolver to retrieve the net salary of the employee. Seam binds the actual employee object into the event context, so, we can just inject it in the EmployeeSalaryResolver component:

@Name("employeeSalaryResolver")
public class EmployeeSalaryResolver {
 
 @In
 private Employee employee;

 public double getNetSalary() {
  double netSalary = employee.getBaseSalary();
  
  // do other complex calculations (extra hours, bonus, etc.)  
  
  return netSalary;
 }
}

The employee attribute is being injected from the iteration variable (the event context) and used to retrieve the net salary of the employee. This component can be then reused in other use cases.

You can also use the event context to pass information between pages. For example, imagine a component that searches for an employee using the social security number and shows the result in another page.

@Name("searchEmployee")
public class SearchEmployee {
 
 private String ssNumber;
 
 @Out(scope=ScopeType.EVENT,required=false)
 private Employee employee;

 public String search() {
  Employee employee = ...; // search for the employee
  if (employee != null) {
   return "success";
  }
  
  return null; 
 }
}

When the search method is called (from a page I’m not showing) and an employee is found, the searchEmployee component will outject the Employee object to the event context and render the result in another page. The navigation in pages.xml would be something like this:

<page view-id="searchEmployee.xhtml">
 <navigation>
  <rule if-outcome="success">
   <render view-id="searchResult.xhtml"/>
  </rule>
 </navigation>
</page>

If you notice, we are using render tag instead of redirect tag. This will forward the request to the searchResult.xhtml page instead of redirecting, so the event context will not be lost.

Seam and JBoss EL

Standard EL (the #{} notation you use in your JSF pages) does not allow you to call methods with predefined parameters. However, Seam overcomes this limitation by using JBoss EL, which is an extension of the standard EL. For example, in our employees application, suppose we have a list of employees and we want to add an option on each row to fire employees. So, we create a fireEmployee component with a fire method that receives an Employee as an argument.

@Name("fireEmployee")
public class FireEmployee {

 public void fireEmployee(Employee employee) {
  // fire employee
 }
}

Now, we just need to add the action to the employees' page.

<rich:dataTable value="#{employees}" var="employee">
 <rich:column>
  <h:outputText value="#{employee.name}" />
 </rich:column>
 <rich:column>
  <h:outputText value="#{employeeSalaryResolver.netSalary}" />
 </rich:column>
 <rich:column>
  <s:link value="Fire Employee" action="#{fireEmployee.fire(employee)}" />
 </rich:column>
</rich:dataTable>

Really cool feature! Look at the <s:link> tag. Seam introduces some JSF tags to ease development. I won’t describe them here, but if you want, you can check them here.

Tips using Seam and JSF

1. Backing beans

In Seam, you can use EJB’s as your backing beans. However, by default, use JavaBeans (POJO’s). The reason is that you usually bind the backing bean to the page scope, but, if you use EJB Session Beans, you will not be able to do this.

@Name("someBean")
@Scope(ScopeType.PAGE)
@Synchronized
public class SomeBean implements Serializable {

 private static final long serialVersionUID = -2524956479693778917L;

 // your code ...
}

You can also bind your backing beans to the conversation or session scopes when needed. The @Synchronized annotation tells Seam to serialize requests from the backing beans as concurrency may cause some problems occasionally, especially when you are using AJAX calls. A better approach, however, is to use the eventQueue attribute in your richfaces components. See this for more information.

2. Use a naming convention for your components

You have to choose carefully the name you assign to each of your components because as the application starts growing, you may repeat component names and having some conflicts. So, you can use the package as a prefix for the name of the component.

However, if the project is small, you also can use a simpler prefix if you want. For example, you can use the “controller” prefix for your backing beans, “logic” for your business components and “model” for your entities and DAO’s.

3. You can use more than one Backing Bean per page

A lot of people use one backing bean per page. However, I really discourage this at it does not promotes code reusing and increments coupling. For example, if you have something you show in every page, use a separate backing bean and bind it to the session scope instead of retrieving the same information in every page.

Conclusion

Seam allows you to access any component in any context from JSF, this gives you the opportunity to choose how you want to architect your solution with some cool features that help you speed development time.