How to write Arquillian tests for JSF classes

2019-09-14 15:58发布

I am trying to perform arquillian tests on a data model rooted in the JSF API. I am getting this error:

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.046 sec <<< FAILURE!
initializationError(mypackage.GenericLazyModelTest)  Time elapsed: 0.003 sec  <<< ERROR!
java.lang.ClassFormatError: Absent Code attribute in method that is not native 
or abstract in class file javax/faces/model/DataModel

Simple arquillian tests, not involving JSF, but JPA and EJB APIs run fine.
Researching the web suggests that a common reason for this is using sun's stub EE APIs as described here and here.

I am definitely not using them. Here is the dependency part of my pom:

  <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.jboss.bom</groupId>
          <artifactId>jboss-javaee-6.0-with-tools</artifactId>
          <version>${javaee6.with.tools.version}</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
   </dependencyManagement>

<dependency>
  <groupId>javax.enterprise</groupId>
  <artifactId>cdi-api</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>javax.faces</groupId>
  <artifactId>jsf-api</artifactId>
  <version>2.1</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.jboss.spec.javax.annotation</groupId>
  <artifactId>jboss-annotations-api_1.1_spec</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.jboss.spec.javax.ws.rs</groupId>
  <artifactId>jboss-jaxrs-api_1.1_spec</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.hibernate.javax.persistence</groupId>
  <artifactId>hibernate-jpa-2.0-api</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.jboss.spec.javax.ejb</groupId>
  <artifactId>jboss-ejb-api_3.1_spec</artifactId>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>4.2.0.Final</version>
  <scope>provided</scope>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-jpamodelgen</artifactId>
  <version>1.1.1.Final</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.primefaces</groupId>
  <artifactId>primefaces</artifactId>
  <version>3.3.1</version>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
</dependency>

<dependency>
  <groupId>org.jboss.arquillian.junit</groupId>
  <artifactId>arquillian-junit-container</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jboss.arquillian.protocol</groupId>
  <artifactId>arquillian-protocol-servlet</artifactId>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.jboss.shrinkwrap.resolver</groupId>
  <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
  <scope>test</scope>
</dependency>

I have also tried to use the internal JBoss JSF API for the tests with no effect on the error:

 <dependency> 
   <groupId>org.jboss.spec.javax.faces</groupId> 
   <artifactId>jboss-jsf-api_2.1_spec</artifactId> 
   <version>2.0.0.Beta1</version> 
   <scope>test</scope> 
 </dependency> 

My model is derived from the primefaces LazyDataModel

public class GenericLazyModel<T> extends LazyDataModel<T>

LazyDataModel in turn is derived from the javax.faces.model.DataModel

public abstract class LazyDataModel<T> extends DataModel<T> implements SelectableDataModel<T>, Serializable

The test is mostly empty, I am requsting an injection of my model and check for null:

EDIT the ShrinkWrap initialization now includes a faces-config.xml, as proposed by stefanglase. Did not change the error output though.

   @RunWith(Arquillian.class)
    public class GenericLazyModelTest {

        @Deployment
        public static Archive<?> createTestArchive() {

          return ShrinkWrap
            .create(WebArchive.class, "genericLazyModelTest.war")
                .addClasses(GenericLazyModel.class, Submitter.class, SubmitterPK.class,
                            Ordering.class)
                .addClasses(GenericDao.class, Resources.class)
                .addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml")
                .addAsWebInfResource(new StringAsset("<faces-config version=\"2.0\"/>"), "faces-config.xml")                            
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
        }

        @Inject
        GenericLazyModel<Submitter> model;

        @Before
        public void before() {
            Assert.assertNotNull(model);
            model.setKlazz(Submitter.class);
        }

I am running this on Jboss 7.1.0.Final.
Any ideas on what could be the issue and how to solve it?

Thank you

1条回答
倾城 Initia
2楼-- · 2019-09-14 16:26

You are missing the faces-config.xml in your Deployment. The Java EE 6 specification requires a faces-config.xml descriptor to be present in your WEB-INF-directory to trigger JSF.

Unlike beans.xml which you already included the faces-config.xml descriptor cannot be an empty file. It must contain at least the root node and the version attribute to specify the JSF version in use.

So you need to add the following code to your ShrinkWrap builder:

.addAsWebInfResource(new StringAsset("<faces-config version=\"2.0\"/>"), "faces-config.xml");
查看更多
登录 后发表回答