3

In my webproject using tomee, openejb and jackson (among a few other things like hibernate, most important dependencies are listed below) I've got a problem that I just can't fix.

Having a structure as follows:

public abstract class AbstractCrud<E extends AbstractEntity>{
 [...]
   public abstract ResultWrapper<E> create (E entity);
 [...]
}

@Path("/path")
@Consumes("application/json")
@Produces("application/json")
public class ImplementingClass extends AbstractCrud<ImplementingEntity>{
    @PUT
    @Override
    public ResultWrapper<ImplementingEntity> create(final ImplementingEntity entity){
      //Some Code
    }
}

I get this warning: Both package.ImplementingClass#create and package.ImplementingClass#create are equal candidates for handling the current request which can lead to unpredictable results

Followed by this exception:

Cannot construct instance of `package.AbstractEntity` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [...]


My best guess is that the annotation scanner doesn't filter for bridge methods and thus the method using the abstract class is used which (of course) can't be instantiated. I have searched on how to exclude methods from the scanner (or complete classes) but haven't found anything.
So my question is: can I exclude classes or methods from the scanner, if not, what else can I do to prevent this from happening?


Dependencies (Using Java 8):

  • jackson-jaxrs-json-provider: 2.9.0
  • hibernate-core: 5.2.10.Final
  • javaee-api: 7.0
  • cdi-api: 2.0
  • openejb-core: 7.0.3
  • openejb-cxf-rs: 7.0.3
  • cxf-rt-frontend-jaxrs: 3.1.12
  • tomee: 7.0.3
  • asm5-shaded (referenced via 3rd party)
  • about 20 more...

All of those should be the newest versions.

Ch4t4r
  • 1,387
  • 1
  • 11
  • 30
  • What happens if you get rid of everything except `javaee-api: 7.0`? Theoretically the jars that you have listed are provided by Tomee at runtime so they should not be deployed with your application. – Steve C Aug 17 '17 at 15:26
  • Part of them are needed at compile time and are declared as such in my maven file(s). I sadly cannot test it today, but I'll test it tomorrow nevertheless. I'll try to remove the abstract method or use an interface for testing purposes. But I really suppose it's JAXRSs fault. – Ch4t4r Aug 17 '17 at 18:29
  • I've removed the dependencies which aren't needed to compile (try & error until compiling worked), moved my methods to an interface which both wielded the same result as before. Removing the abstract method and the @Override annotation however removes the problem but is against the point of using an abstract class. The problem has to be, that the annotation scanner doesn't filter out bridge methods. – Ch4t4r Aug 18 '17 at 06:23

1 Answers1

3

The problem in this case is that the method is generic, the java compiler generates a synthetic method, so when cxf calls getMethod on your class, it will see two 'create' methods, and one is synthetic, but regardless, that resource method will be registered twice.

This is a bug in CXF. CXF-7670

kocka
  • 657
  • 6
  • 14
  • 1
    I wouldn't have excepted an answer on such an old topic. Thanks for the heads up - even though we used a workaround (which I can't remember) and I'm not part of the project anymore. I guess you stumbled upon this problem yourself? – Ch4t4r Mar 14 '18 at 13:48