Monday, April 20, 2009

Portal Update March / April 2009

Winter has turned into Spring, at least here in Switzerland... and in parallel to the brighter days, let's bring some light into the Java Portal area as well: What products are interesting these days and which should be followed for sure in 2009?

From the commercial side, major players are:
Open Source portals that have the most promising potential at the moment are:
  • Liferay Portal 5.2:
    back in August 2008, SUN and Liferay announced their partnership to work jointly on the next portal generation and presented their roadmap, Liferay keeping their Liferay Portal and SUN continuing their WebSynergy project).

  • SUN's brand new Web Space Server:
    Since February 2009, SUN has released Web Space Server version 10 which is including all the efforts from the internal Project WebSynergy. WebSpace Server is not only a portal product, it is a full fletched portal platform and has been integrated into the Glassfish Portfolio.
    For more info, read their first documentations.

  • JBoss Portal 2.7.2:
    - On March 12th, JBoss has released the latest version of its portal product and is available for download.
    - On Apr 3rd, JBoss released the JSR-301 compliant Portlet Bridge CR1. Currently the bridge supports any combination of JSF, Seam, and RichFaces to run inside a portlet.

  • eXo Portal 2.5.1

  • Jetspeed 2: no updates since version 2.1.3 from December 2007.
From a portal technology point of view, it is interesting to see the product's maturity with regards to the following standards:
  • JSR-168 - Portlet Specification (final since Oct 2003)
  • JSR-286 - Portlet Specification 2.0 (final since June 2008)
  • WSRP 1.0 - The first specification of Web Services for Remote Portlets (final since August 2003)
  • WSRP 2.0 (final since April 2008)
  • JSR-301: Portlet 1.0 (JSR-168) Bridge Specification for JSF 1.x:
    Current Status: proposed final draft in Jan 2009
    Currently available implementations of JSR-301:
    - MyFaces Portlet Bridge
    - OpenPortal Portlet Bridge (used in Liferay Portal)
    - JBoss Portlet Bridge (used by JBoss Portal)
  • JSR-329: Portlet 2.0 (JSR-286) Bridge Specification for JSF 1.2:
    too early for products to support this JSR as it has been created in January 2009 and is in the status "Early Draft Review" as of March 2009.
    Note that this specification is led by Oracle exclusively at the moment.
  • JSR-314: JSF 2.0:
    The support of JSF 2.0 in a portlet container is not yet officially addressed. There is no JSR around like "Portlet 2.0 Bridge for JSF 2.0".




Besides the Portal related activities, let's have a look on Java related quick news:
  • SUN has announced that Glassfish v3 Milestone 2 will be ready by Java One 2009 in June.
    For the complete schedule, click on this link.
  • Liferay 5.2 is now fully supporting WSRP 2.0 with the release of the WSRP 2.0 FCS binary.
  • Oracle & SUN: Oracle buys SUN as of the announcement on April 20th 2009.
    It will be very interesting what will happen to SUN's products like
    - The whole Glassfish Portfolio
    - MySQL
    - Netbeans
    - OpenSolaris and
    - JavaFX
  • Java EE 6: The JSR-316 has passed the Public Review state. See its results.

Friday, April 17, 2009

Java People Spotlight: Domenico Crescenti

In this edition of the "CTP People Spotlight" series we introduce Domenico, one of the CTP competences for content related topics.

Java Competence Role:
Messica (insider)
My Master Kung-Fu Skills
:
They call me Mr. Bean
I'd be excited to get my hands dirty on:
JCR 2.0 (JSR-283)

Q&A

Q: Hi Domenico, how would your message look like if you would have to tell it via Twitter what you are currently doing?
A: I'm buying some insecticide to feed the bug in my code :)

Q: What was the greatest piece of code you have ever written so far?
A: That was definitely the play fair chiffre

Q: What is the best quote you have ever heard about programming?
A:
"Cool!!! You didn't mess up my code"

Q: What is the best quote you have heard from our managers?
A: "........."

Q: What is the most cutting-edge technology or framework you actually used on projects?
A: Vamosa!

Q: What is your favorite podcast?
A: Discovery Channel Video Podcast – the US original of course – and the Java Posse Podcast

Q: Which Java book can you recommend and for what reason?
A: Java (Taschenbuch) by far the best Java book I’ve ever read.

Thursday, April 16, 2009

JBoss Seam on Google App Engine - First Steps

[UPDATE] The latest Morjarra release 1.2_13 as well as the latest Appengine SDK 1.2.2 seem to fix a couple of problems described below. My task backlog is actually growing :-) but I hope I find some time to look again how things work with these new versions.

I spent the last three weeks in a repetition course of the Swiss army - far away from any Java code. Naturally my fingers started to itch while reading the announcement of Google that their App Engine now supports Java! So I grabbed my MacBook to enjoy the sun, Java coding and Eastern holidays.

As I usually write web applications with JBoss Seam, I decided to give the framework a try in the Google cloud - preparing for a bumpy road as Seam founds on standards which are mostly listed as either not or not known to be working. The following article describes the (bad) tweaks I had to do to get something basic running - I guess if you start doing serious development, you might hit more walls.

First, install the Eclipse Plugin for App Engine and create a new project. I'll base my descriptions on this initial setup. Switch on sessions in appengine-web.xml:
<sessions-enabled>true</sessions-enabled>

Setting up JSF 1.2

Download the latest Mojarra 1.2 release [1.2_12] and put it in the WEB-INF/lib directory. You can configure the Faces servlet in web.xml as usual
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>

Starting Jetty with only this will fail due to some incompatibilities of Jetty and Mojarra. As with Seam we will need JBoss EL anyway, we can configure Mojarra to use the JBoss EL ExpressionFactory. Add the JBoss EL JAR to WEB-INF/lib and the following XML to your web.xml:
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>

Now it's already patch time. Jetty in the Google environment seems to have a bug in its Servlet API implementation, missing the ServletContext.getContextPath() method (new in version 2.5). Also, Mojarra tries to be clever about initialization work and uses Threads in the ConfigManager - the App Engine SecurityManager will let the whole thing blow up. Something similar happens in the JBoss ReferenceCache class. All patched classes can be found here. Drop the Java code in your source folder, Jettys classloader will pick it up.

This will at least make the whole thing start up. I also added facelets (JAR file, view handler in faces-config.xml and view suffix in web.xml).

Unfortunately, using RichFaces components is an absolute no go on App Engine. RichFaces is full of references to AWT or JAI classes, which Google blocks completely. If anybody wants to try ICEFaces - good luck!

Adding Seam

Now it's time to add all the Seam stuff. Quite a couple of JARs to put into the application. I basically used Seam 2.1.1.GA and libraries from JBoss 4.2.3.GA. The complete list of what should go into WEB-INF/lib is shown in the screenshot below.



JTA is not even on the list of APIs Google gives a recommendation, so let's fall back on Java SE behavior. Configure components.xml with:
<transaction:entity-transaction entity-manager="#{entityManager}"/>


Although we cannot use Hibernate as persistence provider, Seam has a couple of dependencies to it (e.g. when using Hibernate Validators). As soon as we have it in the classpath, Seam activates its HibernatePersistenceProvider component. This will behave pretty bad, and for simplicity we just override this component:
@Name("org.jboss.seam.persistence.persistenceProvider")
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Install(precedence = Install.APPLICATION,
classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
public class OverrideHibernatePersistenceProvider extends PersistenceProvider {
}

Now also add a persistence provider as described in the Google docs and disable DataNucleus checking for multiple PersistenceContextFactory instantiations with this property in appengine-web.xml.
<property name="appengine.orm.disable.duplicate.emf.exception" value="true"/>


As before, also Seam needs a couple of patches. Main reasons for those are references to javax.naming.NamingException (which is not white listed, credits to Toby for the hint) and session/conversation components not implementing Serializable correctly. The last point is probably something not hitting Seam or your application the last time.

Identity

As a next step I tried to add some users to the application. Seam's Identity module builds around the javax.security.auth.Subject and Principal classes. Even though those classes are white listed, the SecurityManager blocks any attempt to add a Principal to a Subject. Well, how useful is that... As a quick fallback I integrated the Google Accounts API:
@Name("org.jboss.seam.security.identity")
@Scope(SESSION)
@Install(precedence = Install.APPLICATION)
@BypassInterceptors
@Startup
public class AppEngineIdentity extends Identity {

private static final long serialVersionUID = -9111123179634646677L;

public static final String ROLE_USER = "user";
public static final String ROLE_ADMIN = "admin";

private transient UserService userService;

@Create
@Override
public void create() {
userService = UserServiceFactory.getUserService();
}

@Override
public boolean isLoggedIn() {
return getUserService().isUserLoggedIn();
}

@Override
public Principal getPrincipal() {
if (isLoggedIn())
return new SimplePrincipal(getUserService().getCurrentUser().getNickname());
return null;
}

@Override
public void checkRole(String role) {
if (!isLoggedIn())
throw new NotLoggedInException();
if ((ROLE_ADMIN.equals(role) && !getUserService().isUserAdmin()) || !ROLE_USER.equals(role))
throw new AuthorizationException(String.format(
"Authorization check failed for role [%s]", role));
}

@Override
public boolean hasRole(String role) {
if (!isLoggedIn())
return false;
return ((ROLE_ADMIN.equals(role) && getUserService().isUserAdmin()) || ROLE_USER.equals(role));
}

@Override
public String getUsername() {
if (isLoggedIn())
return getUserService().getCurrentUser().getNickname();
return null;
}

public String createLoginURL(String destination) {
return getUserService().createLoginURL(destination);
}

public String createLogoutURL(String destination) {
return getUserService().createLogoutURL(destination);
}

public User getUser() {
if (isLoggedIn())
return getUserService().getCurrentUser();
return null;
}

private UserService getUserService() {
if (userService == null)
userService = UserServiceFactory.getUserService();
return userService;
}

}

Both create... methods can be used in the UI for generating login/logout URLs. Destination defines the URL the user gets redirected after successful login/logout. Also make sure that the identity configuration is removed from components.xml

Wrap up

Running this setup should give you a base for a very simple Seam app like in the screenshot below.



This first step has not been doing any persistence work, and my first tries with DataNucleus were not as straight forward as I had expected from a JPA implementation. Hope Google will catch up here with something more mature. Also, even the simple setup required a couple of nasty tweaks on the frameworks. Another big hurdle here are the runtime differences from production to local environment. For some serious work on App Engine, it's so far more recommendable to look into GWT.

Anyway, if you found this useful - looking forward to hear from your next steps in the cloud.