Creating a sample Java EE 6 Blog Application with JPA, EJB, CDI, JSF and Primefaces on GlassFish
February 8th, 2011 by Micha KopsJava EE 6 is out and it indeed offers an interesting stack of technologies. So in today’s tutorial we are going to build a small sample web application that builds on this stack using Enterprise JavaBeans, Java Persistence API, Bean Validation, CDI and finally Java Server Faces and PrimeFaces.
The application we’re going to develop is a simple blog app that allows us to create new articles, list them and – finally delete them. We’re also covering some additional topics like JSF navigation, i18n, Ajax-enabled components and the deployment on the GlassFish application server.
Contents
- Prerequisites
- Our Technology Stack
- Project Setup using Maven Archetypes
- Entity creation using the Java Persistence API 2 / JSR-317
- Validation using Bean Validation / JSR-303
- The middle tier using Enterprise Java Beans / EJB 3.1 - JSR-318
- Creating the presentation layer using Java Server Faces 2 and PrimeFaces
- Adding JSF Navigation Rules
- GlassFish Configuration
- Deploying and Running the Application
- Download Sources
- Troubleshooting
- Resources
- Additional Articles: Testing with Arquillian
- Article Updates
Prerequisites
We do not need anything exotic for this tutorial .. just a JDK, Maven and a GlassFish. I’ve chosen the last one because of its status as Java EE 6 reference implementation but inbetween JBoss released a new version that supports the Java EE 6 Web Profile so perhaps it is also worth a look …
Our Technology Stack
We’re going to cover a lot of specifications so here is a brief overview of technologies used in the following tutorial:
Build management: Maven, Maven EJB Plugin and others ..
Application Server: GlassFish 3 (running on my Ubuntu machine)
Persistence: Java Persistence API as abstraction layer, TopLink/EclipseLink as persistence provider, JavaDB/Derby as concrete underlying RDBMS
Inversion of Control/Dependency Injection: CDI specs using Weld
Validation: Bean Validation / JSR 303
Presentation Tier: Java Server Faces 2 / Mojarra and PrimeFaces 2.2
Middle Tier: Enterprise Java Beans 3.1
Project Setup using Maven Archetypes
We’re too lazy to create a project skeleton and add dependencies by hand so we’re using an archetype to create our project..
- Create a new Maven project using the webapp-javaee6 (org.codehaus.mojo.archetype:webapp-javaee6) archetype with your favourite IDE and Maven plugin or via console
mvn archetype:generate [INFO] Scanning for projects... [..] 254: remote -> webapp-javaee6 (Archetype for a web application using Java EE 6.) [..] Choose version: 1: 1.0 2: 1.0.1 3: 1.0.2 4: 1.1 5: 1.2 6: 1.3 Choose a number: 6: 6 Define value for property 'groupId': : com.hascode.tutorial.jee6 Define value for property 'artifactId': : jee6-blog-tutorial Define value for property 'version': 1.0-SNAPSHOT: 0.0.1 Define value for property 'package': com.hascode.tutorial.jee6: com.hascode.tutorial.jee6.blog [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
- Add the following dependencies and repositories – your pom.xml should look like this one
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hascode.tutorial.jee6</groupId> <artifactId>jee6-blog-tutorial</artifactId> <version>0.0.1</version> <packaging>war</packaging> <name>hasCode.com Java EE 6 Blog Tutorial</name> <properties> <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>6.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.0.2.GA</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>10.6.1.0</version> </dependency> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <compilerArguments> <endorseddirs>${endorsed.dir}</endorseddirs> </compilerArguments> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.1</version> <executions> <execution> <phase>validate</phase> <goals> <goal>copy</goal> </goals> <configuration> <outputDirectory>${endorsed.dir}</outputDirectory> <silent>true</silent> <artifactItems> <artifactItem> <groupId>javax</groupId> <artifactId>javaee-endorsed-api</artifactId> <version>6.0</version> <type>jar</type> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <configuration> <ejbVersion>3.1</ejbVersion> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> </plugins> <finalName>jee6-blog-tutorial</finalName> </build> <repositories> <repository> <id>maven2-repository.dev.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2</url> </repository> <repository> <id>JBoss repository</id> <url>http://repository.jboss.com/maven2/</url> </repository> <repository> <id>EclipseLink Repo</id> <url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>primefaces-repo</id> <name>Prime Technology Maven Repository</name> <url>http://repository.primefaces.org</url> <layout>default</layout> </repository> </repositories> </project>
- Remove the created index.jsp from src/main/webapp and add the directories for resources, WEB-INF and META-INF
mkdir -p src/main/resources mkdir -p src/main/webapp/WEB-INF mkdir -p src/main/resources/META-INF
- Create an empty file named beans.xml in src/main/webapp/WEB-INF – we need it for CDI .. you’re asking why? Gavin King kindly gives an explaination.
touch src/main/webapp/WEB-INF/beans.xml
Entity creation using the Java Persistence API 2 / JSR-317
We want to save our blog entries in the persistence layer .. what we’re going to store is a title, the author, the date the entry was created and of course some text content.
- First create a new class named BlogEntry in the package com.hascode.tutorial.jee6.blog.entity
package com.hascode.tutorial.jee6.blog.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.PrePersist; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity public class BlogEntry implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; private String title; @Lob private String content; private String author; @Temporal(TemporalType.TIMESTAMP) private Date created = new Date(); @PrePersist private void onCreate() { created = new Date(); } /** * @param id * the id to set */ public void setId(Long id) { this.id = id; } /** * @return the title */ public String getTitle() { return title; } /** * @param title * the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the content */ public String getContent() { return content; } /** * @param content * the content to set */ public void setContent(String content) { this.content = content; } /** * @return the author */ public String getAuthor() { return author; } /** * @param author * the author to set */ public void setAuthor(String author) { this.author = author; } /** * @return the created */ public Date getCreated() { return created; } /** * @param created * the created to set */ public void setCreated(Date created) { this.created = created; } /** * @return the id */ public Long getId() { return id; } }
So what have we done here?
- The minimal set of annotations we need is @Entity and @Id - we have added those to the entity class and to the field id
- We don’t want to set our primary key by hand so we’re adding the @GeneratedValue annotation to our id
- The text from a blog entry might take some space so we’re predicting that with the @LoB annotation
- We want to save the creation date of a blog entry as a timestamp and not a date – that’s why we add @Temporal(TemporalType.TIMESTAMP)
- To set the creation date on our first persist we’re using @PrePersist
Now we need to define a persistence unit ..
- First we create a new xml file named persistence.xml in src/main/resources/META-INF
- We’re using EclipseLink/TopLink as PersistenceProvider
- Because we’re lazy we’re going to use the GlassFish embedded database “__default” via JNDI “jdbc/__default”. SCREENSHOT
- Out persistence unit is named “defaultPersistenceUnit“
- We definitely want container managed transactions/CTM here that’s why we choose JTA as transaction-type
- At last we want EclipseLink to create the tables for our entity so the value for the property eclipselink.ddl-generation is “create-tables“. You might want to change this for another persistence unit for integration tests later.
- Finally the persistence.xml should look like this one
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.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_1_0.xsd"> <persistence-unit name="defaultPersistenceUnit" transaction-type="JTA"> <provider>oracle.toplink.essentials.PersistenceProvider</provider> <jta-data-source>jdbc/__default</jta-data-source> <class>com.hascode.tutorial.jee6.blog.entity.BlogEntry</class> <properties> <property name="eclipselink.ddl-generation" value="create-tables" /> </properties> </persistence-unit> </persistence>
Validation using Bean Validation / JSR-303
Now that we have defined our entities and persistence unit we should add some validation rules not to allow to save invalid blog entries.
For a closer look and more detailed information about bean validation and jsr-303 take a look at my article: “Bean Validation with JSR-303 and Hibernate Validator”
The rules that we’re going to define are ..
- The title must not be null and its length must be between 10 and 100 characters
- The content must not be null and its length must be between 300 and 4000 characters
- The author must not be null and its length must be between 10 and 40 characters
- The creation date, created should lie in the past
- Applying some annotations from the bean validation API like @NotNull, @Size, @Past our BlogEntry’s fields look like this
package com.hascode.tutorial.jee6.blog.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.PrePersist; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; import javax.validation.constraints.Size; @Entity public class BlogEntry implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; @NotNull @Size(min = 10, max = 100) private String title; @Lob @NotNull @Size(min = 300, max = 4000) private String content; @NotNull @Size(min = 10, max = 40) private String author; @Past @Temporal(TemporalType.TIMESTAMP) private Date created = new Date(); @PrePersist private void onCreate() { created = new Date(); } /** * @param id * the id to set */ public void setId(Long id) { this.id = id; } /** * @return the title */ public String getTitle() { return title; } /** * @param title * the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the content */ public String getContent() { return content; } /** * @param content * the content to set */ public void setContent(String content) { this.content = content; } /** * @return the author */ public String getAuthor() { return author; } /** * @param author * the author to set */ public void setAuthor(String author) { this.author = author; } /** * @return the created */ public Date getCreated() { return created; } /** * @param created * the created to set */ public void setCreated(Date created) { this.created = created; } /** * @return the id */ public Long getId() { return id; } }
The middle tier using Enterprise Java Beans / EJB 3.1 – JSR-318
We’re going to use a stateless session bean to provide methods to save, delete and list our blog entry entities. We don’t define any local or remote interfaces to keep it simple here.
- Create a new package named com.hascode.tutorial.jee6.blog.ejb and a class named BlogEntryEJB
package com.hascode.tutorial.jee6.blog.ejb; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import com.hascode.tutorial.jee6.blog.entity.BlogEntry; @Stateless public class BlogEntryEJB { @PersistenceContext(unitName = "defaultPersistenceUnit") private EntityManager em; public BlogEntry saveBlogEntry(BlogEntry blogEntry) { em.persist(blogEntry); return blogEntry; } public List<BlogEntry> findBlogEntries() { final Query query = em.createQuery("SELECT b FROM BlogEntry b ORDER BY b.created DESC"); List<BlogEntry> entries = query.getResultList(); if (entries == null) { entries = new ArrayList<BlogEntry>(); } return entries; } public void deleteBlogEntry(BlogEntry blogEntry) { blogEntry = em.merge(blogEntry); em.remove(blogEntry); } }
- The unit name that we’re using in @PersistenceContext should correspond to the defined named in our persistence.xml
Creating the presentation layer using Java Server Faces 2 and PrimeFaces
First we’re creating some facelets and decorators .. to keep this example simple we’re only creating a view to create new blog entries and a view that lists existing entries.
- First we’re creating a decorator template named _decorator.xhtml in src/main/webapp
- There are three fields in the decorator that may be overridden by our concrete views: the title, the heading and the body:
<!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:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"> <h:head> <title><ui:insert name="title">hasCode.com - Java EE 6 Blog Tutorial</ui:insert></title> <link rel="stylesheet" type="text/css" href="css/style.css" /> </h:head> <h:body> <p:panel> <h:panelGrid columns="2" cellpadding="10"> <img src="image/logo.png" width="100" height="100" alt="hasCode.com logo"/> <h:panelGroup> <h1><ui:insert name="heading">Java EE 6 Tutorial - Blog Application</ui:insert></h1> </h:panelGroup> </h:panelGrid> <ui:insert name="body">Welcome to the tutorial .. you should never see this content ;)</ui:insert> </p:panel> </h:body> </html>
- The ugly logo image is saved in src/main/webapp/image, the cascading stylesheets in src/main/webapp/css - this is my style.css
h1 { font-size: 34px; } .errorMsg { background-color:#D97C7C; color:#A30000; display:block; padding:5px; }
- Now we want to display available blog entries this is my view list.xhtml
<!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:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"> <ui:composition template="/_decorator.xhtml"> <ui:define name="title"> <h:outputText value="hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview" /> </ui:define> <ui:define name="heading"> <h:outputText value="Blog entries overview" /> </ui:define> <ui:define name="body"> <h:form> <h:commandButton title="Create new article" value="Create new article" action="create" /> <br /> <hr /> <br /> <p:panel header="#{blogEntryBean.getBlogEntries().size()} Blog entries available" toggleable="true" closable="true" toggleSpeed="500"> <ui:repeat value="#{blogEntryBean.getBlogEntries()}" var="entry"> <h:panelGrid columns="2" cellpadding="10"> <f:facet name="header"> <h:outputText value="#{entry.title}" /> </f:facet> <h:outputText value="Author: #{entry.author}" /> <h:panelGroup id="pGroup"> <h:outputText value="#{entry.content}" /> <p:contextMenu for="pGroup"> <p:menuitem value="Delete" actionListener="#{blogEntryBean.delete(entry)}" update="@form" /> </p:contextMenu> </h:panelGroup> <f:facet name="footer"> <h:outputText value="Created: #{entry.created}" /> </f:facet> </h:panelGrid> <hr /> </ui:repeat> </p:panel> </h:form> </ui:define> </ui:composition> </html>
- We’re filling the decorator using ui:composition and ui:repeat to iterate over a list of available blog entries
- PrimeFaces gives us nice panels and ajax-delete via context menu, nice is the @form expression that forces the form to update its content
- We should adjust our web.xml in src/main/webapp/WEB-INF/ to load JSF and display list.xhtml per default
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>jee6-blog-tutorial</display-name> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/list.xhtml</welcome-file> </welcome-file-list> </web-app>
- Now we need a ManagedBean to link our views to the middle tier so we’re creating a class named BlogEntryBean in com.hascode.tutorial.jee6.blog.controller
package com.hascode.tutorial.jee6.blog.controller; import java.util.List; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.inject.Named; import com.hascode.tutorial.jee6.blog.ejb.BlogEntryEJB; import com.hascode.tutorial.jee6.blog.entity.BlogEntry; @Named(value = "blogEntryBean") @RequestScoped public class BlogEntryBean { @Inject private BlogEntryEJB blogEntryEJB; private BlogEntry blogEntry = new BlogEntry(); /** * @return the blogEntries */ public List<BlogEntry> getBlogEntries() { return blogEntryEJB.findBlogEntries(); } /** * @return the blogEntry */ public BlogEntry getBlogEntry() { return blogEntry; } /** * @param blogEntry * the blogEntry to set */ public void setBlogEntry(BlogEntry blogEntry) { this.blogEntry = blogEntry; } public String saveBlogEntry() { blogEntryEJB.saveBlogEntry(blogEntry); return "success"; } public void delete(BlogEntry blogEntry) { blogEntryEJB.deleteBlogEntry(blogEntry); } }
- Please note that we’re using CDI for dependency injection here – that means @Named instead of @ManagedBean, @Inject instead of @EJB and javax.enterprise.context.RequestScoped instead of javax.faces.bean.RequestScoped!!
- In the next step we should add some i18n and move our messages and text content to a resource bundle so create a directory src/main/resources/com/hascode/tutorial/jee6/blog and a new file named messages.properties in this directory.
mkdir -p src/main/resources/com/hascode/tutorial/jee6/blog
- Now we’ve got to register this resource bundle – we’re doing this via declaration in the JSF configuration file. Create a new file named faces-config.xml in src/main/webapp/WEB-INF and declare the resource bundle – in this case we’ve registered the bundle for variable named i18n
<?xml version="1.0" encoding="UTF-8"?> <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" 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_2_0.xsd"> <application> <resource-bundle> <base-name>com.hascode.tutorial.jee6.blog.messages</base-name> <var>i18n</var> </resource-bundle> </application> </faces-config>
- Now we’re able to replace our messages via
#{i18n.thekeyfromthebundle}
- Finally out messages.properties looks like this
listTitle=hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview listHeading=Blog entries overview
- Our update facelet list.xhtml now looks like this
<!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:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"> <ui:composition template="/_decorator.xhtml"> <ui:define name="title"> <h:outputText value="#{i18n.listTitle}" /> </ui:define> <ui:define name="heading"> <h:outputText value="#{i18n.listHeading}" /> </ui:define> <ui:define name="body"> <h:form> <h:commandButton title="#{i18n.newArticle}" value="#{i18n.newArticle}" action="create" /> <br /> <hr /> <br /> <p:panel header="#{blogEntryBean.getBlogEntries().size()} #{i18n.amountEntries}" toggleable="true" closable="true" toggleSpeed="500"> <ui:repeat value="#{blogEntryBean.getBlogEntries()}" var="entry"> <h:panelGrid columns="2" cellpadding="10"> <f:facet name="header"> <h:outputText value="#{entry.title}" /> </f:facet> <h:outputText value="#{i18n.author}: #{entry.author}" /> <h:panelGroup id="pGroup"> <h:outputText value="#{entry.content}" /> <p:contextMenu for="pGroup"> <p:menuitem value="#{i18n.delete}" actionListener="#{blogEntryBean.delete(entry)}" update="@form" /> </p:contextMenu> </h:panelGroup> <f:facet name="footer"> <h:outputText value="#{i18n.created}: #{entry.created}" /> </f:facet> </h:panelGrid> <hr /> </ui:repeat> </p:panel> </h:form> </ui:define> </ui:composition> </html>
We could have managed our user actions completely using nice PrimeFaces AJAX-enriched components or JSF’s native AJAX API but to demonstrate JSF’s navigation rules we’re going to define a new view with a form to create a new blog entry. If the blog entry has been successfully saved using this form we want to redirect our user to the entries-list-overview and the URL should change to avoid posting duplicate content by refreshing in the browser.
- First we’re creating the new view reusing our decorator .. add a new template named create.xhtml in src/main/webapp
<!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:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"> <ui:composition template="/_decorator.xhtml"> <ui:define name="title">#{i18n.createTitle}</ui:define> <ui:define name="heading">#{i18n.createHeading}</ui:define> <ui:define name="body"> <h:form> <p:panel id="createPnl" header="#{i18n.newArticle}" toggleable="true" closable="false" toggleSpeed="500" onCloseUpdate="growl" closeSpeed="2000" onToggleUpdate="growl" widgetVar="panel"> <h:panelGrid columns="3" cellpadding="10"> <label>#{i18n.title}</label> <h:inputText label="Title" id="lblTitle" value="#{blogEntryBean.blogEntry.title}" required="true" /> <h:message for="lblTitle" class="errorMsg"/> <label>#{i18n.author}</label> <h:inputText label="Author" id="lblAuthor" value="#{blogEntryBean.blogEntry.author}" required="true" /> <h:message for="lblAuthor" class="errorMsg"/> <label>#{i18n.content}</label> <h:inputTextarea label="Content" id="lblContent" value="#{blogEntryBean.blogEntry.content}" required="true" /> <h:message for="lblContent" class="errorMsg"/> <h:commandButton title="#{i18n.save}" value="#{i18n.save}" action="#{blogEntryBean.saveBlogEntry()}" /> </h:panelGrid> </p:panel> </h:form> </ui:define> </ui:composition> </html>
- We need to update our internationalized messages in our messages.properties
listTitle=hasCode.com - Java EE 6 Blog Tutorial - Blog entries overview listHeading=Blog entries overview newArticle=Create new blog entry amountEntries=Blog entries available author=Author options=Options delete=Delete created=Created createTitle=hasCode.com - Java EE 6 Blog Tutorial - Create a new blog entry createHeading=Create a new blog entry title=Title content=Content save=Save article
- Add navigation rules to your faces-config.xml in src/main/webapp/WEB-INF .. mine now looks like this one
<?xml version="1.0" encoding="UTF-8"?> <faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xi="http://www.w3.org/2001/XInclude" 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_2_0.xsd"> <application> <resource-bundle> <base-name>com.hascode.tutorial.jee6.blog.messages</base-name> <var>i18n</var> </resource-bundle> </application> <navigation-rule> <from-view-id>/list.xhtml</from-view-id> <navigation-case> <from-outcome>create</from-outcome> <to-view-id>/create.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/create.xhtml</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/list.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule> </faces-config>
- The redirect-Tag in the navigation-case forces the a redirect to list.xhtml
GlassFish Configuration
The GlassFish setup is quite easy we simply need a new domain and the embedded database because we’re too lazy to connect or create an external database ..
- Start the GlassFish console via
asadmin
- Create a new domain named blog-domain
asadmin> create-domain blog-domain Enter admin user name [Enter to accept default "admin" / no password]> Using port 4848 for Admin. Using default port 8080 for HTTP Instance. Using default port 7676 for JMS. Using default port 3700 for IIOP. Using default port 8181 for HTTP_SSL. Using default port 3820 for IIOP_SSL. Using default port 3920 for IIOP_MUTUALAUTH. Using default port 8686 for JMX_ADMIN. Using default port 6666 for OSGI_SHELL. Distinguished Name of the self-signed X.509 Server Certificate is: [CN=yourworkstationname,OU=GlassFish,O=Oracle Corporation,L=Santa Clara,ST=California,C=US] No domain initializers found, bypassing customization step Domain blog-domain created. Domain blog-domain admin port is 4848. Domain blog-domain allows admin login as user "admin" with no password. Command create-domain executed successfully.
- Start the created domain
asadmin> start-domain blog-domain Waiting for DAS to start ................................. Started domain: blog-domain Domain location: /somepath/app/glassfishv3/glassfish/domains/blog-domain Log file: /somepath/app/glassfishv3/glassfish/domains/blog-domain/logs/server.log Admin port for the domain: 4848 Command start-domain executed successfully.
- Start the embedded Derby/JavaDB database
asadmin> start-database Starting database in Network Server mode on host 0.0.0.0 and port 1527. [..] ------------------------------------------------------ Starting database in the background. Log redirected to /somepath/derby.log. Command start-database executed successfully.
- Visit the administration console in your browser at http://localhost:4848/ and enjoy ;)
Deploying and Running the Application
- First build the war file for deployment using
mvn package
- Ensure that your GlassFish server is running, the database is started and the domain “blog-domain” is created and started
- Log into the GlassFish administration console at http://localhost:4848/ with login “admin” and empty password if you haven’t defined one in the domain creation process
- Click on “Applications” and deploy the application via file upload as shown as in the following screenshots
- Now click on “Launch” and visit your application at this location: http://localhost:8080/blog-tutorial
View as screencast on YouTube
Download Sources
The sources for this tutorial are available on my Bitbucket repository .. download it from here or check it out using
hg clone https://hascode@bitbucket.org/hascode/javaee6-blog-tutorial
Troubleshooting
- “Exception while preparing the app : org.hibernate.AnnotationException: No identifier missing @Id attribute“: You’ve forgotten to specify an identifying property for your entity class .. e.g.: @Id private Long id;
- “Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLNonTransientConnectionException: No current connection. java.sql.SQLNonTransientConnectionException: No current connection. org.apache.derby.client.am.SqlException: No current connection.“: In this tutorial we’re lazy and rely on GlassFish’s embedded database. To use this database it must be started first as this
asadmin asadmin> start-database Starting database in Network Server mode on host 0.0.0.0 and port 1527.
- “[#|2011-01-16T17:47:47.364+0100|WARNING|glassfish3.0.1|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=30;_ThreadName=Thread-1;|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception javax.el.PropertyNotFoundException or: CDI does not work somehow“: You need to put an empty text file named beans.xml in src/main/webapp/WEB-INF – strange but necessary ;) For more information take a look at Gavin King’s blog article: “Why is beans.xml required in CDI?“
- “Caused by: java.lang.IllegalArgumentException: Entity must be managed to call remove: com.hascode.tutorial.jee6.blog.entity.BlogEntry@184340e, try merging the detached and try the remove again. at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.performRemove(UnitOfWorkImpl.java:3539)“: This is the standard detached object problem .. in JPA there are four possible object states .. new, removed, managed and of course detached .. the last one has a persistent identity that no longer is associated with a persistence context. EntityManager’s merge method is what helps you to “reattach” the bean .. look at this sample code
public void theMethod(XXX entityBean) { entityBean = em.merge(entityBean); em.remove(entityBean); }
- “PrimeFaces is not defined“: There was an issue with some menu components in PrimeFaces 2.2.RC1, Cagatay Civici has already fixed this one in version 2.2.RC2 and above.
- “Duplicate menuitem in contextmenu“: Again Cagatay Civici saved the day and fixed this issue, update to version 2.2-SNAPSHOT or above.
- “Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.1:copy (execution: default, phase: validate)” – It’s the m2eclipse plugin .. why does this error occur? They’re explaining it in this article .. for now add the following code to your pom.xml and update your project configuration
<pluginManagement> <plugins> <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <versionRange>[2.1,)</versionRange> <goals> <goal>copy</goal> </goals> </pluginExecutionFilter> <action> <ignore></ignore> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement>
Resources
- GlassFish Website
- PrimeFaces Website
- JSR-318: Enterprise JavaBeans™ 3.1
- JSR-317: Java™ Persistence 2.0
- JSR-303: Bean Validation
- JSR-316: Java™ Platform, Enterprise Edition 6 (Java EE 6)
- Emmanuelle Bernard: JSR 303 Bean Validation
- JBoss Weld Documentation
- Antonio Goncalves: Bootstrapping CDI in several environments
- Gavin King: Why is beans.xml required in CDI?
- Cagatay Civici’s Weblog
Additional Articles: Testing with Arquillian
If you’re interested in testing your Java EE application , please feel free to have a look at the following tutorials of mine covering the Arquillian framework:
- Arquillian Tutorial: Writing Java EE 6 Integration Tests and more..
- Arquillian Transaction Extension: Transaction Rollback for your Java EE Integration Tests
- Java EE: Setting up and Testing Form-Based JDBC Authentication with Arquillian and Maven
- Marrying Java EE and BDD with Cucumber, Arquillian and Cukespace
Article Updates
- 2018-06-01: Embedded YouTube video removed (GDPR/DSGVO).
- 2015-03-21: Links to my Arquillian articles added, formatting fixed.
Tags: bean, bean validation, cdi, eclipselink, ejb, example, glassfish, hibernate, IoC, java ee, javaee, jee, jndi, jsf, jsr-303, jsr-316, jsr-317, jsr-318, maven, mojarra, primefaces, toplink, tutorial, validator, weld
February 12th, 2011 at 3:00 pm
Simple, to the point and complete.
Good job on the tutorial :)
February 12th, 2011 at 4:42 pm
Excellent tutorial. I followed along building the application in Eclipse with GlassFish v3 as the server and everything worked perfectly.
Just a couple of question…
1. Is EclipseLink/TopLink built-in to GlassFish v3? I don’t see it listed in the pom’s dependencies.
2. What’s the purpose of endorseddirs in your pom.xml? Is that needed to build this application? I’ve not seen endorseddirs before in Java EE 6 app’s pom.xml.
February 12th, 2011 at 10:52 pm
Thanks for your post :)
1) EclipseLink is GlassFish’s default persistence provider, earlier versions (<3.0.1) TopLink Essentials (http://download.oracle.com/docs/cd/E19798-01/821-1762/gjizi/index.html)
2) You don't need the endorsed dirs to build this tutorial .. basically the maven settings above add this function: a) the maven dependency plugin copies javaee-endorsed-api-6.0.jar to the directory target/endorsed b) the compiler adds this directory as endorseddir to override/extend jdk functions (http://download.oracle.com/javase/6/docs/technotes/guides/standards/)
February 13th, 2011 at 1:57 am
Thank you for the tutorial.
I’ve just completed and it works.
I personally learned a lot from it. I still need to review some concepts, but thank you for a complete tutorial.
February 15th, 2011 at 10:08 am
PrimeFaces p:contextMenu doesn’t work for me (nothing is shown)
February 15th, 2011 at 10:12 am
Sorry, It works fine, I forgot it works by clicking the right button.
February 15th, 2011 at 10:29 am
I’m glad to hear that :)
March 3rd, 2011 at 2:15 pm
[...] Imagem retirada de: http://www.hascode.com/2011/02/creating-a-sample-java-ee-6-blog-application-with-jpa-ejb-cdi-jsf-and... [...]
March 13th, 2011 at 2:09 pm
Wonderful, no-nonsense tutorial, Micha. Thanks. Your tutorial is the best so far on the Internet.
Also, I’m using Apache OpenJPA 2.1.0 and I have included this file “openjpa-all-2.1.0.jar” in my Eclipse project but the following imported libraries cannot be resolved:
1) javax.ejb.Stateless;
2) import javax.enterprise.context.RequestScoped;
3) import javax.inject.Inject;
4) import javax.inject.Named;
Is this an issue only with OpenJPA and not EclipseLink? What can I do to resolve the missing libraries? Please help.
March 13th, 2011 at 5:24 pm
Those dependencies are all covered by the artifact javaee-web-api:
However If you’re trying to build without Maven, just download the Jar from the Maven repository and add it as an external jar to your project:
http://download.java.net/maven/2/javax/javaee-web-api/6.0/javaee-web-api-6.0.jar
March 13th, 2011 at 6:41 pm
Thanks, Micha. Much appreciated. You save me a couple of hours floundering on Google trying to find the right library for the unresolved classes.
Also, can I do something like this if I pass a parameter to a query in the EJB class:
final Query query = em.createNamedQuery(“findBlogEntry”).setParameter(“blogId”, blogid).getResultList();
Where findBlogEntry is defined in the Entity class as:
@Entity
@NamedQuery({
@NamedQuery(name = “findBlogEntry”, query = “SELECT b.* FROM BlogEntry b WHERE b.blogId = :id”});
Sorry for asking a dumb question but I find the EJB + JPA stuff very hard to understand and my understanding is further complicated by coming across something like this:
http://soadev.blogspot.com/2010/02/dynamic-tree-menu-based-on-user-roles.html
Is this another way one can configure EJB + Entity for CRUD operation? Or, is this a BAD (and possibly, not recommended) way of doing it? Can you please confirm. Thank you.
March 13th, 2011 at 7:09 pm
You should be able to use named or enumerated parameters on JPA entity’s named queries + queries .. perhaps this other article of mine is of help for you: “Object-relational Mapping using Java Persistence API / JPA 2“
March 14th, 2011 at 2:25 am
Thanks, Micha. That article make sense and it answers my question above about NameQuery/NameQueries defined in Entity class.
March 18th, 2011 at 2:55 pm
Tried the above codes – everything good – except that this EL expression blogEntryBean.getBlogEntries() in list.xhtml will be executed 6 times for each phase of the JSF lifecycle.
March 19th, 2011 at 5:16 am
The above demo works great except that blogEntryBean.getBlogEntries() in list.xhtml will be called 6 times for each phase of the JSF lifecycle.
March 19th, 2011 at 1:15 pm
I’m not sure why the method is called six times in your environment – in mine it is called two times .. one time for the display of the number of available entries and one time for the iteration loop (this is of course no ideal layout but sufficient for a quick tutorial :)
March 19th, 2011 at 1:56 pm
Yeah, I’m not sure either!
Debugging the codes revealed that the method got called 6 times – which to my knowledge – corresponded to the phases of the JSF lifecycle. I tried both blogEntryBean.getBlogEntries() and blogEntryBean.blogEntries and I got the same result.
Anyway, I’ll investigate a bit more and see what I can find…
March 23rd, 2011 at 12:22 pm
Hi from Russia! Thanks for great tutorial!
But one question, because i cant find it by google. How can i use JSF with JAX-WS client?
i want to display a table by jsf. In JAX-ws class i have a method “findall” and “find”, what returns all data and other one entry. Please tell me in common words what i must do. Thanks!!!
March 23rd, 2011 at 7:09 pm
You could pass the list of items received to a backing bean and then render it in a table using ui:repeat or a data table component of your choice .. PrimeFaces’ DataTable components has some nice features and is definitely worth a look
March 24th, 2011 at 4:00 am
Nice tutorial, however some missing points make it hard to adapt for a real application.
First, you should add a count() method to BlogEntryEJB and BlogEntryBean.
Using blogEntryBean.getBlogEntries().size() will read ALL blog entries from database, which is not what you want.
What could make a difference from all other JSF CRUD tutorials is adding pagination support on the server side. While this is one of the most important aspect of a CRUD application, it can be quite a challenger to achieve in JSF application without using @SessionScoped beans – using flash scope parameters, page parameters and post-redirect-get.
Even NetBeans CRUD page generation wizard is not usable.
Otherwise, nice explanations and screenshots!
April 6th, 2011 at 7:26 am
Nice tutorial, however i got the folowing exception:
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:’prePersist’. Please refer to embedded ConstraintViolations for details.
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.prePersist(BeanValidationListener.java:62)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:698)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:641)
at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:200)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectClone(UnitOfWorkImpl.java:4216)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNotRegisteredNewObjectForPersist(UnitOfWorkImpl.java:4193)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.registerNotRegisteredNewObjectForPersist(RepeatableWriteUnitOfWork.java:493)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4135)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:269)
at com.hascode.tutorial.jee6.blog.ejb.BlogEntryEJB.saveBlogEntry(BlogEntryEJB.java:19)
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.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5367)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:46)
at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:862)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
at sun.reflect.GeneratedMethodAccessor110.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:862)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:801)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:371)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5339)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5327)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
… 62 more
June 14th, 2011 at 4:51 pm
> While this is one of the most important aspect of a CRUD application, it can be quite a challenger to achieve in JSF application without using @SessionScoped beans – using flash scope parameters, page parameters and post-redirect-get.
@ViewScoped is the most natural fit here.
August 27th, 2011 at 11:37 am
a very good intro indeed, you are a star
October 23rd, 2011 at 9:28 am
Hi Micha,
Thanks alot for this quick start. I followed all steps but my eclipse Indigo is giving me error as -
Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.1:copy (execution: default, phase: validate)
where as mvn clean install gave me below error -
[ERROR] Failed to execute goal on project jee6-blog-tutorial: Could not resolve dependencies for project com.hascode.tutorial.jee6:jee6-blog
-tutorial:war:0.0.1: Failed to collect dependencies for [javax:javaee-web-api:jar:6.0 (compile), javax.validation:validation-api:jar:1.0.0.G
A (provided), org.hibernate:hibernate-validator:jar:4.0.2.GA (compile), junit:junit:jar:4.8.2 (test), org.apache.derby:derby:jar:10.6.1.0 (c
ompile), org.primefaces:primefaces:jar:2.2 (compile), javax.faces:jsf-api:jar:2.0 (provided)]: Failed to read artifact descriptor for org.pr
imefaces:primefaces:jar:2.2: Could not transfer artifact org.primefaces:primefaces:pom:2.2 from/to JBoss repository (http://repository.jboss
.com/maven2/): Access denied to: http://repository.jboss.com/maven2/org/primefaces/primefaces/2.2/primefaces-2.2.pom -> [Help 1]
October 23rd, 2011 at 10:43 am
Hi Micha,
Second problem is fixed.
The problem was – Primefaces has changed its repo –
http://blog.primefaces.org/?p=1429
Pls update this tutorial.
But still problem 1 regarding Plugin execution, persist.
October 23rd, 2011 at 11:27 am
Hi Amar,
thanks for your note – I have updated the location of the primefaces maven repo to the new address.
The lifecycle error is one of the “features” of the new Sonatype m2eclipse Plugin – they’ve written this article to explain why this problem exists.
One workaround is to make the m2eclipse plugin ignore the unknown lifecycle by adding the following snippet to your pom.xml’s build element (m2eclipse offers this solution if you’re opening the pom.xml in the pom editor):
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[2.1,)
</versionRange>
<goals>
<goal>copy</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Afterwards you should be able to compile the application without any problems ..
October 30th, 2011 at 12:53 pm
Thanks Micha the plugin problem is fixed.
The tutorial helped me alot to kick start me.
One thing would be really nice if you could help me -
Here you explained to use external glassfish. Is there a way to use the glassfish from eclipse itself and it does every thing for me. With this it will re-deploy all changes immediately.
October 30th, 2011 at 5:47 pm
Hi Micha, One more thing, I am not able to download sources for javax javaee-web-api 6.0?
October 30th, 2011 at 5:58 pm
One way is to use the GlassFish Maven Plugin as described in this article or to make convert your project to a facet project, add the ejb facet, add a glassfish server and use run on server
October 30th, 2011 at 6:01 pm
isn’t it present on http://download.java.net/maven/2/javax/javaee-web-api/6.0/ ? :)
October 30th, 2011 at 7:51 pm
Hi Micha,
No the sources are not present there.
October 30th, 2011 at 9:50 pm
ah the sources .. I havent found a repository for this one yet so a possible (annoying) workaround is to download the sources from here and run something like this
mvn install:install-file -Dfile=javadoc-6.0.1.jar -DgroupId=javax -DartifactId=javaee-web-api -Dversion=6.0 -Dpackaging=jar -Dclassifier=javadoc
.. the project might be re-imported afterwards depending on the eclipse/maven plugin used ..There’s an issue regarding this problem (open since October 2010) .. you might want to vote on this one :) #GLASSFISH-11389
February 4th, 2012 at 4:34 pm
Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: javax.servlet.ServletException: com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class org.jboss.weld.servlet.WeldListener. Please see server.log for more details.
April 17th, 2012 at 7:53 pm
hi, awsome tutorial for a jee6 starter.
Almost got it working, the only problem, it’s that after pressing save button, get this:
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:’prePersist’. Please refer to embedded ConstraintViolations for details.
After searching a lot, i couldn’t solve it. if you got any idea i’ll really apreciate that.
late ;D
April 17th, 2012 at 8:43 pm
thanks! do you have some more information – e.g. a more detailed stack trace? have you modified the code from the tutorial somehow .. e.g. mixed @NotNull and @Id or something like that? You might try to catch the exception and call getConstraintViolations() on it to find out which constraints were violated.
I’ve tested the tutorial code against the latest GlassFish version just to be sure it works.
April 18th, 2012 at 9:31 pm
sorry about the stack trace, just a noob in glassfish, that’s why i just put that :p
about annotations: i changed stuff but only packages, and i18n stuff. not touched the entity anotations.
i followed your advice and catched the exception, and got a surprise…
the values of the object where null. almost all of them, except for the time stamp.
going backwards, found that the values are never getting in the JSF bean.
So when it arrives to the ejb, is empty.
still trying to figure out what can be that make that behavior. guess i’m missing something about the @Named stuff. ( i had put the empty beans.xml )
when its solved i’ll let you know ;D
thnx for the help.
April 18th, 2012 at 10:10 pm
nevermind. my mistake there was that had imported the wrong annotation.
( i’ve done the project step by step, without donwloading, thats why i have some mistakes about imports.i guess the eclipse import and not paying much attention on that )
conclusion:
@named > @request ( the enterprise context request, not the faces context).
after that i got an error on the @past, cannot solve it so removing it it worked fine.
thnx again for such a great introduction.
April 19th, 2012 at 8:37 am
I’m glad to hear that it worked for you – and thanks for keeping me updated :)
April 19th, 2012 at 4:43 pm
in case someone wants to update this projecto to last version of primefaces (3.2 nowadays )
when creating the xhtml, in the html tag, put this:
xmlns:p=”http://primefaces.org/ui”
instead of
xmlns:p=”http://primefaces.prime.com.tr/ui”
may be updating this tutorial will be nice :).
( and may be add a DB server, not embebed ( mysql or something. )
late ;D
April 19th, 2012 at 7:18 pm
thanks for mentioning! in my latest tutorials (primefaces mobile etc ..) I’m already using the new namespace .. I could update the tutorial to use the latest versions of the major frameworks used one day indeed
May 16th, 2012 at 11:11 pm
Great. This is a very informative tutorial. I do have one question however. I have noticed many tutorials where they use dependency injection to inject an entity (BlogEntry) into the controller/backing bean. Does this violate separation of concerns? Is it just the responsibility of the programmer to use the entity in the controller in a way that does not violate separation of concerns or am I just totally confused. Thanks.
May 23rd, 2012 at 1:13 pm
Hi micha
i have a problem and i’m tired to resolve it
help plz !!
when i try to deploy blog-tutorial on glassfish server
i have this error :
StandardWrapperValve[FacesServlet]: PWC1406: Servlet.service() for servlet FacesServlet threw exception java.lang.ClassNotFoundException: org.apache.commons.io.output.DeferredFileOutputStream at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at org.apache.commons.fileupload.DefaultFileItemFactory.createItem(DefaultFileItemFactory.java:103) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:358) at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:310) at com.sun.webui.jsf.util.UploadFilter.doFilter(UploadFilter.java:176) at
if you have any idea
Thanks
May 23rd, 2012 at 5:52 pm
Hi, sorry to hear that .. which glassfish version are you using here? you’re just building the blog application with maven, you’re uploading it in the glassfish web adminstration panel as a web application and this exception is thrown?
May 24th, 2012 at 9:37 am
yes this is what’s happened
i’m using glassfish-3.1.2, i verified all my sources compared with your code as well, everything is Ok
May 24th, 2012 at 10:02 pm
i have a problem
after execute my project
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException
root cause
javax.ejb.EJBException
root cause
java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName defaultPersistenceUnit
May 25th, 2012 at 5:10 am
Hi, is this persistence unit defined in your persistence.xml? and does the jta datasource named “jdbc/__default” exist on your GlassFish configuration?
May 25th, 2012 at 10:45 pm
hi,micha
jdbc/__default exist on my glassFish configuration
but i didn’t understand what is the problem exactly
May 26th, 2012 at 7:24 pm
hi hamza,
did you start the embedded database via “asadmin” and “start-database”?
May 26th, 2012 at 7:40 pm
Youssef: works for me on gf 3.1.2 .. your problem sounds like a gf problem for me .. any special configuration here?
May 27th, 2012 at 9:51 am
Erreur lors du déploiement : Exception while preparing the app : Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Erreur lors de l’allocation d’une connexion. Cause : Connection could not be allocated because: java.net.ConnectException : l’erreur lors de la connexion au serveur localhost sur le port 1527 a émis le message Connection refused: connect. Error Code: 0. Pour plus d’informations, consultez le fichier server.log.
May 27th, 2012 at 11:55 am
hi micha
i start the embedded database and i add the jar toplink in domaine/lib/ext in glassfish …
but i have another exception after execution this project
Exception while preparing the app : Exception [EclipseLink-4002] (Eclipse Persistence Services – 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.SQLException: Erreur lors de l’allocation d’une connexion. Cause : Connection could not be allocated because: java.net.ConnectException : l’erreur lors de la connexion au serveur localhost sur le port 1527 a émis le message Connection refused: connect.
i need helps
thanks
May 27th, 2012 at 1:57 pm
seems like you’re not able to connect to the database .. any hint in your database logs in /path/to/glassfish3-installation/glassfish/databases/derby.log? are you able to directly connect to the derby database using ij or another tool? is there something in your environment that blocks a connection – e.g. firewall or stuff like that?
May 29th, 2012 at 10:24 am
Hi all,
I have arrived to deploy the example and i’ts work fine, so i’m using JBOSS AS7 for this…
Otherwise, i have another issue when i create blog, it concerne annotation @Past
exception :
avax.validation.ConstraintViolationException: Validation failed for classes [fr.rsi.foundation.tutoriel.jee6.blog.entity.BlogEntry] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must be in the past', propertyPath=created, rootBeanClass=class fr.rsi.foundation.tutoriel.jee6.blog.entity.BlogEntry, messageTemplate='{javax.validation.constraints.Past.message}'}
]
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159)
So, i don’t know why for the first time i created an article, i didn’t have this error !
I think, the date created through “@PrePersist” when the Entity is loaded & the local date used when the entityManager try to persist the object are equivalent. but if it’s about a datetime it should have some difference of seconds
any idea ?
July 9th, 2012 at 11:38 pm
Great tutorial. One question. You have shown how to perform CRD of CRUD. Can you show us how to do updates using JSF 2 + JPA?
Thanks,
Joseph
May 3rd, 2013 at 4:05 pm
i have try the tutorial with:
glassfish 3.1.2.2
jsf mojarra
primefaces 3.4
but into the create.xhtnl the it is not faound .
you can helop me?
the ajax event it is changed form primefaces 2.2
.
help me
September 3rd, 2013 at 3:11 pm
Great! works fine on Glassfish 3.1.2.2! I’m gonna integrate it as a blog in my webapp , which works with primefaces already.
September 8th, 2013 at 1:02 am
Great job man! Fantastic entry to refresh ideas.
Thanks!
Pablo
December 6th, 2013 at 1:01 pm
Hello i did every step like you but i get an error
The module has not been deployed.
See the server log for details.
BUILD FAILED (total time: 1 second)
December 6th, 2013 at 8:54 pm
Hi,
could you post some more details about the error – e.g. an excerpt from your server.log?
May 19th, 2014 at 2:55 pm
Hi,
I need ur help. when i clicked on the “save article”, i had this error:
javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
May 19th, 2014 at 4:02 pm
Hi Dalun,
could you please post the complete stack trace?
May 20th, 2014 at 7:21 am
hi,
thank you, u can find it below:
javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:115)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:95)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:232)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:32)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165)
at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:173)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72)
at com.admin.data.BlogEntryEJB$$$view4.saveBlogEntry(Unknown Source)
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.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260)
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:111)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
at com.admin.data.BlogEntryEJB$Proxy$_$$_Weld$Proxy$.saveBlogEntry(BlogEntryEJB$Proxy$_$$_Weld$Proxy$.java)
at com.admin.controller.BlogEntryBean.saveBlogEntry(BlogEntryBean.java:34)
at com.admin.controller.BlogEntryBean$Proxy$_$$_WeldClientProxy.saveBlogEntry(BlogEntryBean$Proxy$_$$_WeldClientProxy.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
… 25 more
Caused by: javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92)
… 70 more
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295)
at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1481)
at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109)
at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53)
at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165)
… 73 more
Caused by: org.hibernate.exception.GenericJDBCException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:52)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy71.setClob(Unknown Source)
at org.hibernate.type.descriptor.sql.ClobTypeDescriptor$2$1.doBind(ClobTypeDescriptor.java:69)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2593)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2846)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104)
… 79 more
Caused by: org.postgresql.util.PSQLException: Les Large Objects ne devraient pas être utilisés en mode auto-commit.
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:301)
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:288)
at org.postgresql.jdbc2.AbstractJdbc2Statement.setClob(AbstractJdbc2Statement.java:3180)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.setClob(WrappedPreparedStatement.java:1102)
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.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
May 20th, 2014 at 7:25 am
i’m using JBoss as 7 server and maven3.
May 20th, 2014 at 9:17 am
its works well now! ijust removed @Lob in my entity class. thanks again!
May 20th, 2014 at 5:39 pm
I’m glad that it worked out for you – and thanks a lot for keeping me updated! :)
June 11th, 2014 at 11:29 am
I was using your tutorial to create my own PrimeFaces application (jboss 7, Eclipse) and I had some problems with components that were not rendered until I substituted xmlns:p=”http://primefaces.prime.com.tr/ui” with xmlns:p=”http://primefaces.org/ui”. Eclipse also started autocompleting the tags after the substitution.
June 11th, 2014 at 7:25 pm
Hi,
thanks for your remark! The namespace has changed a few years ago and I’ve not updated all of my primefaces tutorials yet.
Tutorial updated! :)
Cheers,
Micha
August 27th, 2014 at 8:41 am
Hello Micha,
Thank you so much for this very clear article.
i followed all steps, but when i lunch it i have this problem :
1/ when i lunch it from the glassfish editor, it gaves me this :
“”
If the server or listener is not running, the link may not work. In this event, check the status of the server instance. After launching the web application, use the browser’s Back button to return to this screen.”"
2/ and when i tried to run it on server (run th create.xhtml page) i had this:
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Can’t find bundle for base name /webapp-javaee6/src/blog/messages.properties, locale fr_FR
root cause
java.util.MissingResourceException: Can’t find bundle for base name /webapp-javaee6/src/blog/messages.properties, locale fr_FR
The server encountered an internal error () that prevented it from fulfilling this request.
can you help me with this please.
Thank you so much.
Nadjah :)
August 27th, 2014 at 3:15 pm
hello Micha,
by chance i found the problem and i fixed it.
i have another problem, the famous HTTP STATUS 404 => the requested resource in not available.
i don’t know what to do, and i’m stuck, so can you please help me .
thank you!!
nadjah!
August 27th, 2014 at 4:23 pm
Hi Nadjah,
I suppose you’ve added a property-file for french locale? :)
To reproduce your problem: Did you create your own Java EE application in a similar way as in the tutorial? Or did you download the sources, built the project using Maven, configured the GlassFish and having deployed the war file you’re not able to open the application in your browser?
Best wishes
Micha
August 28th, 2014 at 8:40 am
hi Micha,
thank you for the answer :)
=>yes, i added a property file for french local. (/webapp-javaee6/src/blog/messagesBundle-fr-FR.properties) (is the path right or not??)
=>all my xhtml pages (create, list and decorator) are in the web content.
i didn’t create the project on maven commadn,on eclipse i started by creating a dynamic project than i convert it to a maven project, after that i added the dependacies, than i deployed it on the glassfish, after creating a pool connexion and a data source. i checked every thing in the properties of the project and it seems that everything is ok.
=> i made some changes and now, i got this probleme :
java.util.MissingResourceException: Can’t find bundle for base name webapp-javaee6.src.blog.messagesBundle-fr-FR.properties, locale fr_FR
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:1028)
at com.sun.faces.application.ApplicationResourceBundle.getResourceBundle(ApplicationResourceBundle.java:124)
at com.sun.faces.application.ApplicationAssociate.getResourceBundle(ApplicationAssociate.java:608)
at com.sun.faces.application.ApplicationImpl.getResourceBundle(ApplicationImpl.java:700)
at javax.faces.application.ApplicationWrapper.getResourceBundle(ApplicationWrapper.java:526)
at com.sun.faces.el.FacesResourceBundleELResolver.getValue(FacesResourceBundleELResolver.java:83)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:103)
at com.sun.el.parser.AstValue.getValue(AstValue.java:179)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:169)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:744)
August 28th, 2014 at 11:12 am
Hi Nadjah,
you may specify the i18n settings for JSF in your faces-config like this:
<application>
<resource-bundle>
<base-name>yourbundlebasename</base-name>
<var>msg</var>
</resource-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
</locale-config>
</application>
For a comparison: This is the location of the resource-bundle properties file from my tutorial when I’m analyzing the generated war file:
Hi Nadjah,
you may specify the i18n settings for JSF in your faces-config like this:
<application>
<resource-bundle>
<base-name>yourbundlebasename</base-name>
<var>msg</var>
</resource-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
</locale-config>
</application>
For a comparison: This is the location of the resource-bundle properties file from my tutorial when I'm analyzing the generated war file:
August 28th, 2014 at 1:02 pm
hello Micha,
i finally found the solution, you were right concerning the faces-config, and the problem was in my web.xml
the only thing that i found realy bizzare is that, when i lunch the project from glassfish, i don’t have directly the create.xhtml page, i have to clic on a link http://name-pc:8080/create.xhtml, and then i have the page!!!
thank you for your help and your time.
nadjah :)
August 28th, 2014 at 2:38 pm
Hi Nadjah,
I’m glad to hear it’s working for you now. If you’d like to specify a view as start-page, you may do so by adding the following lines to your web.xml:
<welcome-file-list>
<welcome-file>/create.html</welcome-file>
</welcome-file-list>
August 28th, 2014 at 3:05 pm
hello Micha,
i realy appreciate the fact that you answer all my question, i have this last one (i sorry :().
earlier, you told me to change my faces-confi with this :
yourbundlebasename
msg
en
fr
and it worked.the question is:
do i have to change in the create, list.xhtml pages the #i18n with msg??? when i try to do this it doesn’t work ?????
=> when i lunch the page i have the structure as in the video, but no title, and sub titles like (author, content). what can cause this problem.
thank you so much for your help.
PS: i’m not tht good in english, i’m doing my best :)
nadjah
September 3rd, 2014 at 5:50 pm
Hi Nadjah,
et moi, je ne sais pas bien parler français :)
You’re right indeed that you need to modify the variable name – this is the faces-config.xml excerpt from my application (using i18n as variable name):
<application>
<resource-bundle>
<base-name>com.hascode.tutorial.jee6.blog.messages</base-name>
<var>i18n</var>
</resource-bundle>
</application>
If you can’t resolve the resouce bundle, please verify your war-file if it contains the properties file in the right place – as described above and with the base-name com.hascode.tutorial.jee6.blog.messages, my war file contains a file named messages.properties in WEB-INF/classes/com.hascode.tutorial.jee6.blog.
February 20th, 2015 at 3:54 pm
Can never thank you enough. Thanks.
February 21st, 2015 at 1:58 pm
You’re welcome!
May 22nd, 2015 at 11:51 am
Hi Micha,
Thank you for such a good example for the beginners. I have developed a multi module maven project based on your sample and now i am trying to add the logging for it, could you please try to tell me how to do it as i am unable to understand where to configure the properties file and so on.
One more doubt in the existing project is that if i wanted to use the derby out side of the glass fish how should i do it.
Thanks & Regards
Subhash Reddy P
May 25th, 2015 at 9:15 am
Hi,
if you’d like to use an external database, simply configure it in the application container configuration by adding a new JDBC connection pool exporting a JNDI name and use this reference in your persistence.xml.
For the logging – do you use the juli logger here?
February 21st, 2016 at 8:43 am
Dear sir/madam,
Thank you for your sample but i have an error when full out the create.xml and run the action
the blogEntry is null and can not save in the database please help me.
February 21st, 2016 at 8:51 am
Dear all,
Thank you for the example but when i fill out the create.xml form and send for save the blogEntry is null and could not save in the database.
February 22nd, 2016 at 7:57 am
i can not create new artile in the create page some body can help me.when i send the argument th blogEntry is null.
February 22nd, 2016 at 8:02 am
Hi Morteza,
are you using the same setup as in this article? Any exception/stracktrace logged?
February 22nd, 2016 at 11:03 am
yes,when i fill out the create form and send the data to the bean the blogEntry is null.