4

I've been stuck for a while now. I have searched a lot and I can't find the easiest way to test entity classes or JPA operations against a postgres database. I've found how to using Spring, Mockito and other things, but I can't find the simplest way using pure Java.

I have the following JUnit test:

public class ModelConverterTest {

    private static EntityManagerFactory emf;
    private static EntityManager em;


    public ModelConverterTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        emf = Persistence.createEntityManagerFactory("PU");
        em = emf.createEntityManager(); // Retrieve an application managed entity manager
    }

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

    @Before
    public void setUp() {
         ...    
    }

    @After
    public void tearDown() {
    }

    /**
     * Test of SIMModelToModel method, of class ModelConverter.
     */
    @Test
    public void testSIMModelToModel() {
        System.out.println("SIMModelToModel");
        SIMModel simModel = new PESMModel();
        simModel.addState(testState);
        Model expResult = null;
        Model result = ModelConverter.SIMModelToModel(em, simModel);
        assertTrue(expResult!=null);
        // TODO review the generated test code and remove the default call to fail.
        //fail("The test case is a prototype.");
    }
}

and when running it, I get the following error:

java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/PersistenceContextType
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:787)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:447)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
    at java.lang.Class.getDeclaredMethods(Class.java:1808)
    at sun.reflect.annotation.AnnotationType$1.run(AnnotationType.java:104)
    at sun.reflect.annotation.AnnotationType$1.run(AnnotationType.java:101)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:100)
    at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:84)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:221)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:88)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:70)
    at java.lang.reflect.Field.declaredAnnotations(Field.java:1033)
    at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:1026)
    at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:196)
    at org.junit.runners.model.FrameworkField.getAnnotations(FrameworkField.java:26)
    at org.junit.runners.model.TestClass.addToAnnotationLists(TestClass.java:52)
    at org.junit.runners.model.TestClass.<init>(TestClass.java:45)
    at org.junit.runners.ParentRunner.<init>(ParentRunner.java:73)
    at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:55)
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:51)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)

My persistence.xml file is:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
  <persistence-unit name="PU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/modelsystemdb</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

What should I do to make the test run?

2
  • 4
    If you're using a real JPA provider, rather than mocking the interfaces, then this is not a unit test, it's an integration test. Which is absolutely fine - but you shouldn't call it a unit test. Commented Jul 24, 2012 at 17:55
  • You're right, I edited the question. Commented Jul 24, 2012 at 19:15

5 Answers 5

3

Quoting Trouble With Crippled Java EE 6 APIs in Maven Repository And The Solution by Adam Bien:

Instead of using

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-web-api</artifactId>
  <version>6.0</version>
  <scope>provided</scope>
</dependency>

You should use alternative (geronimo, jboss etc.) dependencies:

<dependency>
   <groupId>org.apache.geronimo.specs</groupId>
   <artifactId>geronimo-ejb_3.1_spec</artifactId>
   <version>1.0</version>
   <scope>provided</scope>
</dependency>
<dependency>
   <groupId>org.apache.geronimo.specs</groupId>
   <artifactId>geronimo-jpa_2.0_spec</artifactId>
   <version>1.0</version>
   <scope>provided</scope>
</dependency>
Sign up to request clarification or add additional context in comments.

2 Comments

thanks! but I don't have that dependency included on my pom. I have javaee-api. Tried to remove it but couldn't find a complete replacement for it. Also, I tried with the those dependencies you gave me and Jboss, and didn't work. Although I'm working with Glassfish and coudn't find an alternative package either :S
javaee-api is fine for compiling against, but you cannot use it at runtime. You must have a proper API implementation from a provider. I use org.hibernate.javax.persistence:hibernate-jpa-2.0-api, which contains the JPA 2 API, and nothing else. It's okay to use that even if you aren't using Hibernate, because it's just the API.
2

Had a similar issue. i.e Even though the Hibernate JPA jar was available through transitive dependencies and javaee 6.0 dependency was provided, the JUNIT Test case was failing. I just moved the javaee dependency at the end of the dependencies definition on the pom file so that the hibernate JPA api jar appeared before the Javaee jar during classpath resolution. That seemed to do the trick and I was able to run the test case. Hope this helps.

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

javaee appears after hibernate dependency

<dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>

1 Comment

+1: I've had this same bodge in place, with javaee-api at the bottom of my POM. Nice to narrow it down to Hibernate ordering, seems obvious now I think about it. :-)
1

If you want to use JPA in your tests, then you will need to have a JPA provider on the classpath when you run them. You can compile against javaee-api, but you must have a real, live provider at runtime.

You mention that you're using GlassFish; that uses EclipseLink as its provider, so it would make sense for you to do the same for your tests. There's information about using EclipseLink via Maven on their wiki.

9 Comments

thanks Tom, but I'm looking to make it work with hibernate, is that possible?
Sure! Just add the relevant Hibernate dependencies instead. I have org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final as a compile dependency, and org.hibernate:hibernate-entitymanager:4.1.4.Final as a runtime dependency. Those plus their transitive dependencies are all i need to use Hibernate. Well, and a database driver. And some sort of logging backend, although actually, i haven't figured that out.
I'm sorry Tom, really thanks for your time, but I have those dependencies installed. I can't find a way to run tests without deploying to Glassfish.
All the annotations in there are also in org.hibernate.javax.persistence:hibernate-jpa-2.0-api, so if you have that on your compile classpath, they will be resolved. If they aren't resolved, then it isn't actually on your classpath.
Aha. In that case, you either need to find other sources for those, or make sure that hibernate-jpa-2.0-api has more priority than javaee-api on the classpath. But really, javaee-api is only suitable for compiling against, not use at runtime.
|
0

We a very similar issue: Junit tests were successfully executing during maven build, however trying to run them from Eclipse directly showed this awful "Absent Code" error. The solution is not in pom.xml-s (they must be right since your build runs, right?) but the configuration of Junit execution in eclipse. In our case, when the maven dependencies were moved on top of the project itself, the correct implementation (eclipselink 2.0.4) persistence classes were loaded. So in eclipse try to check "Run Configurations...", select the Junit configuration in question and on the "Classpath" tab, change the order of libraries in the "User Entries" section: move Maven dependencies on top.

Best regards, Joe Public

Comments

0

In my case under Run Configurations/ClassPath on the the project, click Edit and check "Only include exported entries" that did the trick.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.