Conversational Scope on JSF 2.0 (without Custom Scope)

December 29th, 2009 by Eduardo Costa

JSF 2.0 is finally out. One thing that you will notice is the absence of a “conversational” scope. That would solve a lot of problems I have, but, unfortunately, I must wait for the next release. Or not?

There’s no silver bullet to solve it, but I found a simple workaround using “view” scoped beans. Works for most cases - unless you need redirection or other advanced requirements.

First, your “conversational” managed bean must be have a “view” scope:

@ManagedBean(name="tbean")
@ViewScoped
public class TBean {
  private String name;
  private String result;

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getResult() {
    return result;
  }
  public String sayHi() {
    result = "Hi, " + name;
    return "";
  }
}

No big deal: just a POJO with @ViewScoped. The catch is you must return empty on your action. The view is simple, too:

<h:body>
  <h:form rendered="#{empty tbean.result}">
    Name: <h:inputText value="#{tbean.name}"/>
    <h:commandButton value="hi!"
        action="#{tbean.sayHi}"/>
  </h:form>
  <h:panelGroup rendered="#{not empty tbean.result}">
    <h1><h:outputText value="#{tbean.result}"/></h1>
    <h:button value="back" outcome="index"/>
  </h:panelGroup>
</h:body>

Nothing really new: classic JSF 1.0 magic tricks with the rendered attribute. The real catch, although, is the view scope. The bean will remain as long as you keep the current view (by returning empty on your actions). The “back” button clears the form and conditionally rendered components will give the feel of different pages.

This means you can easily have an three-page CRUD (list, view, edit), or an wizard-style page, that will reset when you enter it and keep state as long as you stay on “subpages”.

Your page will grow fast using this method, but, since Facelets support is now native, you can use <ui:include> to keep this solution modular.

File attributes on layer.xml

December 15th, 2009 by Eduardo Costa

When registering files on NBM’s layer file, you can define attributes, too:

<file name="my-pkg-MyClass.instance">
  <attr name="mystr" stringvalue="value"/>
  <attr name="myint" intvalue="1"/>
  <attr name="mymethod"
    methodvalue="my.pkg.MyClass.myMethod"/>
</file>

They are avaliable as attributes of FileObject (through getAttribute). You can also use special attributes “instanceClass” to define a different class to instantiate or “instanceCreate” to define a factory method. This factory method can receive a map of attributes. I’m using it to customize a generic DataLoader:

public class MyLoader extends MultiDataLoader {
  private MyDataLoader(String secondaryExt) {
    super("MyObject");
    this.secondaryExt = secondaryExt;
  }
  public static build(Map<String, Object> attrs) {
    return new MyLoader(attrs.get("ext").toString());
  }
  ...
}

Customizing LiftWeb’s error/warning/notice messages

November 12th, 2009 by Eduardo Costa

After some CRUD experiments with LiftWeb, I’m really in love with the “view first” paradigm. Specially because the XHTML bindings are very webdesigner-friendly.

One big limitation is the <lift:msgs> snippet - it produces a mandatory “Error” title. This obligatory text is unacceptable when developing enterprise applications. Hopefully, there’s an workaround: you can create a snippet named “Msgs” with a “render” method. Your snippet will “override” the builtin (without overriding the class), like this:

package mypkg.snippets
class Msgs {
  def msgs(cls : String, ms : List[NodeSeq]) = ms match {
    case Nil => Nil
    case x => <div class={ cls }>{ ms.flatMap(m => <p>{ m }</p>) }</ul>
  }
  def render(xml : NodeSeq) : NodeSeq =
    <div id={ LiftRules.noticesContainerId }>
      { msgs("msgError", noIdMessages(errors)) }
      { msgs("msgWarning", noIdMessages(warnings)) }
      { msgs("msgNotice", noIdMessages(notices)) }
    </div>
}

This little snippet will emit messages using <div> and <p> instead of <ul> and <li> (with that hardcoded title block). And, since you have the control over the snippet, you can put stub code inside <lift:msgs/> and allow your webdesigner use their favorite WYSIWYG editor:

<lift:msgs>
  <div class="msgError">
    <p>name must have 3 charactes</p>
  </div>
</lift:msgs>

Booleans in JPA (the portable way)

October 21st, 2009 by Eduardo Costa

If you want to map a boolean value in JPA, you will have a headache if your RDBMS is Oracle. Since it does not support a boolean data type, you usually create a CHAR(1) ‘Y’/'N’ field and use a lot of bad words to describe the feeling you have when you find out that JPA does not support boolean-to-char convertion.

A nice and portable workaround is described here. The trick is to remember why getter/setter encapsulation is a good pratice - you can do a lot more than just plain old get/set:

private char enabled;

public boolean isEnabled() {
  return enabled == 'Y';
}
public void setEnabled(Boolean enabled) {
  this.enabled = (enabled ? 'Y' : 'N');
}

Copying html attributes on Lift bindings

September 18th, 2009 by Eduardo Costa

Since Java and Scala are complementary, I will post Scala-related stuff here, too (without creating a new blog).

Today’s tip refers to Lift (Scala’s JavaEE/Rails/Grails/Django). Suppose your webdesigner gives you this XHTML:

<input type="text" class="x" style="width: 100px;"/>

When you bind this using Lift, one of possible solutions is surround it with a tag:

<mybind:myfield><input type="text" class="x" style="width: 100px;"/></mybind:myfield>

Please notice I put it without spaces or newlines between “mybind:myfield” and “input” - this will be important later.

I prefer this way because this XHTML can be opened in other applications, like Firefox and Dreamweaver, making life easier for the webdesigner.

Then, if I bind it using old mama’s recipe:

bind("mybind", form, "myfield" -> myfield.toForm)

Lift will remove my “input” tag and replace it - destroying “class” and “style”. To solve this, I merge “toForm” tag with original attributes:

def merge(form : => Box[NodeSeq])(input : NodeSeq) : NodeSeq = {
  var in = input.first
  var attrs = form.open_!.first.attributes

  new Elem(in.prefix, in.label,
      in.attributes append attrs,
      in.scope, Group(in.child))
}
bind("mybind", form,
    FuncBindParam("myfield", merge(myfield.toForm)))

Function “merge” takes the form and returns a function that receives the original XHTML and translates it into XHTML with Lift’s attributes (”id”, “name”, “lift:gc”, etc). I guess I can improve it somehow, but works great. And, since I’m keeping only the first child of source XHTML, you need to keep “bind” and “input” together (as I said before).

I know I can use a map function to ignore whitespaces, but I’ll leave it as an later exercise (for you and for me, too).

Mandelbrot with Scala and Java

September 16th, 2009 by Eduardo Costa

I’m testing if Scala can be used to increase productivity here. Pretty nice language: as powerful as Ruby and JVM-compatible. To improve my skills, I decided to implement Mandelbrot on Scala, using Swing’s BufferedImage to show the image. Very simple, indeed. The code is:

import java.awt.image.BufferedImage
import javax.swing.ImageIcon
import javax.swing.JFrame
import javax.swing.JLabel
object Mandelbrot extends Application {
  case class Complex(r : Double, i : Double) {
    def +(b : Complex) = Complex(r + b.r, i + b.i)
    def *(b : Complex) = Complex(r * b.r - i * b.i, r * b.i + i * b.r)
    def insideM = (r * r + i * i) < (2 * 2)
  }

  implicit def start = Complex(0, 0)

  def pc(z : Complex, c : Complex) : Complex = z * z + c

  def iter(qtd : Int, c : Complex)(implicit z : Complex) : Int = {
    if (qtd == 0) 0
    else if (!z.insideM) qtd
    else iter(qtd - 1, c)(pc(z, c))
  }

  val scale = 1.0
  def pixToComplex(x : Double, y : Double) =
    Complex(((x / 640.0) * 3.0 - 2.0) / scale,
        ((y / 480.0) * 2.0 - 1.0) / scale)

  def raster(f : (Int, Int, Int) => Unit) = {
    for (y <- 0 until 480; x <- 0 until 640) {
      f(x, y, iter(1024, pixToComplex(x, y)))
    }
  }

  def qtdToColor(c : Int) = List(c / 4, c / 4, c / 4).toArray

  val frame = new JFrame("Mandelbrot")
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

  val lbl = new JLabel
  frame.add(lbl)
  frame.setSize(640, 480)
  frame.setVisible(true)

  val img = new BufferedImage(640, 480, BufferedImage.TYPE_3BYTE_BGR)
  raster((x, y, c) => img.getRaster.setPixel(x, y, qtdToColor(c)))
  lbl.setIcon(new ImageIcon(img))
}

Since I’m new to Scala, I guess it’s not the best solution. Nevertheless, I have an “Yes-we-can” feeling, because this code have some Scala features, like higher-order functions and (possibly) tail recursion. And, of course, I felt productive implementing Mandelbrot’s recursive algorithm (I got a lot of errors misunderstanding the algorithm, BTW).

That’s extreme!

September 16th, 2009 by Eduardo Costa

And, talking about being extreme, I found a mix of bytecode programming with ASCII art

Using JBoss as a remote datasource provider

July 20th, 2009 by Eduardo Costa

After some trial-and-error, I managed to use a JBoss 5 as a JNDI server and a Tomcat as a JNDI client. If you plan to make a JBoss DataSource public, just add a “<use-java-context>false</use-java-context>” to your “<local-tx-datasource>”.

Tomcat is easy to configure. You need to add a resource like this one (”look mom! no password!”):

<Resource name="jdbc/myds"
    auth="Container"
    type="javax.sql.DataSource"
    factory="org.jnp.interfaces.NamingContextFactory"
    URL="jnp://jboss-host:1099/jdbc/mydsOnJboss" />

The “jdbc/mydsOnJBoss” part is the same as the “<jndi-name>” on JBoss datasource. The real trick is the classpath. Go to JBOSS_HOME/client and copy these files:

  • jboss-logging-jdk (or jboss-logging-log4j)
  • jboss-logging-spi
  • jnp-client
  • jboss-client
  • jboss-common-core
  • jboss-integration
  • jboss-remoting
  • jboss-security-spi
  • jboss-serialization
  • jbosscx-client
  • jboss-javaee (optional if your Tomcat has the javax.transation.* already)

The first three (jnp-client, jboss-logging-*) are obvious, since they are explicit dependencies (i.e. you receive a “ClassNotFoundException”). The others are implicit - you don’t receive a CNFE, you get a “ClassCastException” (cannot cast javax.naming.Reference to javax.sql.Datasource). It is evil - no docs, no log, only “-verbose:class” helped me.

With the right libs and the right configuration, you can use @Resource (or Spring’s JNDI lookup) the same way as a locally defined datasource - without any sensitive information exposed.

As a final note, you don’t need the JDBC driver on client.

NetBeans 6.7

June 30th, 2009 by Eduardo Costa

Two days ago, NetBeans 6.7 was released. These are the new features I tested:

  • Maven integration was improved with autocomplete and dependency graph;
  • Profiler’s HeapWalker supports OQL - very useful if you do memory tunning;
  • Hudson server management and a status bar icon with build status.

See more at release page!

Using Spring with Mojarra InjectionProvider

May 22nd, 2009 by Eduardo Costa

Are you using SpringBeanFacesELResolver to handle dependency injection on managed beans? It works nice, but your faces-config grows fast with this approach.

Two months ago, I posted about using Spring injection outside application context. I forgot to mention that the same trick can be used to replace ELResolver solution if you are using Mojarra as your JSF provider.

You only need to add a servlet context parameter:

<context-param>
  <param-name>
    com.sun.faces.injectionProvider
  </param-name>
  <param-value>
    mypkg.SpringJSFInjectionProvider
  </param-value>
</context-param>

And the implementation of SpringJSFInjectionProvider is as simple as:

public class SpringJSFInjectionProvider
       implements InjectionProvider {
  private WebContainerInjectionProvider wcip =
      new WebContainerInjectionProvider();

  @Override
  public void inject(Object bean)
         throws InjectionProviderException {
    FacesContextUtils
      .getWebApplicationContext(
         FacesContext.getCurrentInstance())
      .getAutowireCapableBeanFactory()
      .autowireBeanProperties(bean,
         AutowireCapableBeanFactory.AUTOWIRE_NO,
         false);
    wcip.inject(bean);
  }
  @Override
  public void invokePreDestroy(Object bean)
         throws InjectionProviderException {
    wcip.invokePreDestroy(bean);
  }
  @Override
  public void invokePostConstruct(Object bean)
         throws InjectionProviderException {
    wcip.invokePostConstruct(bean);
  }
}

Adding this, you can shrink your faces-context, removing all “managed-property” tags. Your managed beans can look more JavaEE 5 after you change this:

private BO bo;

public void setBo(BO bo) {
  this.bo = bo;
}

To this:

@Resource(name="bean-on-appctx")
private BO bo;

No setter, no ELResolver. This means less code to maintain! If you plan to migrate from Spring to EJB, this means you will only need to promote the BO to an stateless bean and change @Resource to @EJB!