SpringOne 2GX 2011

Chicago, October 25-28, 2011

Cagatay Civici's complete blog can be found at: http://prime.com.tr/cagataycivici

Items:   1 to 5 of 10   Next »

2008-06-18 03:48:00.0

I was wondering if writing the backing bean code for JSF with ruby or groovy is a good idea or not after seeing Kito’s presentation in Austria JSFDays08 about this topic. So decided to give it a try. Spring’s dynamic language support is where I’ve started. Currently spring supports groovy, jruby and beanshell, in this example I’m using ruby.

Following is a simple xhtml jsf view;


<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">

<h:form>
<h:inputText value="#{myBean.text}"></h:inputText>
<h:commandButton action="#{myBean.click}" value="Submit"></h:commandButton>
You typed: #{myBean.text}
</h:form>
</html>

The backing bean name is “myBean” with a text property, you can easily provide the code for this bean with java, but that’s just boring right:)
In order to implement this backing bean with ruby we need an interface for the spring-jruby integration;


public interface IMyBeanController {
public String getText();
public void setText(String text);
public String click();
}

Here’s the ruby backing bean that implements this interface;


require 'java'

include_class 'com.prime.tutorial.moviestore.view.scripting.IMyBeanController'

class MyBeanController
include IMyBeanController

@text = nil

def setText(text)
@text = text
end

def getText
@text
end

def save
puts @text
end

end

Final step is to define this bean as a spring bean;


<lang:jruby id="myBean"
script-interfaces="com.prime.tutorial.moviestore.view.scripting.MyBeanController"
script-source="classpath:com/prime/tutorial/moviestore/view/scripting/MyBeanController.rb" scope="request">
</lang:jruby>

Note that the scripted backing bean can also have a scope like request. Of course we need standard jsf-spring integration configuration to make this stuff work, you can check my older post about how to do it. By the way you can also use groovy or beanshell instead of ruby.

Although the idea of using a scripted language with JSF looks interesting there’re some downsides;

- I couldn’t make attr_reader :message work, so I had to write the accessors for the text property, what’s the point of using ruby if I’m going to use it as java right?
- Your scripted backing bean needs to implement a java interface for the integration, this just sucks.

Other than these downsides there’s a really cool part here, since the backing bean is scripted it can be reloaded without redeploying or reloading the application, just add refresh-check-delay=”5000″ to the bean definition in spring and the changes in the development environment will be reflected easily.

To sum up, sure the idea is cool but the cons make this a bit ugly.


2008-06-17 03:41:00.0

On my way to combine my favorite frameworks together, I posted an example application called moviestore demonstrating the annotation driven integration of JSF(Facelets)-Spring-JPA. .
Lately I’ve added Spring-Security and Apache MyFaces Orchestra to this formula to fix the missing parts for security and conversation-workflow management.

Here’s the final contents of moviestore;
- JSF with Facelets, Apache MyFaces 1.2 impl
- Spring 2.5.x
- JPA with Toplink
- Spring Security
- Apache MyFaces Orchestra

with jetty and hsqldb

The example contains two modes of new movie entity creation, one is done on single page and the other is the wizard mode and consists of 3 pages.Thanks to MyFaces Orchestra, creating wizards, flowScopes, viewScopes are no-brainer. Best part is that you dont get Lazy Exception since Orchestra manages the entity manager per conversation rescuing us from the openblablainviewfilter pattern. If you’re still not using Orchestra, give it a try, it’ll make your life much easier, simply request or session scope both are not enough for web applications and Orchestra is a life-saver. Again Persistence support
is a fantastic bonus.

Other addition to the moviestore example is the spring-security formerly known as acegi. I really liked the new namespace support, considering the number of xml lines with Acegi, Spring-Security is fun to use.

You can download the moviestore here. It uses in memory db and jetty so just running
mvn jetty:run is enough to test the moviestore in action. By the way,

username: tony
password: 55555


2008-04-21 03:35:00.0

FacesTrace, developed by me and my fella Yigit Darcin, is a small library to display several visual trace info for JSF applications. Other than the trace/debug features the library also has an educational value on the learning process of JSF itself. Following is the changelog;

Online Demo : http://www.nightdev.devisland.net/facestrace-example

Check out the project homepage : http://facestrace.sourceforge.net

See you on 1.0.0 with new features;)


2008-03-04 04:51:00.0

JSF-Spring-JPA is the popular stack of choice these days, mostly to be used in my consulting and training purposes I’ve created a base project called MovieStore demonstrating the annotation-driven integration of JSF-Spring-JPA. JSF backing beans, spring service level beans and DAO’s are configured and integrated with annotations. Only the core infrastructure like datasource, entityManagerFactory or transactionManager are configured with xml.

Following are the package contents;

- JSF (MyFaces 1.2.2 with Facelets)
- Spring 2.5
- JPA with Hibernate
- HSQLDB for persistence
- Jetty for deployment
- Maven2 for build

The example application is simple; a MovieStore(Yes, I’m a movie maniac so all my examples are about movies)
There are two formats DVD and BLU-RAY, not including HD-DVD because it’s dead.

Movie


package com.prime.tutorial.moviestore.domain;

//imports not displayed

@Entity
public class Movie implements Serializable{

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

    @Basic
    private String title;

    @Basic
    private Integer discs;

    @Enumerated
    private Format format;

    public Movie() {}

    public Movie(String title, Integer discs) {
        this.title = title;
        this.discs = discs;
    }

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

    public Integer getDiscs() {
        return discs;
    }
    public void setDiscs(Integer discs) {
        this.discs = discs;
    }

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public Format getFormat() {
        return format;
    }
    public void setFormat(Format format) {
        this.format = format;
    }
}

For DAO part, I’ve included a GenericDAO too for the crud operations;


package com.prime.tutorial.moviestore.dao;

//imports are not displayed

public interface GenericDAO<t, ID extends Serializable> {

	T loadById(ID id);

	void persist(T entity);

	void update(T entity);

	void delete(T entity);

	List<t> loadAll();

}

Following is the GenericDAO implementation with JPA, note how the entityManager is injected. Instead of extending JPATemplate, with @PersistenceContext, the entityManager is resolved by spring. This way you don’t need to subclass JPATemplate.


package com.prime.tutorial.moviestore.dao;

//imports are not displayed
public abstract class GenericDAOWithJPA<t, ID extends Serializable> implements GenericDAO<t,ID> {

	 	private Class<t> persistentClass;

	 	@PersistenceContext
	 	protected EntityManager entityManager;

	 	@SuppressWarnings("unchecked")
	    public GenericDAOWithJPA() {
	        this.persistentClass = (Class<t>) ((ParameterizedType) getClass()
	                                .getGenericSuperclass()).getActualTypeArguments()[0];
	    }

	    public Class<t> getPersistentClass() {
	        return persistentClass;
	    }

	    public T loadById(ID id) {
	       return entityManager.find(persistentClass, id);
	    }

	    public void persist(T entity) {
	        entityManager.persist(entity);
	    }

	    public void update(T entity) {
	        entityManager.merge(entity);
	    }

	    public void delete(T entity) {
	        entityManager.remove(entity);
	    }

	    @SuppressWarnings("unchecked")
	    public List<t> loadAll() {
	        return entityManager.createQuery("Select t from " + persistentClass.getSimpleName() + " t").getResultList();
	    }
}

That’s all about the GenericDAO, for movie specific database operations here comes the MovieDAO.

MovieDAO


package com.prime.tutorial.moviestore.dao;

//imports not displayed

public interface MovieDAO extends GenericDAO{

    public List findByTitle(String title);
}

MovieDAOWithJPA is annotated with @Repository, by this way spring can manage it and can also allows ExceptionTranslation(PersistenceAnnotationBeanPostProcessor also needs to be configured in applicationContext.xml).


package com.prime.tutorial.moviestore.dao;

//imports not displayed

@Repository
public class MovieDAOWithJPA extends GenericDAOWithJPA implements MovieDAO{

    @SuppressWarnings("unchecked")
    public List findByTitle(String title) {
        Query query = entityManager.createQuery("Select m from Movie m where m.title = ?1");
        query.setParameter(1, title);

        return query.getResultList();
    }

}

At service level there are two classes, MovieService and MovieServiceImpl.

MovieService - Notice the @Transactional annotation, this way transactions are configured with annotations.(<tx:annotation-driven /> also needs to be declared to enable this, see applicationContext.xml)


package com.prime.tutorial.moviestore.service;

//imports not displayed

public interface MovieService {

    public void createNew(Movie movie);

    public List findAll();

    public List findByTitle(String title);
}

MovieServiceImpl - @Service annotation makes this a spring bean, and movieDAO is injected by type using @AutoWired


package com.prime.tutorial.moviestore.service;

//imports not displayed

@Service
public class MovieServiceImpl implements MovieService{

    private MovieDAO movieDAO;

    @Autowired
    public MovieServiceImpl(MovieDAO movieDAO) {
        this.movieDAO = movieDAO;
    }

    @Transactional
    public void createNew(Movie movie) {
        movieDAO.persist(movie);
    }

    public List findAll() {
        return movieDAO.loadAll();
    }

    public List findByTitle(String title) {
        return movieDAO.findByTitle(title);
    }
}

Finally the JSF Bean and Facelets page to use the stuff above, the page is used for creating new movies.

createMovie.xhtml


<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	template="template.xhtml">

  <ui:define name="content">
	<h:messages showDetail="true"/>
	<h:form>
		<h:panelGrid columns="2">
			<h:outputLabel for="title" value="Title"></h:outputLabel>
			<h:inputText id="title" value="#{createMovie.movie.title}"></h:inputText>

			<h:outputLabel for="discs" value="Number of Discs"></h:outputLabel>
			<h:inputText id="discs" value="#{createMovie.movie.discs}"></h:inputText>

			<h:outputLabel for="format" value="Format"></h:outputLabel>
			<h:selectOneMenu id="format" value="#{createMovie.movie.format}">
				<f:selectItem itemLabel="DVD" itemValue="DVD" />
				<f:selectItem itemLabel="BLU-RAY" itemValue="BLURAY" />
			</h:selectOneMenu>
		</h:panelGrid>
		<h:commandButton value="Save" action="#{createMovie.save}"></h:commandButton>
	</h:form>
  </ui:define>

</ui:composition>

CreateMovie is the backing bean to handle this page, also managed by spring. The MovieService is set through construction injection, one thing you cannot do in plain jsf ioc. @Component marks this bean as a spring bean with the “createMovie” name. In jsf views, this is the name to be resolved in el expressions like #{createMovie.movie.title}. @Scope is set to request, as you may already know with spring it’s also possible to provide custom scopes.


package com.prime.tutorial.moviestore.view;

//imports not displayed

@Component("createMovie")
@Scope("request")
public class CreateMovie implements Serializable{

    private MovieService movieService;

    private Movie movie = new Movie();

    @Autowired
    public CreateMovie(MovieService movieService) {
        this.movieService = movieService;
    }

    public Movie getMovie() {
        return movie;
    }
    public void setMovie(Movie movie) {
        this.movie = movie;
    }

    public String save() {
        movieService.createNew(movie);
        FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, "Movie is saved successfully", "OK");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
        movie = new Movie();

        return null;
    }
}

So where’s the xml? Let’s start with the spring config.

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<context:property-placeholder location="classpath:application.properties"/>
	<context:component-scan base-package="com.prime.tutorial.moviestore" />
	<tx:annotation-driven transaction-manager="txManager"/>

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="moviestore"/>
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="databasePlatform" value="${database.dialect}"/>
				<property name="showSql" value="${database.showSql}" />
				<property name="generateDdl" value="${database.generateDdl}" />
			</bean>
		</property>
	</bean>

	 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
        <property name="driverClassName" value="${database.driver}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
    </bean>

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

</beans>

Notes on spring config;
- <context:component-scan base-package=”com.prime.tutorial.moviestore” /> scans the moviestore sub packages for annotated classes, with this it can find our jsf beans, services, daos and etc.
- <tx:annotation-driven transaction-manager=”txManager”/> enables annotation driven transaction management
- PersistenceAnnotationBeanPostProcessor is for exception translation, we don’t extend from JPATemplate but we can still have this feature.

persistence.xml


<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1_0.xsd"
	version="1.0">

	<persistence-unit name="moviestore" transaction-type="RESOURCE_LOCAL">
		  <class>com.prime.tutorial.moviestore.domain.Movie</class>
	</persistence-unit>

</persistence>

faces-config.xml - Pretty empty:)


<?xml version="1.0" encoding="utf-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
	version="1.2">

	<application>
		<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
		<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
	</application>

</faces-config>

- DelegatingVariableResolver helps JSF to resolve spring managed beans like CreateMovie.

Finally the web.xml


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">

	<context-param>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>client</param-value>
	</context-param>

	<context-param>
		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
		<param-value>.xhtml</param-value>
	</context-param>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>

	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<listener>
		<listener-class>
			org.springframework.web.context.request.RequestContextListener
		</listener-class>
	</listener>

	<filter>
		<filter-name>JPA Filter</filter-name>
		<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>JPA Filter</filter-name>
		<url-pattern>*.jsf</url-pattern>
	</filter-mapping>

	<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>*.jsf</url-pattern>
	</servlet-mapping>
</web-app>

- org.springframework.web.context.request.RequestContextListener listener enables spring scopes with @Scope annotation

- JPA Filter is same as OpenSessionInViewFilter but for jpa.

Testing

I’ve also included an integration test for MovieDAOWithJPA, it does not subclass AbstractJPATests and configured completely on spring’s annotation support for testing.


package com.prime.tutorial.moviestore.dao;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.prime.tutorial.moviestore.domain.Movie;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TransactionConfiguration(transactionManager="txManager")
@ContextConfiguration(locations={"/applicationContext.xml"})
public class MovieDAOWithJPATest{

    private MovieDAO movieDAO;

    @Autowired
    public void setRepository(MovieDAO movieDAO) {
        this.movieDAO = movieDAO;
    }

    @Test
    public void shouldPersistNewMovie() {
        Movie movie = new Movie();
        movie.setTitle("Scarface");
        movie.setDiscs(new Integer(2));

        movieDAO.persist(movie);

        assertNotNull(movie.getId());
    }

    @Test
    public void shouldFindByTitle() {
        Movie movie = new Movie();
        movie.setTitle("Carlito's Way");
        movie.setDiscs(new Integer(1));

        movieDAO.persist(movie);
        assertNotNull(movie.getId());

        List results = movieDAO.findByTitle("Carlito's Way");
        assertEquals(1, results.size());
        assertEquals("Carlito's Way", results.get(0).getTitle());
    }

    @Test
    public void shouldReadAllMovies() {
        Movie movie1 = new Movie();
        movie1.setTitle("Godfather Part I");
        movie1.setDiscs(new Integer(1));

        Movie movie2 = new Movie();
        movie2.setTitle("Godfather Part II");
        movie2.setDiscs(new Integer(1));

        movieDAO.persist(movie1);
        assertNotNull(movie1.getId());

        movieDAO.persist(movie2);
        assertNotNull(movie2.getId());

        List results = movieDAO.loadAll();
        assertEquals(2, results.size());
    }
}

I’ve packaged my moviestore example and uploaded to http://people.apache.org/~cagatay/moviestore.rar, build is based on maven2 and you can easily get it running with;

mvn jetty:run

And then go to -> http://localhost:8080/moviestore

The database is hsqldb with inmemory setting.Final words;
I’ve actually created this sample app to be used in my consulting work but if you’ve decided to go with JSF-Spring-JPA, it is definitely a good resource for kickstart.


2008-02-24 16:38:00.0

I was playing with indeed.com job trends stuff to see what’s hot nowadays. One head-to-head comparison showed an interesting result, it’s the comparison of JSF and Wicket job opportunities, as seen in the graph JSF is by far the winner. A friend of mine commented on this with “The only people talking about wicket are it’s developers:)”.

I really like working with JSF but I’m not an anti-wicket guy(although I don’t like the fact that I have to do things twice both in html&java code behind). But I gotta ask this question? As developers we have to update ourselves regularly on new stuff but is wicket really worth our time?

jobgraph.png


Items:   1 to 5 of 10   Next »