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

Chris Dunphy (JIRA) jira-events at lists.jboss.org
Mon Jul 27 17:25:41 EDT 2009


    [ https://jira.jboss.org/jira/browse/JBSEAM-4242?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12477818#action_12477818 ] 

Chris Dunphy commented on JBSEAM-4242:
--------------------------------------

I have learned a bit more about Seam (still not an expert) and I have distilled the workaround down to 4 steps.  I also determined why I was having issues injecting other session bean components.

Here are the four steps that I needed in order to use @In to biject the entityManager component into a basic EJB based Authenticator session bean component:

1. Disable the ant target that moves the persistence.xml file to /WEB-INF/classes/META-INF. Its better to keep everything in the EJB-JAR:

<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 the following property to persistence-dev.xml:

<property name="hibernate.transaction.manager_lookup_class"
	value="org.hibernate.transaction.SunONETransactionManagerLookup" />


Another user was having the exact same issue in this thread:
http://seamframework.org/Community/Seam212Glassfish21ExplodeDeploy

This is really easy to test.  You just have to use seam-gen to create an EAR based project with GlassFish.  Then create one User entity class, generate the ui for it, and try to look up a User object using the EntityManager in the EJB Authenticator bean component.

> 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.CR2, 2.1.2.GA
>         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