Saturday, August 22, 2009

Constructor annotation in Scala 2.8.0

It was really hard for me to find any information concerning annotations on default constractor. Finally I discovered that scala accepts the following syntax:
class MyClass @Annotation() (val arg : Int) {
}

It is important that an annotation is followed by (), otherwise parameters of MyClass are parsed as parameters of annotation...

Tuesday, August 18, 2009

Richfaces & JSF 1.2

The problem with Richfaces 3.3.1 and Sun JSF RI is that an exception thrown in action listener is suppressed by Richfaces. I will show why this happens. The following stacktrace shows an order of invocations that takes place when an action listener is called:

((1)) at blah.blah.blah.ActionListenerTest.test(ActionListenerTest.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.el.parser.AstValue.invoke(AstValue.java:170)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
((2)) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:99)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:771)
at javax.faces.component.UICommand.broadcast(UICommand.java:372)
at javax.faces.component.UIData.broadcast(UIData.java:938)
((3)) at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)

I've marked interesting places with ((1)), ((2)) and ((3)). The first interesting method is ((1)) - that is where we throw an unchecked exception. The exception will be catched somewhere between ((1)) and ((2)) and wrapped into the ELException class. Then this exception will be caught in ((2)) as it can be seen here (sources are taken from Sun JSF RI 1.2.12):

public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
if (actionEvent == null) {
throw new NullPointerException();
}

try {
FacesContext context = FacesContext.getCurrentInstance();
ELContext elContext = context.getELContext();
methodExpression.invoke(elContext, new Object[] {actionEvent});
} catch (ELException ee) {
Throwable eeCause = ee.getCause();
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE,
"severe.event.exception_invoking_processaction"
new Object[]{
eeCause == null ? ee.getClass().getName() : eeCause.getClass().getName(),
methodExpression.getExpressionString(),
actionEvent.getComponent().getId()
});
StringWriter writer = new StringWriter(1024);
if (eeCause == null) {
ee.printStackTrace(new PrintWriter(writer));
} else {
eeCause.printStackTrace(new PrintWriter(writer));
}
LOGGER.severe(writer.toString());
}

throw eeCause == null ? new AbortProcessingException(ee.getMessage(), ee) : new AbortProcessingException(ee.getMessage(), eeCause);
}
}
When the processActio methods catches exception it logs it and wraps exception cause into the AbortProcessingException. Here we come to place ((3)) which catches AbortProcessingException. The following is the source code from RichFaces 3.3.1.GA:

public void processEvents(FacesContext context,
EventsQueue phaseEventsQueue, boolean havePhaseEvents) {
FacesEvent event;
while (havePhaseEvents) {
try {
event = (FacesEvent) phaseEventsQueue.remove();
UIComponent source = event.getComponent();
try {
source.broadcast(event);
} catch (AbortProcessingException e) {
if (_log.isErrorEnabled()) {
UIComponent component = event.getComponent();
String id = null != component ? component
.getClientId(context) : "";
_log.error(
"Error processing faces event for the component "
+ id, e);
}
}
} catch (NoSuchElementException e) {
havePhaseEvents = false;
}
}
}
As you can see processEvents catches AbortProcessingException, logs it and does nothing! That is it!

I've tried a lot of solutions to solve this, I've tried to solve it with servlets/filters/phase-listeners/action-listeners and so on with no luck! Then I've solved it with last resort - AspectJ. The following aspect does the job perfectly:

@Aspect
public class RichfacesErrorIntercepterAspect {
@Around("call(* javax.faces.component.UIComponent.broadcast(..)) && within (org.ajax4jsf.component.AjaxViewRoot)")

public void callToBroadcast (final ProceedingJoinPoint thisJoinPoint) throws Throwable
{
try {
thisJoinPoint.proceed ();
} catch (final AbortProcessingException e) {
throw new RuntimeException ("Exception in action listener: " + e.getMessage (), e.getCause ());
}
}
}
To weave Richfaces's jar I've used the maven (I use it to build the project anyway):

<plugin>
<groupId>org.codehaus.mojo</groupId>

<artifactId>aspectj-maven-plugin</artifactId>

<configuration>
<complianceLevel>1.5</complianceLevel>
<weaveDependencies>
<weaveDependency>
<groupId>org.richfaces.framework</groupId>
<artifactId>richfaces-impl</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>

<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

Sunday, August 2, 2009

Richfaces or Trinidad with Facelets

I upgraded existing project from Java 1.4 to Java 1.5, JSF 1.1 to JSF 1.2, myfaces to sun ri... and decided to leverage a framework providing AJAX for JSF. The first I tried was richfaces. But it worked unstable and I spent 2 days trying to find a reason for it. Then I tried to use trinidad. It was the same. The framework worked but very unstable. For example. I opened a jsf page, if I clicked on a ajaxfied button just immediately after page appeared, then button worked OK. But if I clicked on the button after a while, then the button didn't work, the relevant page part was not updated! It looked like a magick in work. Then I noticed a very strange message which I noticed long time ago but didn't pay any attention to it. The message was "INFO: Facelet[/page/blah.xhtml] was modified @ 14:23:24 AM, flushing component applied...". A quick investigation revealed a root of my problem! It turned out that time in a virtual machine I used as a place for application server was 3 hours less then current time! And so file creation time of files in WAR-file was greater than time in the virtual machine. It looked like facelets framework had some strange algorithm based on current time to reload modified files (and flush components tree). Having set facelets.REFRESH_PERIOD context parameter in web.xml I solved the problem. Both richfaces and trinidad worked fine after that.