Bug in seam-gen (Seam 2.1.2.CR2) for GlassFish EAR Projects?
cdunphy May 29, 2009 12:27 AMI started a really simple seam-gen project with GlassFish 2.1 and MySQL using seam 2.1.2.CR2 on an Ubuntu workstation. There is one Entity class:
package rcd.hello.model; import javax.persistence.*; @Entity public class User { private long id; private String username; private String password; @Id @GeneratedValue public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
I ran seam setup, seam create-project. Here is my seam-gen.properties file:
#Generated by seam setup #Thu May 28 15:52:23 MDT 2009 hibernate.connection.password=hello workspace.home=/home/cdunphy/projects hibernate.connection.dataSource_class=com.mysql.jdbc.jdbc2.optional.MysqlDataSource model.package=rcd.hello.model hibernate.default_catalog=hello driver.jar=/home/cdunphy/mysql-connector-java-5.1.7/mysql-connector-java-5.1.7-bin.jar action.package=rcd.hello.action test.package=rcd.hello.test database.type=mysql richfaces.skin=blueSky glassfish.domain=domain1 hibernate.default_schema.null= database.drop=n project.name=hello hibernate.connection.username=hello glassfish.home=/home/cdunphy/glassfish hibernate.connection.driver_class=com.mysql.jdbc.Driver hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider jboss.domain=default project.type=ear icefaces.home= database.exists=y jboss.home=/home/cdunphy/jboss/jboss-5.1.0.GA driver.license.jar= hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.connection.url=jdbc\:mysql\://localhost\:3306/hello icefaces=n
I ran seam generate-ui to create a view based on the one entity class that belongs to the project. So far so good. I ran ant gf-prepare, and I made the following changes to the seam-gen project (as per the glassfish-readme.txt file):
/resources/WEB-INF/web.xml:
<ejb-local-ref> <ejb-ref-name>hello/AuthenticatorBean/local</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home/> <local>rcd.hello.action.Authenticator</local> </ejb-local-ref> <!-- Add entries for each EJB session bean which is also a Seam component (not required on JBoss AS) --> <persistence-unit-ref> <persistence-unit-ref-name>hello/pu</persistence-unit-ref-name> <!-- The relative reference doesn't work on GlassFish. Instead, set the <persistence-unit-name> to "hello", package persistence.xml in the WAR, and add a <jar-file> element in persistence.xml with value "../../hello.jar". --> <persistence-unit-name>hello</persistence-unit-name> </persistence-unit-ref>
/resources/META-INF/persistence-dev.xml:
<?xml version="1.0" encoding="UTF-8"?> <!-- Persistence deployment descriptor for dev profile --> <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="hello"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>helloDatasource</jta-data-source> <!-- The <jar-file> element is necessary if you put the persistence.xml in the WAR and the classes in the JAR --> <!-- <jar-file>../../vehicles.jar</jar-file> --> <jar-file>../../hello.jar</jar-file> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <property name="hibernate.default_catalog" value="hello"/> <property name="jboss.entity.manager.factory.jndi.name" value="java:/helloEntityManagerFactory"/> </properties> </persistence-unit> </persistence>
Ok, so far its great. I can run gf-explode and the project is deployed to GlassFish no problem. I can use the default authenticator session component to login if I supply the admin username and the blank password.
Here is where the problems start. First I add a username/password to the database. Then if I change AuthenticatorBean to do this:
package rcd.hello.action; import javax.ejb.Stateless; @Stateless @Name("authenticator") public class AuthenticatorBean implements Authenticator { @Logger private Log log; @In EntityManager entityManager; @In Identity identity; @In Credentials credentials; public boolean authenticate() { log.info("authenticating {0}", credentials.getUsername()); User user = (User) entityManager.createQuery( "select u from User u where username = :username") .setParameter("username", credentials.getUsername()) .getSingleResult(); if (user == null) { log.error("no matching user found in the database"); return false; } if (user.getPassword().equals(credentials.getPassword())) { log.info("Authentication successful for user {0}", credentials .getUsername()); return true; } log.info("Invalid password"); return false; } }
It doesn't work. I get the following exception:
[#|2009-05-28T16:14:13.449-0600|INFO|sun-appserver2.1|javax.enterprise.system.co ntainer.ejb|_ThreadID=17;_ThreadName=httpSSLWorkerThread-8080-0;| javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; neste d exception is: java.lang.IllegalArgumentException: EntityManagerFactory not fou nd in JNDI : java:comp/env/hello/pu java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : jav a:comp/env/hello/pu at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManager FactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:245) at org.jboss.seam.persistence.ManagedPersistenceContext.initEntityManage r(ManagedPersistenceContext.java:78) at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManager (ManagedPersistenceContext.java:107) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39)
This is a dead-simple EAR based project based clean right off of Seam gen. I can't seem to get the seam managed persistence to work with EJB/seam session bean components on glassfish, not off the project structure created by seam-gen.