eclipse-ee4j / jersey

Eclipse Jersey Project - Read our Wiki:
https://github.com/eclipse-ee4j/jersey/wiki
Other
691 stars 352 forks source link

BeanGenerator does not generate unique Names in Test Environment #1402

Closed jerseyrobot closed 12 years ago

jerseyrobot commented 12 years ago

The CDI Extension uses the Class BeanGenerator to create Classes on the fly and uses a counter

private int generatedClassCounter = 0;

to generate unique Names. However when used in Conjunction with the jersey-test-framework the CID Extension is executed multiple times within the same thread and thus the "unique" Names are no longer unique within the scope of the Thread Classloader. Here is the Exception:

20:09:03.695 [main] ERROR c.s.jersey.server.impl.cdi.CDIExtension - error calling ClassLoader.defineClass
java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_31]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_31]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_31]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_31]
    at com.sun.jersey.server.impl.cdi.BeanGenerator.createBeanClass(BeanGenerator.java:107) ~[jersey-servlet-1.12.jar:1.12]
    at com.sun.jersey.server.impl.cdi.CDIExtension.afterBeanDiscovery(CDIExtension.java:800) [jersey-servlet-1.12.jar:1.12]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_31]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_31]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_31]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_31]
    at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.introspector.jlr.WeldMethodImpl.invokeOnInstance(WeldMethodImpl.java:170) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.introspector.ForwardingWeldMethod.invokeOnInstance(ForwardingWeldMethod.java:51) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:154) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:241) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:229) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:207) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:75) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:46) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl.fire(AfterBeanDiscoveryImpl.java:40) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:346) [weld-core-1.1.5.Final.jar:2012-01-06 11:59]
    at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:182) [weld-servlet-core-1.1.5.Final.jar:20120106-1159]
    at org.glassfish.grizzly.servlet.WebappContext.contextInitialized(WebappContext.java:1654) [grizzly-http-servlet-2.2.2.jar:2.2.2]
    at org.glassfish.grizzly.servlet.WebappContext.deploy(WebappContext.java:253) [grizzly-http-servlet-2.2.2.jar:2.2.2]
    at com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory$GrizzlyWebTestContainer.instantiateGrizzlyWebServer(GrizzlyWebTestContainerFactory.java:235) [jersey-test-framework-grizzly2-1.12.jar:1.12]
    at com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory$GrizzlyWebTestContainer.<init>(GrizzlyWebTestContainerFactory.java:134) [jersey-test-framework-grizzly2-1.12.jar:1.12]
    at com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory$GrizzlyWebTestContainer.<init>(GrizzlyWebTestContainerFactory.java:91) [jersey-test-framework-grizzly2-1.12.jar:1.12]
    at com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory.create(GrizzlyWebTestContainerFactory.java:84) [jersey-test-framework-grizzly2-1.12.jar:1.12]
    at com.sun.jersey.test.framework.JerseyTest.getContainer(JerseyTest.java:342) [jersey-test-framework-core-1.12.jar:1.12]
    at com.sun.jersey.test.framework.JerseyTest.<init>(JerseyTest.java:182) [jersey-test-framework-core-1.12.jar:1.12]
    at ReproduceBeanGEneratorProblemTest.<init>(ReproduceBeanGEneratorProblemTest.java:20) [test-classes/:na]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.6.0_31]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [na:1.6.0_31]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [na:1.6.0_31]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [na:1.6.0_31]
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:187) [junit-dep-4.10.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:236) [junit-dep-4.10.jar:na]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) [junit-dep-4.10.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:233) [junit-dep-4.10.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) [junit-dep-4.10.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) [junit-dep-4.10.jar:na]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) [junit-dep-4.10.jar:na]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]
Caused by: java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader): attempted  duplicate class definition for name: "com/sun/jersey/server/impl/cdi/generated/Bean0"
    at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.6.0_31]
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) ~[na:1.6.0_31]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615) ~[na:1.6.0_31]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:465) ~[na:1.6.0_31]

Code to reproduce:

public class ReproduceBeanGEneratorProblemTest extends JerseyTest {

    static {
        System.setProperty("com.sun.jersey.server.impl.cdi.lookupExtensionInBeanManager", "true");
    }

    public ReproduceBeanGEneratorProblemTest() {
        super(new GrizzlyWebTestContainerFactory());
    }

    protected AppDescriptor configure() {
        return new WebAppDescriptor.Builder().
servletClass(ServletContainer.class).
requestListenerClass(Listener.class).
build();
    }

    @Test public void foo() {}
    @Test public void bar() {} // Teh Second Test creates an server Side Exception }

Possible Solution: Make the counter static.

A possible Workaround without patching Jersey is to use a new Classloader for each Test:

@Before
    public void setUp() throws Exception {
        // This is a bit hacky. We use a new ClassLoader for each Test to avoid Problems with jerseys "BeanGenerator".
        ClassLoader orig = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(new MyClassLoader(orig));
        super.setUp();
    }
    public static class MyClassLoader extends ClassLoader {
        public MyClassLoader(ClassLoader parent) {
            super(parent);
        }
    }

Affected Versions

[1.12]

jerseyrobot commented 6 years ago
jerseyrobot commented 12 years ago

@glassfishrobot Commented Reported by eigenbrodtm

jerseyrobot commented 12 years ago

@glassfishrobot Commented @pavelbucek said: cannot reproduce.

actually I'm little surprised that you are using CDI on Grizzly container (that should not work at all). Anyway, I tried with Grizzly 1 & 2 and test is still passing. Can you please provide complete maven project?

Thanks!

jerseyrobot commented 12 years ago

@glassfishrobot Commented eigenbrodtm said: Hm. Maybe I tried to be to simple. The Test are successfull, but there is a serverside exception. However I'll try to create a more complete, mavenized example.

jerseyrobot commented 12 years ago

@glassfishrobot Commented eigenbrodtm said: I figured in addition to the code posted above you need a beans.xml and also have to use some annotation that jerey will try to register as qualifier, @QueryParam in the example.

Please find a complete Test here: https://github.com/martinei/jersey-1130 mvn test will give one test failing and one succeeding although they test the very same thingh.

jerseyrobot commented 12 years ago

@glassfishrobot Commented eigenbrodtm said: Uploaded zipped copy from the github repo for completness.

jerseyrobot commented 12 years ago

@glassfishrobot Commented @pavelbucek said: great, thanks!

jerseyrobot commented 12 years ago

@glassfishrobot Commented eigenbrodtm said: I have problems to identify the fixing commit. Could you give me a hint?

jerseyrobot commented 12 years ago

@glassfishrobot Commented File: martinei-jersey-1130-628d47f.zip Attached By: eigenbrodtm

jerseyrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA JERSEY-1130

jerseyrobot commented 12 years ago

@glassfishrobot Commented Marked as fixed on Monday, May 28th 2012, 9:19:07 am