[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-4242) EAR projects for GlassFish generated by seam-gen not working

Chris Dunphy (JIRA) jira-events at lists.jboss.org
Fri Jun 12 16:57:56 EDT 2009


EAR projects for GlassFish generated by seam-gen not working
------------------------------------------------------------

                 Key: JBSEAM-4242
                 URL: https://jira.jboss.org/jira/browse/JBSEAM-4242
             Project: Seam
          Issue Type: Bug
    Affects Versions: 2.1.2.GA, 2.1.2.CR2
         Environment: Had the same problem on Windows, Ubuntu Linux 9.04 and Mac OS X Leopard
            Reporter: Chris Dunphy


I started a really simple seam-gen project with GlassFish 2.1 and MySQL using seam 2.1.2.

This is the one Entity class I created:

package dunphy.chris.hello.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@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
#Fri Jun 12 14:34:39 MDT 2009
hibernate.connection.password=hello
workspace.home=/Users/cdunphy/Code/Seam
hibernate.connection.dataSource_class=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
model.package=dunphy.chris.hello.model
hibernate.default_catalog=hello
driver.jar=/Users/cdunphy/Code/mysql-connector-java-5.1.7/mysql-connector-java-5.1.7-bin.jar
action.package=dunphy.chris.hello.action
test.package=dunphy.chris.hello.test
database.type=mysql
richfaces.skin=glassX
glassfish.domain=domain1
hibernate.default_schema.null=
database.drop=n
project.name=hello
hibernate.connection.username=hello
glassfish.home=/Users/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=n
jboss.home=/Users/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.  I can also browse the CRUD pages that are generated just fine.

Here is where the problems start. First I add a username/password to the database. Then if I change AuthenticatorBean to do this:

package dunphy.chris.hello.action;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;

import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

import dunphy.chris.hello.model.User;

@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-06-12T14:43:37.641-0600|INFO|sun-appserver2.1|javax.enterprise.system.container.e
jb|_ThreadID=19;_ThreadName=httpSSLWorkerThread-8080-0;|
javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested excepti
on is: java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:
comp/env/hello/pu
java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:comp/en
v/hello/pu
        at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManagerFactoryFr
omJndiOrValueBinding(ManagedPersistenceContext.java:245)
        at org.jboss.seam.persistence.ManagedPersistenceContext.initEntityManager(Managed
PersistenceContext.java:78)
        at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManager(ManagedP
ersistenceContext.java:107)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.j
ava:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
        at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
        at org.jboss.seam.Component.callComponentMethod(Component.java:2249)
        at org.jboss.seam.Component.unwrap(Component.java:2275)
        at org.jboss.seam.Component.getInstance(Component.java:2041)
        at org.jboss.seam.Component.getInstance(Component.java:1983)
        at org.jboss.seam.Component.getInstance(Component.java:1977)
        at org.jboss.seam.Component.getInstanceInAllNamespaces(Component.java:2349)
        at org.jboss.seam.Component.getValueToInject(Component.java:2301)
        at org.jboss.seam.Component.injectAttributes(Component.java:1736)
        at org.jboss.seam.Component.inject(Component.java:1554)
        at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.jav
a:61)
        at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.j
ava:68)
        at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterce
ptor.java:44)
        at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.j


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.



I try this workaround:

Okay, so yeah, the way seam-gen sets up the project doesn't work for EAR projects on GlassFish. I had to take the following steps to fix it (starting from the point where you run seam-gen and follow the instructions in glassfish-readme.txt):

1. Disable the ant target that moves the persistence.xml file to /WEB-INF/classes/META-INF:

<target name="gf-cleanup-ear" if="project.ear">
		<!--
		<move todir="${war.dir}/WEB-INF/classes">
			<fileset dir="${jar.dir}">
				<include name="META-INF/orm.xml" if="project.ear" />
				<include name="META-INF/persistence.xml" if="project.ear" />
			</fileset>
		</move>
		-->
</target>
2. Comment out the persistence-unit-ref entry in web.xml

3. Don't try to lookup the seam managed context using @puJndiName@ in components.xml... instead use this:

<persistence:entity-manager-factory
		name="entityManagerFactory" persistence-unit-name="hello" />

	<persistence:managed-persistence-context
		name="entityManager" auto-create="true" entity-manager-factory="#{entityManagerFactory}" 
4. Add ejb-transactions as well to components.xml (you need to add stuff to the namespace headers, see link at the end):

<tx:ejb-transaction />
5. Comment out the jboss.entity.manager.factory.jndi.name property in the persistence-dev.xml file.

6. Add the following property to persistence-dev.xml:

<property name="hibernate.transaction.manager_lookup_class"
	value="org.hibernate.transaction.SunONETransactionManagerLookup" />
7. Add an EJB ref for org.jboss.seam.transaction.LocalEjbSynchronizations to web.xml:

<ejb-local-ref>
		<ejb-ref-name>hello/EjbSynchronizations/local</ejb-ref-name>
		<ejb-ref-type>Session</ejb-ref-type>
		<local-home />
		<local>org.jboss.seam.transaction.LocalEjbSynchronizations</local>
	</ejb-local-ref>

This fixes the persistence unit issue, but it seems to break the ability to use @In to inject session bean components.  

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list