Saturday, February 20, 2010

Subclipse Commit Hangs, Cannot Cancel, Blocks Save

Consider this scenario: You're committing a changeset to your Subversion repository with Subclipse in Eclipse IDE.

The Subversion commit takes a long time, probably due to flaky network connection (which happens often). In the meantime, you continue working and make changes. Somehow, the commit never finished, so you cancel. Alas, Subclipse cannot immediately cancel, it can only give you "Cancel Requested".

Subclipse apparently provides no clean way of stopping an SVN commit operation and restarting the commit in the case of network problems. Even worse, all your work in progress cannot be saved, since Subclipse is blocking it:



The window above has been showing in my screen for about 10 minutes now, and it will never go away anyway... until I quit Eclipse or (if I can't do that) kill Eclipse process by force.

I can't even save my files! It's very frustrating. Even if Subclipse cannot cancel SVN commit cleanly, it should allow me to at least save my files so I can restart Eclipse and try again!

Update: Submitted bug to Subclipse issue tracker

Friday, February 19, 2010

NullPointerException on JSP page on JSF+PrimeFaces

My first experience with JSF is with JSF 2.0 + PrimeFaces 2.0 and PDL/Facelets. ;-) When I went back to JSF 1.2 + PrimeFaces 1.0 using JSP templates I get this error.

java.lang.NullPointerException
at org.primefaces.component.resources.ResourcesTag.setProperties(ResourcesTag.java:37)
at javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:614)
at javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:1142)
at org.apache.jsp.RequiredSecurityInfo_jsp._jspx_meth_p_005fresources_005f0(RequiredSecurityInfo_jsp.java:274)

I wish the errors would be more helpful.

Solution:

When using JSP view technology, JSF tags including p:resources should be wrapped inside f:view.

Source: Problem with <p:resources/>

Wednesday, February 17, 2010

java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException

If you get this error:
java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException
The solution is:
Add the AspectJ library to the classpath.

If it's a web application, that means either:
  • Add the AspectJ Runtime (aspectjrt.jar) to WEB-INF/lib, or
  • In Eclipse, enable AspectJ on your project. Then open Project Properties, add the AspectJ Runtime library to Java EE Dependencies.

JSF 1.2 + JSP and Facelets error - java.lang.RuntimeException: Cannot find FacesContext

I've just finished installing Facelets on my JSF 1.2 tutorial when I got this error message:
HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

org.apache.jasper.JasperException: An exception occurred processing JSP page /index.jsp at line 13

10: <%@page import="java.util.List"%>
11: <%@page import="identity.Identifiable"%>
12: <%@page import="name.Nameable"%>
13: <f:view>
14: <html>
15: <head>
16: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">


Stacktrace:
 org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:505)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:416)
 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

java.lang.RuntimeException: Cannot find FacesContext
 javax.faces.webapp.UIComponentClassicTagBase.getFacesContext(UIComponentClassicTagBase.java:1855)
 javax.faces.webapp.UIComponentClassicTagBase.setJspId(UIComponentClassicTagBase.java:1672)
 org.apache.jsp.index_jsp._jspService(index_jsp.java:93)
 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
 javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.
Apache Tomcat/6.0.20
This happens because:
  • I've added Facelets to the web project
  • I have set up the JSF default suffix to *.xhtml and JSF view technology to Facelets
  • I have a JSF+JSP page
This exact question on java.net Forums : Is that possible/good to mix the ... leads to this FAQ on How do I use Facelets and JSP in the same application?:
You have to use prefix mapping for the Facelets pages in order for this to work. Leave the DEFAULT_SUFFIX with the JSF default of .jsp. Configure the Facelet's VIEW_MAPPINGS parameter:
<web-app>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.jsp</param-value>
  </context-param>

  <!-- Facelets pages will use the .xhtml extension -->
  <context-param>
    <param-name>facelets.VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param>     

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  </servlet>
 
  <!-- Use prefix mapping for Facelets pages, e.g. http://localhost:8080/webapp/faces/mypage.xhtml -->
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
</web-app>
The best way is, of course... to get rid of JSP pages and use Facelets exclusively. :-)

But at least now you know you have a choice. :-)

If you're still using JSF 1.2 I heavily recommend you to upgrade to JSF 2.0 as soon as possible. Check out the book JavaServer Faces 2.0, The Complete Reference which is a great resource on using JSF 2.0.

JSF 1.2 + PrimeFaces Web Application Tutorial using Eclipse IDE

Setting up a full stack web application with JSF 1.2 Java web framework takes some work. Here I will show you the "mostly manual" way aka non-Ruby on Rails-style.

The project will:
  • Use Eclipse Java EE (aka JDT + WTP)
  • Not use Maven
  • Deployed on Tomcat
  • Use PrimeFaces JSF component library
Why?
I know you're smart enough that this is the hard way. Considering there is AppFuse, Maven archetypes, and SpringSource Tool Suite projects templates to help you start a Java web project the Ruby on Rails way. The reason is because:
  • Educational purposes
  • Make it easy to depend on non-Maven libraries or our own Eclipse projects
Steps
  1. Create new Dynamic Web project in eclipse, select JSF 1.2.
  2. Download JSF-RI (Mojarra) 1.2 either manually or automatically
  3. Make sure to export on Java EE dependencies to get libs on WEB-INF/lib (aka compile vs provided)
  4. Add el-impl dependency and export. This is needed for deploying to Tomcat, not needed for Glassfish other complete Java EE containers.
  5. Download PrimeFaces 1.x and export
  6. PrimeFaces Resources Servlet
  7. PrimeFaces p:resources (JSF 1.x only)
  8. Put f:view on JSP pages (mandatory) -- see forum thread about NullPointerException on p:resources
  9. Beans -> faces-config.xml  . Eclipse IDE helps here, but now you know annotations are much nicer.
Setup Facelets

  1. Download Facelets as dependency and export to WEB-INF/lib
  2. Configure WEB-INF/web.xml

     <!-- Use Documents Saved as *.xhtml -->
     <context-param>
      <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
      <param-value>.xhtml</param-value>
     </context-param>
     <!-- Special Debug Output for Development -->
     <context-param>
      <param-name>facelets.DEVELOPMENT</param-name>
      <param-value>true</param-value>
     </context-param>
     <!-- Optional JSF-RI Parameters to Help Debug -->
     <context-param>
      <param-name>com.sun.faces.validateXml</param-name>
      <param-value>true</param-value>
     </context-param>
     <context-param>
      <param-name>com.sun.faces.verifyObjects</param-name>
      <param-value>true</param-value>
     </context-param>
  3. Configure WEB-INF/faces-config.xml

     <application>
      <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
     </application>
  4. Install JBoss Tools for Facelets editor code completion and other JSF helpers. 
  5. IF you opt for not installing JBoss Tools in the previous step:
    - Configure *.xhtml to be opened with JSP Editor. Open Eclipse Preferences,  go to Window > Preferences > General > Content Types:  Text > JSP > Add (xhtml).
    - Configure Eclipse File Type associations to open *.xhtml as JSP Editor by default, not the Doxia Xhtml editor (which is very slow and not helpful).
  6. Create a sample page.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:ui="http://java.sun.com/jsf/facelets">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Facelets: Number Guess Tutorial</title>
    <style type="text/css">
    <!--
    body {
      font-family: Verdana, Arial, Helvetica, sans-serif;
      font-size: small;
    }
    -->
    </style>
    </head>
    
    <body>
    <h1> <ui:insert name="title">Default Title</ui:insert> </h1>
    <p> <ui:insert name="body">Default Body</ui:insert> </p>
    </body>
    
    </html>
  7. Redeploy the web app!

To Do
  1. Add Facelets
  2. Add Spring
  3. Add JPA
  4. Add Spring Transactions
  5. Add Spring Security
  6. Unit Testing

Tuesday, February 16, 2010

Four Approaches of Mixins in Java with AspectJ

Aspect Oriented Programming (AOP) is used to introduce cross-cutting concerns in several OO classes at once, for example mixins. In Java, AspectJ is the most popular tool for doing aspect oriented programming and domain-driven development.

If you're not familiar with AOP or AspectJ, the book Aspectj in Action: Enterprise AOP with Spring Applications is an excellent resource for learning AOP.

One use case of AOP is for implementing mixins or traits. Its purpose is to introduce members aka methods, properties, and fields to an existing class, and also implement interfaces. This is called static structure weaving.

There are four approaches to do static structure weaving.

Here I list them all with their benefits and weaknesses, and conclusion of when you should use it:

1. non-AOP: proxy to interface Impl

+ weaved API completion is available from consumer object
+ no need for external tool (AspectJ) nor any IDE and build configuration/plugin
+ mixin Impl can be reused like approach #3 and #4 below
- needs @Embedded for JPA
- overriden aspect methods do not take effect inside aspect methods (must take the aspect Impl as a whole)
- need to code proxy methods manually

Conclusion: just say good bye to this programming model from hell. Thank me later.

Example:
public class Note implements Nameable {

 @Embedded
 private Nameable nameable = new NameableImpl();

 @Override
 @Transient
 public String getName() {
  return nameable.getName();
 }

 @Override
 public void setName(String name) {
  nameable.setName(name);
 }
 
 @Override
 public boolean hasName() {
  return nameable.hasName();
 }

} 

2. AspectJ-only

+ can override aspect methods at will
 + no need for @Embedded for JPA
 - require AspectJ IDE
+ weaved API completion is available from consumer object

Conclusion: bBest choice for developing aspects, need AspectJ IDE. Resulting classes can be used normally (even with non-AspectJ IDE), especially if you use build-time weaving.

Example class:

@NameableMixin
public class Ticket { }

Example aspect:
public aspect NameableAspect {

 declare parents : @NameableMixin * implements Nameable;
 declare parents : @NameableMixin * implements NameableSupport;

 public String NameableSupport.name;
 
 public String NameableSupport.getName() {
  return name;
 }
 
 public void NameableSupport.setName(String name) {
  this.name = name;
 }

 public boolean NameableSupport.hasName() {
  return getName() != null && !getName().isEmpty();
 }
}

3. @AspectJ annotations

+ can override aspect methods at will
 + no need for @Embedded for JPA
 + usable in any IDE
 - weaved API completion not available from consumer object

Conclusion: if you definitely can't use AspectJ IDE, start from this  so you can develop aspects fast. beware that usage from client objects is not so convenient.

Example class:

@NameableMixin2
public class Project { }
Example aspect using @AspectJ notation:
@Aspect
public class NameableAspect2 {

 @DeclareMixin("@NameableMixin2 *")
 public Nameable nameableMixin() {
  return new NameableImpl();
 }
 
}
Example mixin Impl:
@Embeddable
public class NameableImpl implements Nameable {

 private String name;
 
 @Override
 @Basic
 public String getName() {
  return name;
 }

 @Override
 public void setName(String name) {
  this.name = name;
 }

 @Override
 public boolean hasName() {
  return getName() != null && !getName().isEmpty();
 }

}
Using the aspected class with typecasting: (pretty bad huh?)

  Project project = new Project();
  Nameable named = (Nameable)project;
  named.setName("Get coffee");
  System.out.println(named.getName());

4. AspectJ + Impl hybrid

Hybrid here means using the exact semantics of a non-AOP approach (proxying). Implementation of the aspect is a combination of AspectJ syntax for the aspect "proxy", plus standard Java for actual mixin implementation.

In essence, this is a modified approach #3 that replaces the @AspectJ-annotation aspect, with AspectJ syntax aspect to introduce interface members that delegates all calls to a separate concrete implementation (in plain Java).

+ single Impl for both non-AOP (approach #1), @AspectJ (approach #3), and hybrid (this one)
+ weaved API completion is available from consumer object
+ Impl editable from any IDE. aspect code is simple thus AspectJ IDE not so required.
+ Impl can be marked as @Embeddable, but weaved class does not need to use @Embedded
- overriden aspect methods do not take effect inside aspect methods (must take the aspect Impl as a whole)
- code twice for each method: the Impl and the aspect proxy methods

Conclusion: if you don't have AspectJ IDE and you need to access the API easily. beware that aspect methods won't be overridable. you can also start from @AspectJ annotations first then switch to this when the aspect implementation is "stable". Don't start with this approach because you'll be burdened with synchronizing the AspectJ aspect with the mixin Impl.

If you want to learn more about AspectJ and AOP in general, the book Aspectj in Action: Enterprise AOP with Spring Applications by Ramnivas Laddad has the most comprehensive coverage on this subject.

Facelets tag library not loading?

I got a weird and frustrating problem today with JSF 2.0, Facelets (aka PDL), and Tomcat. I installed PrimeFaces to my web application, and it's not working at all.

"Not working" in the sense that there are no error messages, and my PrimeFaces tags are output verbatim. In a sense, PrimeFaces became 'unresolved namespace' in my web app.

I tried turning on Facelets logging but failed (I'm not so good with java.util.logging), maybe because PDL uses a different logging configuration than the "legacy" Facelets for JSF 1.2.

After hours of research, it turned out that the problem was simple: my primefaces-2.0.0.jar file is corrupt!

I used Maven to manage dependencies and I didn't realize that it did not download successfully (blame my flaky Internet connection.)

The real problem is that Tomcat did not give any indication whatsoever that one of my JARs is corrupt. Ridiculous!