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!

"Error: Could not open JPA EntityManager" problem on EclipseLink

When you use JPA and EclipseLink 2.0 and get this error:

HTTP Status 500 -


type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_setperson_vh] or [_persistence_getperson_vh] is not defined in the object [com.googlecode.pu1.domain.PersonDetail].
Internal Exception: java.lang.NoSuchMethodException: com.googlecode.pu1.domain.PersonDetail._persistence_getperson_vh()
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[person]
Descriptor: RelationalDescriptor(com.googlecode.pu1.domain.PersonDetail --> [DatabaseTable(PERSONDETAIL)])

Runtime Exceptions: 
---------------------------------------------------------

java.lang.NullPointerException

 javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
root cause
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_setperson_vh] or [_persistence_getperson_vh] is not defined in the object [com.googlecode.pu1.domain.PersonDetail].
Internal Exception: java.lang.NoSuchMethodException: com.googlecode.pu1.domain.PersonDetail._persistence_getperson_vh()
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[person]
Descriptor: RelationalDescriptor(com.googlecode.pu1.domain.PersonDetail --> [DatabaseTable(PERSONDETAIL)])

Runtime Exceptions: 
---------------------------------------------------------

java.lang.NullPointerException

 org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:382)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
 org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:336)
 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 $Proxy22.findAll(Unknown Source)
 com.googlecode.sandcode.helloworld.HelloWorld.getName(HelloWorld.java:29)
 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:597)
 javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
 javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
 com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
 com.sun.el.parser.AstValue.getValue(AstValue.java:116)
 com.sun.el.parser.AstValue.getValue(AstValue.java:163)
 com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
 com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
 javax.faces.component.UIOutput.getValue(UIOutput.java:168)
 com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:338)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
 javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
 javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
 javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
 com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
 com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
 com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
root cause
javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_setperson_vh] or [_persistence_getperson_vh] is not defined in the object [com.googlecode.pu1.domain.PersonDetail].
Internal Exception: java.lang.NoSuchMethodException: com.googlecode.pu1.domain.PersonDetail._persistence_getperson_vh()
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[person]
Descriptor: RelationalDescriptor(com.googlecode.pu1.domain.PersonDetail --> [DatabaseTable(PERSONDETAIL)])

Runtime Exceptions: 
---------------------------------------------------------

java.lang.NullPointerException

 org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:392)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
 org.springframework.orm.jpa.JpaTransactionManager.createEntityManagerForTransaction(JpaTransactionManager.java:400)
 org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:321)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
 org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:336)
 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 $Proxy22.findAll(Unknown Source)
 com.googlecode.sandcode.helloworld.HelloWorld.getName(HelloWorld.java:29)
 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:597)
 javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
 javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
 com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
 com.sun.el.parser.AstValue.getValue(AstValue.java:116)
 com.sun.el.parser.AstValue.getValue(AstValue.java:163)
 com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
 com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
 javax.faces.component.UIOutput.getValue(UIOutput.java:168)
 com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:338)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
 javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
 javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
 javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
 com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
 com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
 com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
root cause
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-60] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The method [_persistence_setperson_vh] or [_persistence_getperson_vh] is not defined in the object [com.googlecode.pu1.domain.PersonDetail].
Internal Exception: java.lang.NoSuchMethodException: com.googlecode.pu1.domain.PersonDetail._persistence_getperson_vh()
Mapping: org.eclipse.persistence.mappings.OneToOneMapping[person]
Descriptor: RelationalDescriptor(com.googlecode.pu1.domain.PersonDetail --> [DatabaseTable(PERSONDETAIL)])

Runtime Exceptions: 
---------------------------------------------------------

java.lang.NullPointerException

 org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:478)
 org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
 org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:671)
 org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:633)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:230)
 org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
 org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
 org.springframework.orm.jpa.JpaTransactionManager.createEntityManagerForTransaction(JpaTransactionManager.java:400)
 org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:321)
 org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
 org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:336)
 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:102)
 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 $Proxy22.findAll(Unknown Source)
 com.googlecode.sandcode.helloworld.HelloWorld.getName(HelloWorld.java:29)
 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 java.lang.reflect.Method.invoke(Method.java:597)
 javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
 javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175)
 com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
 com.sun.el.parser.AstValue.getValue(AstValue.java:116)
 com.sun.el.parser.AstValue.getValue(AstValue.java:163)
 com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
 com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
 javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
 javax.faces.component.UIOutput.getValue(UIOutput.java:168)
 com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:338)
 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
 javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
 javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
 javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
 com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
 com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
 com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
 com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.

Apache Tomcat/6.0.20


Although the Exception list is very long, it boils down to one thing:

The JPA entity classes should be statically woven first by EclipseLink.

During project build, EclipseLink must be configured to weave your JPA entity classes.

You can also configure EclipseLink static weaving using Maven:
<build>
 <plugins>
   <plugin>
     <artifactId>maven-antrun-plugin</artifactId>
     <executions>
       <execution>
         <phase>process-classes</phase>
         <configuration>
           <tasks>
             <java classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
                   classpathref="maven.runtime.classpath" fork="true">
               <arg line="-loglevel FINE -persistenceinfo src/main/resources target/classes target/classes"/>
             </java>
           </tasks>
         </configuration>
         <goals>
           <goal>run</goal>
         </goals>
       </execution>
     </executions>
   </plugin>
 </plugins>
</build>
In addition, edit your META/INF/persistence.xml and add this property:
<property name="eclipselink.weaving" value="static" />

Monday, February 15, 2010

Solving Tomcat + JSF 2.0 Error: java.lang.LinkageError: loader constraint violation

What happens when you try running JSF 2.0 web framework on Tomcat 6? This error:

HTTP Status 500 -


type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.servlet.jsp.JspApplicationContext.getExpressionFactory()Ljavax/el/ExpressionFactory;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/index_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspApplicationContext, have different Class objects for the type javax/el/ExpressionFactory used in the signature org.apache.jasper.servlet.JspServlet.service(JspServlet.java:275) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) root cause
java.lang.LinkageError: loader constraint violation: when resolving interface method "javax.servlet.jsp.JspApplicationContext.getExpressionFactory()Ljavax/el/ExpressionFactory;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/index_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspApplicationContext, have different Class objects for the type javax/el/ExpressionFactory used in the signature org.apache.jsp.index_jsp._jspInit(index_jsp.java:25) org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52) org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329) 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

The problem is simple: Tomcat ships with an old version of el-api, the Expression Language used by JSP, JSTL, and JSF.

JSF 2.0 uses the new Java EE 6 version that is EL 2.2. Unfortunately you can't just put the new EL libraries in your WEB-INF/lib because of Tomcat's restriction.

To fix this, you don't need to change your project.. but you need to patch your Tomcat installation:
  1. Delete el-api.jar from your Tomcat's lib folder.
  2.  Get the new el-api-2.2.jar from java.net and save it as el-api.jar on the Tomcat's lib folder.
You will also need to put the new el-impl.jar on your web application's WEB-INF/lib folder.

For a Maven web project, put this in your pom.xml :
                <dependency>
                    <groupId>javax.el</groupId>
                    <artifactId>el-api</artifactId>
                    <version>2.2</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>org.glassfish.web</groupId>
                    <artifactId>el-impl</artifactId>
                    <version>2.2</version>
                    <scope>runtime</scope>
                </dependency>
You also need to use java.net's Maven repository:
<repositories>
    <repository>
        <id>java.net.m2</id>
        <url>http://download.java.net/maven/2</url>
        <snapshots>
           <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>
Related Articles:

Solving Error - log4j:WARN No appenders could be found for logger

This log4j error is probably the simplest and most common problem ever encountered in Java EE development history.

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.
Actually it's not even a real problem, but it can be confusing at first. Understandably so because the error message doesn't give any hint over how to "initialize the log4j system properly".

Fortunately, it's very easy. Just save the following code as log4j.properties. Put it inside your classpath root that is WEB-INF/classes. If you're using Maven that would be src/main/resources.

log4j.rootLogger=info, R
log4j.appender.R=org.apache.log4j.ConsoleAppender
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-5p %-30.30c{1} %x - %m%n

Solving "JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved"

I believe that any Java EE Web developer working with Spring, Tomcat, JSP, and JSTL has gone through this error at least once:
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
 org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51)
 org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
 org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:116)
 org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:315)
 org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:148)
 org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:429)
 org.apache.jasper.compiler.Parser.parseDirective(Parser.java:492)
 org.apache.jasper.compiler.Parser.parseElements(Parser.java:1439)
 org.apache.jasper.compiler.Parser.parse(Parser.java:137)
 org.apache.jasper.compiler.ParserController.doParse(ParserController.java:255)
 org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
 org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:170)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:332)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)
 org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)
 org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586)
 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
 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)
This means that Tomcat cannot find the JSTL library.

If you use Maven, simply add this dependency to your pom.xml (inside <dependencies>):
        <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>jstl</artifactId>
         <version>1.2</version>
        </dependency

Make sure that you use the correct taglib meta-tag :
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Exposing RESTful APIs with JAX-RS on Spring

JAX-RS is the way to expose RESTful APIs using Java.

Since JAX-RS is a standard/specification, several implementations exist:
All of them should work with Spring, making it easy for you to use Spring dependency injection and other goodies with JAX-RS methods.

Don't forget to mark the JAX-RS beans as @Scope("request") because REST APIs should be stateless.

There's nothing forbidding you to use Singleton or other scoping though.

Sending HTTP Error Response from JAX-RS Method

Whether you use Apache CXF, Restlet, or Jersey, JAX-RS (JSR-311) gives you a standard way of sending RESTful HTTP Response with error status code.

All you need to do is throw javax.ws.rs.WebApplicationException. You don't have to change the method signature, you can still return the normal domain class when the method is successful.

 @Path("{id}")
 public SessionResource getSession(@PathParam("id") String id) {
  try {
   // ...........
  } catch (IllegalArgumentException e) {
   throw new WebApplicationException(e, Status.NOT_FOUND);
  }
 }
That's it!

JPA Error - ClassCastException: SerialContext cannot be cast to DataSource?

If you happen to get this ClassCastException error while developing with JPA 2.0 and/or EclipseLink:
[EL Severe]: 2010-02-16 04:02:45.519--ServerSession(26903574)--
java.lang.ClassCastException: com.sun.enterprise.naming.impl.SerialContext cannot be cast to javax.sql.DataSource
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94)
        at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
        at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
        at user.UserTest.setUp(UserTest.java:39)
        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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
        at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
        at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:422)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:931)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:785)
I solved this problem by removing the non-jta-data-source in the persistence.xml below:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="PragmaticDciPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>user.internal.UserMixin</class>
    <non-jta-data-source />
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost/pragmaticdci"/>
      <property name="javax.persistence.jdbc.user" value="app"/>
      <property name="javax.persistence.jdbc.password" value="app"/>
    </properties>
  </persistence-unit>
</persistence>

Persisting Qi4j Transient Composites using JPA

I've been trying to use Qi4j in a "lightweight mode", while still retaining the JPA (Java Persistence API) programming model. I haven't been successful yet.

Qi4j is a framework for domain driven development aka composite-oriented programming in Java. If that's still not enough buzzwords for you, Qi4j allows you to implement Data-Context-Interaction (DCI) architecture the same way Spring Web MVC allows you to implement MVC.

Fast forward to the current results, what I get is this error:
Testcase: createOne(user.UserTest):        Caused an ERROR
Object: org.qi4j.runtime.composite.TransientInstance@8fa0f0 is not a known entity type.
java.lang.IllegalArgumentException: Object: org.qi4j.runtime.composite.TransientInstance@8fa0f0 is not a known entity type.
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4147)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:368)
        at user.UserTest.createOne(UserTest.java:57)
In short, I was trying to persist a Qi4j Transient Composite object using JPA. Transient Composites are the simplest composite objects in Qi4j, I thought it may work.

But it won't, because JPA expects an entity class (the closest to that would be the a UserMixin class), not a TransientInstance class (which is Qi4j implementation detail).

Here's the test code:

// test/user/UserTest.java
package user;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.Test;
import org.qi4j.bootstrap.AssemblyException;
import org.qi4j.bootstrap.ModuleAssembly;
import org.qi4j.test.AbstractQi4jTest;
import static org.junit.Assert.*;

public class UserTest extends AbstractQi4jTest {

    EntityManager em;

    public void assemble(ModuleAssembly module) throws AssemblyException {
        module.addTransients(UserEntity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("PragmaticDciPU");
        assertNotNull(emf);
        em = emf.createEntityManager();
        assertNotNull(em);
    }

    @Override
    public void tearDown() throws Exception {
        if (em != null) {
            em.close();
        }
        super.tearDown();
    }

    @Test
    public void createOne() {
        UserEntity user = transientBuilderFactory.newTransient(UserEntity.class);
        user.setFirstName("Hendy");
        em.getTransaction().begin();
        em.persist(user);
        em.getTransaction().commit();
        UserEntity user2 = em.find(UserEntity.class, user.getId());
        assertEquals(user.getFirstName(), user2.getFirstName());
    }
} 
Here's the UserEntity composite interface:
// main/user/UserEntity.java
package user;

import org.qi4j.api.composite.TransientComposite;

public interface UserEntity
  extends User, TransientComposite { }
Here's the User mixin interface:
// main/user/User.java
package user;

import org.qi4j.api.mixin.Mixins;
import user.internal.UserMixin;

@Mixins(UserMixin.class)
public interface User {

    public Long getId();
    void setId(Long id);
    String getFirstName();
    void setFirstName(String firstName);
    String getLastName();
    void setLastName(String lastName);
}
And finally, the User mixin implementation:

// main/user/internal/UserMixin.java
package user.internal;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import user.User;

@Entity
public class UserMixin implements User, Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}
If you're curious about the persistence unit, here is it:
<!-- WEB-INF/persistence.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="PragmaticDciPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>user.internal.UserMixin</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost/pragmaticdci"/>
      <property name="javax.persistence.jdbc.user" value="app"/>
      <property name="javax.persistence.jdbc.password" value="app"/>
    </properties>
  </persistence-unit>
</persistence>

Friday, February 12, 2010

Writing Facelets Composite Component in JSF 2.0

JSF 2.0 is making it easier for Java EE web developers to write composite components.

Composite components are reusable custom HTML fragments + presentation logic.

I said "easier" because in JSF 1.x it was horrible. Now it's manageable, but not necessarily easier than other frameworks, like Tapestry or Wicket. At least it can compete on a similar level.

To create a composite component, write a view using Facelets XHTML like this example:
<?xml version='1.0' encoding='UTF-8' ?>

<!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:composite="http://java.sun.com/jsf/composite">

    <composite:interface>

        <composite:attribute name="title" required="true" />

    </composite:interface>

    <composite:implementation>

        <div style="background: red; color: yellow">

            #{cc.attrs.title}

        </div>

        <div style="border: 1px solid green">

            <composite:insertChildren />

        </div>

    </composite:implementation>

</html>
Save the XHTML code above as resources/ezcomp/titleBorder.xhtml.

Composite components live under resources folder, and the namespace will be determined from the subfolder name.

Use the ezcomp:titleBorder component like this:
<?xml version='1.0' encoding='UTF-8' ?>

<!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:h="http://java.sun.com/jsf/html"

      xmlns:ezcomp="http://java.sun.com/jsf/composite/ezcomp">

    <h:head>

        <title>Composite Component Demo</title>

    </h:head>

    <h:body>

        <ezcomp:titleBorder title="Cool stuff">

            So happy to be here!

        </ezcomp:titleBorder>

    </h:body>

</html>
Not bad, is it? ;-)

Related posts:

RESTful GET URLs with JSF 2.0

JSF 2.0 introduces Bookmarkable URLs with so-called "view params", when combined with the new h:link component, can be used to implement RESTful GET URLs.

Traditionally JSF is using POST exclusively. It was possible to use GET but in practice this required some workarounds, especially because "page load action" is not natively supported by JSF. In effect, making Ruby on Rails-style controller ridiculously hard to implement.

JSF 2.0 improves this. Let's see how it's done.

A JSF-style show entity link looks like this:
<h:commandLink action="#{campaignController.prepareView}"
  value="Show"/>
Where CampaignController.prepareView() essentially sets the current entity bean that will be displayed by the next view:
public String prepareView() {
    current = (Campaign)getItems().getRowData();
    selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
    return "View";
}
This works, but it's quite overkill to use HTTP POST just for showing a page of entity info. To change it to GET, we use h:link :
<h:link outcome="ViewOne" value="Show Campaign">
  <f:param name="campaignId" value="#{item.id}" />
</h:link>
This will generate a URL like http://localhost:8080/app/faces/campaign/View?campaignId=7

We'll need to process this new parameter "campaignId", by declaring a viewParam inside f:metadata in the destination JSF view (ViewOne.xhtml):
<f:metadata>
  <f:viewParam name="campaignId" value="#{campaignController.campaignId}"/>
</f:metadata>
The campaignController.campaignId refers to a property, therefore we create the setter and getter in the controller class:
public Long getCampaignId() {
    if (current != null) return current.getId();
    else return null;
}

public void setCampaignId(Long campaignId) {
    current = ejbFacade.find(campaignId);
}
That's it!

The URL is still not pretty / SEO-friendly, but for that purpose we can use PrettyFaces.

Related resources:

Solving Configuration Failed Error on JSF 2.0 + IceFaces 2.0

I'm trying IceFaces 2.0 alpha 2 web development on JSF 2.0, using NetBeans 6.8 and Glassfish v3. The JARs needed are:
  • icefaces.jar
  • icepush.jar
  • icefaces-compat.jar
  • icefaces-comps-compat.jar
  • krysalis-jCharts-1.0.0-alpha-1.jar

If you are getting this error:
SEVERE: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! org.apache.commons.logging.LogFactory
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:5216)
        at com.sun.enterprise.web.WebModule.start(WebModule.java:499)
Backtracking above, the error log shows:
com.sun.faces.config.ConfigurationException: 
  Source Document: jar:file:/C:/Users/ceefour/Documents/NetBeansProjects/AddressBook/build/web/WEB-INF/lib/icefaces-comps-compat.jar!/META-INF/faces-config.xml
  Cause: Class 'com.icesoft.faces.component.effect.ApplyEffectRenderer' is missing a runtime dependency: java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
        at com.sun.faces.config.processor.AbstractConfigProcessor.createInstance(AbstractConfigProcessor.java:281)
        at com.sun.faces.config.processor.RenderKitConfigProcessor.addRenderers(RenderKitConfigProcessor.java:313)
Which means Apache Commons Logging is needed.

To solve this problem, add commons-logging.jar into the web app classpath, and the IceFaces 2.0 web application should start successfully.

Solving EclipseLink-JPA Connection Error: User id length (0) is outside the range of 1 to 255.

While trying to connect to a database with NetBeans 6.8, EclipseLink - JPA, and Apache Derby / Java DB, I get the following error:

 User id length (0) is outside the range of 1 to 255.

It's because a non-empty username is needed for connection. However, I've put a username and the problem persists.

The solve this problem, edit META-INF/persistence.xml and add the following:
    <properties>
      <property name="javax.persistence.jdbc.user" value="APP"/>
      <property name="javax.persistence.jdbc.password" value="APP"/>
     </properties>
Change user and password to your configuration.

Note: The above works only for JPA 2.0-compliant ORM. For proprietary EclipseLink would be:
    <properties>
      <property name="eclipselink.jdbc.user" value="APP"/>
       <property name="eclipselink.jdbc.password" value="APP"/>
    </properties>

Related resources:

Plugin Architecture for Java EE Web Applications?

Java EE Web Applications are usually self-contained, in the sense that there is only limited runtime extensibility. It begs the question: How to support plugins architecture in a Java EE webapp?

Examples in the real world:
  • Mozilla Firefox addons
  • NetBeans modules
  • Eclipse IDE plugins
  • Servlet containers and WARs
A plugin system for Java EE would basically allows you to load in arbitrary jars as plugins. In case of plugins containing web resources, they would probably be WARs, not just JARs.

The plugin system requires the capability to load a plugin WAR (a sub-WAR, perhaps) inside an already running WAR. These plugin WARs can be added, removed, configured, at runtime just like relationship of normal WARs with the container.

Java Portlets are the closest thing to a standard way of doing this. You deploy portlet WARs into a Liferay container, easy. But since we're creating something like a Portlet container, it isn't straightforward.

OSGi is probably the best bet, however it also has its own complexities and classpath model.

What's your advice?

JSF 2.0 RESTful URLs with PrettyFaces

JSF's RESTless nature is a big problem to some Java EE web developers. Not everybody cares, unfortunately I'm coming from a Ruby on Rails background so I'm one of the guys who cares.

In JSF, by default every page transition is done using HTTP POST. Even when you use JSF's GET support aka bookmarkable URLs, you still don't get the pretty SEO-friendly URLs that frameworks like Ruby on Rails generate by default.

Lucky you and me, there is a solution: PrettyFaces by OcpSoft.

Checkout the  PrettyFaces slideshare presentation below on why pretty, bookmarkable, SEO-friendly URLs are important for a JSF web application; and how to do it.

What's the Java EE killer apps?

Java EE 6 and JSF 2.0 has been released, as also Spring Frameworks 3.0. But when I think of killer apps what comes to my mind are: WordPress, Drupal, Magento, Moodle, vTiger CRM.

What are the Java EE killer apps, specifically the open source opens?

I definitely can think of a few well-known open source Java apps, like Liferay, Alfresco, Nuxeo...

These definitely aren't lightweight. And they're not (yet?) using the latest improvements available in Java as of 2010, not even 2009. And I shudder to think these apps being used as the reference best practices or study of Java EE's ease of development.

Can you suggest Java EE apps that are...
  • "killer app" compliant, i.e. highly useful
  • demonstrating practical usage of the latest Java EE technologies
  • can serve as a learning tool, reading Java EE code shouldn't be that hard
  • using the best design & programming practices of the Java EE community
  • open source (hopefully)
Any ideas would be much appreciated!

Thursday, February 11, 2010

Facelets editor for Eclipse Java EE IDE ?

One thing lacking in Eclipse IDE for Java EE web development is Facelets (JSF) editor with Code Assist / code completion features.

Is there such thing? Where?

My Google App Engine Preferred Stack

I'd like to jump deeper into Google App Engine, and my preferred web development stack would be:
  • CDI (JSR-299) for depency injection, using Weld. So apps are easily portable from/to Java EE 6.
  • JPA for ORM, using GAE's recommended DataNucleus. So apps are somewhat portable. The primary key is always GAE's proprietary Key type, I wonder if this can be made somewhat more portable?
  • JSF 2.0 for web framework, using Mojarra.
  • PrimeFaces as the Facelets component library, as I want to try TouchFaces mobile UI. I am not fixed into a single xFaces library though. IceFaces, RichFaces, or Apache Trinidad will do just fine.
  • Maven Ant Tasks for dependency management. Before GAE has decent Maven integration that allows "refresh-driven-development" aka short build-debug cycle, I'll use the standard Google App Engine for Eclipse development model, with Maven Ant Tasks to help me with JAR dependencies.
  • Spring Security for authentication & authorization. Ouch... will this conflict with Weld?
My experiences will be coming soon to this blog :-)

Google App Engine for Java Web Development Review

I have been experimenting in Google App Engine for Java web development and my first impressions are... it's (still) buggy.

Google App Engine's administration console is even not working for me. Instead of listing my apps, it continually prompts me to create an application. I have actually created a bunch of app IDs (and I can deploy my app to them).

For now, here are useful resources related to Google App Engine for Java web development:

Monday, February 8, 2010

Spring Web Flow Cheat Sheet

DZone has posted a new refcard that is Spring Web Flow Cheat Sheet.

Based on Spring MVC, Spring Web Flow is a framework for building flow-based applications. In this Refcard, you’ll see how to add Spring Web Flow to a Spring application and define flows that initiate conversations between the application and its users.

Check out and download it here.

Thursday, February 4, 2010

What is the Best Java Web Framework?

If you're looking for the best web framework for your Java EE project, which one will you choose?

First of all you should decide what kind of web framework are you looking for, action-based or component-based, or else.

Action-based means that the web application is fundamentally page-oriented, where HTTP requests are dispatched to a specific controller and then responded.

Component-based means that the web application is more about components than pages. You develop your web application similar to developing desktop GUI applications and Flex RIAs.

Service-oriented web applications are those that provide REST APIs and generally consume and produce JSON, XML, or Atom... not HTML. This kind of applications will be discussed in another post (remind me, please!) :-)

Here are the frameworks that I recommend you should review.

Action-based Java Web frameworks

Component-based Java web frameworks 

Thanks to JSF 2.0, the choice in this category is simpler. JSF 2.0 comes with built-in AJAX support, which means you not only have a choice in component libraries but can mix-and-match them if you want.
At the time of this writing, most JSF 2.0 component libraries are still in beta testing phase.

For the JSF 2.0 implementation you have several choices: Mojarra, Apache MyFaces.

Other considerations.
  • JBoss Seam 3 (not yet released) since it has JSF 2.0 support.
So, what's your take? Let me know of your opinions.

Monday, February 1, 2010

Spring 3.0 vs Java EE 6 - The Review

Spring Framework 3.0 and Java EE 6 has been released almost simultaneously during late 2009. Both are technologies to develop enterprise applications for Java, notably web applications. Which one is better?

Although they are competitors, their approach and philosophy are radically different.

Spring aims to promote best-of-breed, mix-and-match, use-only-what-you-need kind of development, and portability across all Java EE servlet web servers (most notably Apache Tomcat). That is, because the application server is Spring itself.

Java EE on the other hand, gives you the full package. It has changed a lot now with Java EE 6, in that you don't have to use all of Java EE's components to use Java EE 6. The powerful-ness of Java EE 6 comes from the standard specification of technologies, which is also its weakness: it's not really meant to be flexible.

Now when I'm talking Java EE 6, I meant the components for a web application, which are: Servlet 3.0, EJB 3.1, CDI, JSF 2.0 + Facelets, JPA.

However when I'm talking Spring, I'm mostly talking about Spring Framework, and less of the rest of the Spring Portfolio (e.g. Spring MVC, Spring Web Flow, Spring Security, etc.)

Why I mentioned that, is because there is a noticeable shift from SpringSource, the maker of Spring Framework.

In its Spring Framework version 2.5, Spring is making developers enjoy the most of Java EE 5 with:
* ability to deploy on any servlet container (since Spring "application server" is embedded)
* choice of backend implementations (JPA vs. Hibernate)
* easier to use templates to use an API (e.g. HibernateTemplate)
* enabling dependency injection to any web framework

However, recent APIs and specifications reduce the significance the above benefits of using Spring.

For example, if you're using JPA (Java Persistence API), there's not much gain of using JpaTemplate to standard JPA API. This is compared to the gain of using HibernateTemplate to Hibernate API.

In fact, JpaTemplate will make your application *less* portable. Which is what you want out of Spring. Strange, isn't it?

CDI (Java Context and Dependency Injection aka JSR 299) and Bean Validation (JSR 303) specs make this matter worse for Spring.

CDI is not only a better dependency injection than Spring, but it's a standard (Spring's XML format and annotations are always proprietary). Moreover, Spring doesn't (yet?) support CDI.

Bean Validation makes Spring MVC's validations look ancient. You can use Bean Validation with Spring using Hibernate Validator, but it's not an integral part of Spring.

Perhaps this happens because SpringSource is focusing more on its corporate strategy than the Spring philosophy.

With SpringSource always expanding its portfolio of technologies, they're now a Java application server company and infrastructure provider (with parent company VMware). Surely it's in their best interest to lock-in customers with proprietary technologies than open specifications?

Corporate politics aside, both Spring and Java EE are actually converging when you compare it with a few years ago. You can write code that work in both Spring and Java EE environments. Fortunately, the part that you still need to get specific on is only configuration... i.e. Dependency Injection.

Beyond that though, it's a completely different arena. You can assume Java EE 6 apps use JSF 2.0, but who knows what eccentric web framework is used in a Spring app?

Spring promotes Spring MVC, but it's not the only choice. Even if it's Spring MVC, there are so many ways to configure a Spring MVC app. Even more when you add Spring Web Flow. It's too flexible!

A Java EE 6 application server enables easily deployment of Java EE 6 apps. However, you don't always have to use a Java EE 6 server to use a technology from Java EE 6. For example if you use CDI, you can use an open source implementation like Weld, and run your app in Tomcat.

In the end, who will win: Spring or Java EE? Let me know what you think in the comments.

Logging to GUI by Writing Custom log4j Appender

All applications need logging. Logging means presenting useful information to the user. Logging can be configured separately from the code that emits logging information.

Apache log4j is a logging implementation library for Java. It can be used directly, however to make our application more portable, we usually use logging abstraction. I recommend Apache Commons Logging for this.

The most popular logging configurations are:
  • printing messages to standard console output
  • appending messages to a log file
However there is one popular use of logging that is seldom talked about, and that is logging to GUI.

For example, you have a text box and you want to log messages to it.

Of course you can do it the old fashioned way, by getting the text box object and appending messages directly to it. But other than it is not portable, and all of your code will be dependant on that text box object.

A more robust resolution would be to use log4j's flexibility. Here I will prove to you that flexibility does not have to equal complex.

log4j since version 1.2 adds a feature that is dynamic logging configuration at runtime. We'll use this feature to add a GUI Appender to log4j. An Appender's job is to take action of a log event. In our case, displaying the log message to a text box.

See the code below:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class MainConsoleFrame extends javax.swing.JFrame {

    private Log log = LogFactory.getLog(MainFrame.class);
    private Appender guiAppender;
    ...

    public AuthoringConsoleFrame() {
        initComponents();
        
        // Setup logging to GUI
        final MainFrame frame = this;
        guiAppender = new AppenderSkeleton() {
  
     @Override
     public boolean requiresLayout() { return true; }
  
     @Override
     public void close() { }
  
     @Override
     protected void append(LoggingEvent event) {
             frame.consoleMessagesArea.append(layout.format(event));
         consoleMessagesArea.setCaretPosition(consoleMessagesArea.getText().trim().length() - 1);
            }
        };
 guiAppender.setLayout(new PatternLayout("%5p|%40.40c|%m%n"));
        Logger.getRootLogger().addAppender(guiAppender);
        
        // Log like this...
        log.info("Hello world!");
    }
    
    @Override
    protected void finalize() throws Throwable {
     Logger.getRootLogger().removeAppender(guiAppender);
     super.finalize();
    }

    ...
}    

Please note that I skipped a lot of boilerplate code in the above.

After setting up the Appender, you probably notice that the code for logging is now very simple. It uses Apache Commons Logging which means the application will work with any logging implementation. This makes code very portable, even if you remove the textbox or move code to a different application, logging code should just work.

I hope this post is helpful to you. Let me know if you have ideas or questions.
 
Copyright 2009 Spring vs Java EE Web Dev. Powered by Blogger Blogger Templates create by Deluxe Templates. WP by Masterplan