Uploaded image for project: 'Seam 2'
  1. Seam 2
  2. JBSEAM-4242

EAR projects for GlassFish generated by seam-gen not working

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.1.2.CR2, 2.1.2.GA
    • Fix Version/s: None
    • Component/s: None
    • Environment:

      Had the same problem on Windows, Ubuntu Linux 9.04 and Mac OS X Leopard

      Description

      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.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                cdunphy Chris Dunphy
              • Votes:
                2 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated: