Проблема разработки через тестирование - PullRequest
2 голосов
/ 06 мая 2010

Я новичок в Java EE 6 и пытаюсь разработать очень простое приложение JAX-RS. RESTfull веб-сервис работает нормально. Однако когда я запустил свое тестовое приложение, я получил следующее. Что я сделал не так? Или я забыл любую конфигурацию? Конечно, я создаю JNDI и использую Netbeans 6.8 IDE. В заключение, спасибо за любые советы.

Моя сущность:


@Entity
@Table(name = "BOOK")
@NamedQueries({
    @NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
    @NamedQuery(name = "Book.findById", query = "SELECT b FROM Book b WHERE b.id = :id"),
    @NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title"),
    @NamedQuery(name = "Book.findByDescription", query = "SELECT b FROM Book b WHERE b.description = :description"),
    @NamedQuery(name = "Book.findByPrice", query = "SELECT b FROM Book b WHERE b.price = :price"),
    @NamedQuery(name = "Book.findByNumberofpage", query = "SELECT b FROM Book b WHERE b.numberofpage = :numberofpage")})
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "ID")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "TITLE")
    private String title;
    @Basic(optional = false)
    @Column(name = "DESCRIPTION")
    private String description;
    @Basic(optional = false)
    @Column(name = "PRICE")
    private double price;
    @Basic(optional = false)
    @Column(name = "NUMBEROFPAGE")
    private int numberofpage;

    public Book()
    {
    }

    public Book(Integer id)
    {
        this.id = id;
    }

    public Book(Integer id, String title, String description, double price, int numberofpage)
    {
        this.id = id;
        this.title = title;
        this.description = description;
        this.price = price;
        this.numberofpage = numberofpage;
    }

    public Integer getId()
    {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getNumberofpage() {
        return numberofpage;
    }

    public void setNumberofpage(int numberofpage) {
        this.numberofpage = numberofpage;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Book)) {
            return false;
        }
        Book other = (Book) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.entity.Book[id=" + id + "]";
    }
}

Мой тестовый класс Junit:


public class BookTest
{

    private static EntityManager em;
    private static EntityManagerFactory emf;

    public BookTest()
    {

    }

    @BeforeClass
    public static void setUpClass() throws Exception
    {
        emf = Persistence.createEntityManagerFactory("E01R01PU");
        em = emf.createEntityManager();
    }

    @AfterClass
    public static void tearDownClass() throws Exception
    {
        em.close();
        emf.close();
    }

    @Test
    public void createBook()
    {
        Book book = new Book();
        book.setId(1);
        book.setDescription("Mastering the Behavior Driven Development with Ruby on Rails");
        book.setTitle("Mastering the BDD");
        book.setPrice(25.9f);
        book.setNumberofpage(1029);

        em.persist(book);

        assertNotNull("ID should not be null", book.getId());
    }
}

My persistence.xml


<persistence>
  <persistence-unit name="E01R01PU" transaction-type="JTA">
    <jta-data-source>BookstoreJNDI</jta-data-source>
    <properties />
  </persistence-unit>
</persistence>

И исключение:


May 7, 2009 11:10:37 AM org.hibernate.validator.util.Version 
INFO: Hibernate Validator bean-validator-3.0-JBoss-4.0.2
May 7, 2009 11:10:37 AM org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
[EL Info]: 2009-05-07 11:10:37.531--ServerSession(13671123)--EclipseLink, version: Eclipse Persistence Services - 2.0.0.v20091127-r5931
May 7, 2009 11:10:40 AM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
May 7, 2009 11:10:43 AM com.sun.enterprise.connectors.ActiveRAFactory createActiveResourceAdapter
SEVERE: rardeployment.class_not_found
May 7, 2009 11:10:43 AM com.sun.enterprise.connectors.ActiveRAFactory createActiveResourceAdapter
SEVERE: 
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR
        at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:104)
        at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:216)
        at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:352)
        at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:106)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
        at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:472)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:437)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:569)
        at javax.naming.InitialContext.lookup(InitialContext.java:396)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94)
        at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
        at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
        at com.entity.BookTest.setUpClass(BookTest.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
        at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888)
Caused by: java.lang.ClassNotFoundException: com.sun.gjc.spi.ResourceAdapter
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:96)
        ... 32 more
[EL Severe]: 2009-05-07 11:10:43.937--ServerSession(13671123)--Local Exception Stack: 
Exception [EclipseLink-7060] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [BookstoreJNDI].
Internal Exception: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]]
        at org.eclipse.persistence.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:451)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:116)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94)
        at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
        at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
        at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
        at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
        at com.entity.BookTest.setUpClass(BookTest.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
        at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031)
        at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888)
Caused by: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]]
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:442)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:569)
        at javax.naming.InitialContext.lookup(InitialContext.java:396)
        at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110)
        ... 23 more
Caused by: javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]
        at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:109)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
        at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:472)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:437)
        ... 26 more
Caused by: com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR
        at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:104)
        at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:216)
        at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:352)
        at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:106)
        ... 29 more
Caused by: java.lang.ClassNotFoundException: com.sun.gjc.spi.ResourceAdapter
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:96)
        ... 32 more

Exception Description: Cannot acquire data source [BookstoreJNDI].
Internal Exception: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]])

Ответы [ 2 ]

3 голосов
/ 06 мая 2010

Во-первых, вам не хватает некоторых JAR-файлов на вашем пути к классам, и я предлагаю добавить $GF_HOME/modules/gf-client.jar (не копируйте JAR-файл в ваш проект, укажите прямо на него).

Во-вторых, ваш тест не пройдет в текущем состоянии, в нем отсутствуют некоторые части:

  • persist необходимо вызвать внутри транзакции
  • вам нужно flush внести изменения, чтобы получить присвоенный идентификатор.

Вот улучшенная версия, которая будет запускать каждый метод тестирования со своим собственным EntityManager и внутри транзакции (которая откатывается в конце метода тестирования):

public class BookTest {
    private static EntityManager em;
    private static EntityManagerFactory emf;

    @BeforeClass
    public static void createEntityManagerFactory() {
        emf = Persistence.createEntityManagerFactory("E01R01PU");
    }

    @AfterClass
    public static void closeEntityManagerFactory() throws Exception {
        emf.close();
    }

    @Before
    public void beginTransaction() {
        em = emf.createEntityManager();
        em.getTransaction().begin();
    }

    @After
    public void rollbackTransaction() {
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }

    @Test
    public void createBook() {
        Book book = new Book();
        book.setId(1);
        book.setDescription("Mastering the Behavior Driven Development with " +
                            "Ruby on Rails");
        book.setTitle("Mastering the BDD");
        book.setPrice(25.9f);
        book.setNumberofpage(1029);

        em.persist(book);
        em.flush(); // sync the in-memory changes with the db
        // now this will pass
        assertNotNull("ID should not be null", book.getId()); 
    }
}

Бонус: этот тест пройдёт:)

Обратите внимание, что люди обычно предпочитают иметь возможность запускать тесты без запуска контейнера, то есть без использования JNDI. Вот persistence.xml, показывающий, как настроить EclipseLink для подключения к базе данных Derby, работающей в режиме сервера, которую можно использовать в контексте тестирования:

<?xml version="1.0" encoding="UTF-8"?>
<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_2_0.xsd"
    version="2.0">

  <persistence-unit name="TestPu" transaction-type="RESOURCE_LOCAL">
    <class>com.acme.Foo</class>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
      <!--property name="eclipselink.target-database" value="DERBY"/-->
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527//path/to/derbyDBs/TestDB;create=true"/>
      <property name="javax.persistence.jdbc.user" value="APP"/>
      <property name="javax.persistence.jdbc.password" value="APP"/>

      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>

      <property name="eclipselink.weaving" value="static" />

      <property name="eclipselink.debug" value="ALL"/>
      <property name="eclipselink.logging.level.sql" value="FINEST" />
      <property name="eclipselink.logging.level" value="FINEST" />
      <property name="eclipselink.logging.level.cache" value="FINEST" />
    </properties>
  </persistence-unit>
</persistence>
1 голос
/ 06 мая 2010

У вас есть сначала «Причина: java.lang.ClassNotFoundException: com.sun.gjc.spi.ResourceAdapter "ошибка в выходных данных. Это должно быть первое, что вы должны исправить (чего-то не хватает). С другой стороны, я вижу так много аннотаций в вашем классе Book, которые в большинстве своем не нужны. В частности, для имен столбцов. Кстати: почему вы аннотируете атрибуты вместо получателей? Вы перезаписали equals (), но на самом деле не реализовали его (только для поля Id, а как насчет других полей?). И если вам нужно перезаписать equals, вы должны перезаписать hashCode а также. Позвольте IDE создавать их, это намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...