JMockit 1.10 causes linkage errors when used with eclEmma or Cobertura #50

Closed
drath3000 opened this Issue Aug 21, 2014 · 2 comments

Comments

3 participants
@drath3000

I have a project that I am putting unit tests together against and after upgrading to JMockit 1.10 are now receiving the following exception when running these unit tests from within both EclEmma and Cobertura:

java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "my/package/TestMyClass$3"

I initially started with JUnit (4.11) tests but have since migrated these across to TestNG (6.8.8) with the same issue. When I run these unit tests alone, they all pass (JUnit and TestNG), however when I attempt to get code coverage from within Eclipse a number of these appear to fail with the linkage error above.

I have also downgraded to JMockit 1.9 and most of my tests pass except for a couple which require functionality in 1.10 so I am assuming that there is some sort of incompatibility between JMockit and the code coverage tools I have been using.

I am using:

  • Eclipse (Luna)
    • Windows 7
    • Java 1.7.0_67 (64 bit)
    • TestNG 6.8.8
    • JMockit 1.10
    • Cobertura 0.9.8
    • EclEmma 2.3.1

I have been able to recreate this in a small example below.

I have an EJB that looks like the following

package my.pkg;

import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Singleton
public class MyBean {

    @PersistenceContext
    private EntityManager em;

    public Object doSomething (String value) {
        Query query = em.createNamedQuery("SomeQuery");

        Object objReturned = query.getSingleResult();

        return objReturned;
    }

}

I then have the TestNG class as follows:

package my.pkg;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import mockit.Tested;

import org.testng.annotations.Test;

public class TestMyBean {

    @Tested MyBean myBean;  

    @Mocked Query query;

    @Test public void 
    should_test_something(@Injectable final EntityManager em) {

        new Expectations() {{
            em.createNamedQuery(anyString); returns (query);

            query.getSingleResult(); returns (new Object());
        }};

        myBean.doSomething("A value");
    }

}

When I run the test on it's own, everything works fine. If I run either EclEmma or Cobertura with the above test using JMockit 1.9, my code coverage is reported correctly. However, when the test is run using JMockit 1.10 and a code coverage tool such as EclEmma or Cobertura I end up with a LinkageError being reported like this one:

FAILED: should_test_something(javax.persistence.$Impl_EntityManager@77ea08e7)
java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "my/pkg/TestMyBean$1"
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    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:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at my.pkg.TestMyBean.should_test_something(TestMyBean.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:606)

@rliesenfeld rliesenfeld added the other label Aug 25, 2014

@rliesenfeld rliesenfeld self-assigned this Aug 25, 2014

@jamesflagg

This comment has been minimized.

Show comment
Hide comment
@jamesflagg

jamesflagg Sep 30, 2014

I am also still encountering the same problem with JMockit 1.12. It seems that the LinkageError is, for me at least, caused by the mere presence of an expectations block.

  • Eclipse Luna 4.4.0
  • EclEmma 2.3.2.201409141915
  • JUnit 4.11
  • Java 1.7

The below code reproduces the error on my environment.

import mockit.Mocked;
import mockit.NonStrictExpectations;

import org.junit.Test;

class MyClass {

    public int myMethod() {
        return 17;
    }
}

public class TestJacocoLinkageError {

    @Mocked
    MyClass myClass;

    @Test
    public void testWithoutExpectations() {
        myClass.myMethod();
    }

    @Test
    public void testWithExpectations() {

        new NonStrictExpectations() {
            {
                myClass.myMethod();
                result = 42;
            }
        };
    }
}
java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "TestJacocoLinkageError$1"
    at TestJacocoLinkageError.testWithExpectations(TestJacocoLinkageError.java:26)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

I am also still encountering the same problem with JMockit 1.12. It seems that the LinkageError is, for me at least, caused by the mere presence of an expectations block.

  • Eclipse Luna 4.4.0
  • EclEmma 2.3.2.201409141915
  • JUnit 4.11
  • Java 1.7

The below code reproduces the error on my environment.

import mockit.Mocked;
import mockit.NonStrictExpectations;

import org.junit.Test;

class MyClass {

    public int myMethod() {
        return 17;
    }
}

public class TestJacocoLinkageError {

    @Mocked
    MyClass myClass;

    @Test
    public void testWithoutExpectations() {
        myClass.myMethod();
    }

    @Test
    public void testWithExpectations() {

        new NonStrictExpectations() {
            {
                myClass.myMethod();
                result = 42;
            }
        };
    }
}
java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "TestJacocoLinkageError$1"
    at TestJacocoLinkageError.testWithExpectations(TestJacocoLinkageError.java:26)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
@rliesenfeld

This comment has been minimized.

Show comment
Hide comment
@rliesenfeld

rliesenfeld Oct 14, 2014

Member

Fixed as issue #87.

Member

rliesenfeld commented Oct 14, 2014

Fixed as issue #87.

@jmockit jmockit deleted a comment from drath3000 Aug 23, 2017

@jmockit jmockit deleted a comment from MicN Aug 23, 2017

@jmockit jmockit deleted a comment from drath3000 Aug 23, 2017

@jmockit jmockit deleted a comment from dan-v Aug 23, 2017

@jmockit jmockit deleted a comment from sivasankariit Aug 23, 2017

@jmockit jmockit deleted a comment from fixpunkt Aug 23, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment