web-dev-qa-db-fra.com

AbstractMethodError utilisant UriBuilder sur JAX-RS

J'essaie de créer un service Web REST à l'aide d'une réponse asynchrone.

J'ai regardé autour de cette erreur sur le Web, cependant, aucune des solutions n'a fonctionné pour moi. Je ne sais pas trop comment s'y prendre.

Il s'agit du code du service REST. Il contient AsyncResponse et @Suspended, qui sont extraits du fichier jar spécifié dans le pom.xml, que je fournirai ci-dessous. Le problème est que, lors du déploiement de la guerre, j'obtiens une exception:

Java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder;
    javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.Java:119)
    com.Sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.Java:651)
    javax.servlet.http.HttpServlet.service(HttpServlet.Java:728)
    org.Apache.Tomcat.websocket.server.WsFilter.doFilter(WsFilter.Java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.50 logs

Ma classe est la suivante:

package com.crudapp;

import Java.util.ArrayList;
import Java.util.List;
import Java.util.concurrent.Callable;
import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.Executors;
import Java.util.concurrent.Future;

import javax.annotation.Generated;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
//import javax.ws.rs.core.UriBuilder;

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.google.gson.Gson;
import com.mysql.jdbc.StringUtils;

import dao.User;
import dao.UserDAO;
import dao.UserDAOImpl;

import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;

@Path("/crudpath")
public class EntityResource {

       private final ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/spring.xml");
       UserDAO userdao = null;
       private final int numOfThreads = 10;
       private final ExecutorService executorService = Executors.newFixedThreadPool(numOfThreads);
      // userdao.getUsers("118");

       //ctx.close();
    @GET
    @Produces("application/json")
    public Response getTupleFromDBasJSON(@QueryParam("param1") String userid, @Suspended final AsyncResponse asyncresponse ){

        if(StringUtils.isNullOrEmpty(userid))
            throw new ServiceException("Userid passed to the REST service /crudpath is null or empty");
        userdao = (userdao==null)?  
                ctx.getBean("userDAO", UserDAOImpl.class)
                : userdao;
        Gson gson = new Gson();

        Future<List<User>> futures = executorService.submit(new DAOTaskHandlerThread(userid));
        List <User> users = new ArrayList<User>();
        if(futures.isDone())
        {
            try{
            users = futures.get();
            if(users!= null)
              return     Response.status(200).entity( gson.toJson(users).toString()).build();
            }
            catch(Exception ex)
            {
                throw new ServiceException(ex);
            }
        }

        return Response.status(200).entity(new ArrayList<User>().toString()).build();

        /*// crrate  a new thread.. call the DAO .. returns the result from here.
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("key", "value");
        return Response.status(200).entity( jsonObject.toString()).build();*/
    }

    private class DAOTaskHandlerThread implements Callable<List<User>>{

        //private UserDAO userDAO;
        private String userid;
        private DAOTaskHandlerThread(//UserDAO userDAO,
                String useridpassed){
            ///this.userDAO= userDAO;
            userid= useridpassed;
        }
        @Override
        public List<User> call() throws Exception {
            // TODO Auto-generated method stub
            return userdao.getUsers(userid);
        }

    }

}

Mon fichier pom.xml pour maven est le suivant:

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>RESTJerseyExample</groupId>
    <artifactId>RESTJerseyExample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <!-- spring framework just added -->

    <properties>
        <Java-version>1.7</Java-version>
        <org.springframework-version>4.0.3.RELEASE</org.springframework-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework-version}</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <!-- spring framework just added ends here -->

        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.jersey</groupId>
            <artifactId>jersey-bundle</artifactId>
            <version>1.19</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20140107</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.19</version>
        </dependency>
        <dependency>
            <groupId>com.Sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.19</version>
        </dependency>
        <dependency>
            <groupId>org.Apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.0</version>
        </dependency>
        <!--  used for httpclient library -->   
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>org.Apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.2</version>
        </dependency>
        <!--  for async response  -->
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0-m12</version>
        </dependency>
    </dependencies>
</project>
26
user471450

AbstractMethodError are levé lorsqu'une application tente d'appeler une méthode abstraite.

uri est une méthode abstraite dans UriBuilder , vous avez donc besoin d'une implémentation de cela. Cette méthode (avec le paramètre String) provient de la version 2.0 de la spécification JAX-RS.

Vous essayez d'utiliser JAX-RS 2.0 avec Jersey 1. *. Au lieu de cela, vous devez utiliser Jersey 2. * qui implémente JAX-RS 2.0 et contient une implémentation selon la méthode uri.

Dans votre pom.xml, vous pouvez supprimer ces dépendances:

<dependency>
    <groupId>com.Sun.jersey</groupId>
    <artifactId>jersey-bundle</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>com.Sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>com.Sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0-m12</version>
</dependency>

Et utilisez ces dépendances:

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.17</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.17</version>
</dependency>

Avec cette méthode, la méthode uri est implémentée dans JerseyUriBuilder class à partir de jersey-common.

MODIFIER:

Vous devez modifier, dans votre web.xml, le servlet com.Sun.jersey.spi.container.servlet.ServletContainer en org.glassfish.jersey.servlet.ServletContainer et init-param de com.Sun.jersey.config.property.packages à jersey.config.server.provider.packages

51
Bruno César

Je voudrais ajouter une réponse à ce post. J’ai rencontré un problème similaire aujourd’hui et j’ai trouvé la cause fondamentale d’un autre fichier jar dépendant, qui était utilisant en interne une version plus ancienne de Jersey/JAX-RS.

Mon POM avant correctif était:

<jersey.version>2.17</jersey.version>
...
<dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>com.ci.wrapper</groupId>
        <artifactId>client-wrapper</artifactId>
        <version>${clients-wrapper.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.api.commons</groupId>
        <artifactId>transferobjects</artifactId>
        <version>3.0.2</version>
    </dependency>

Le problème était avec "com.ci.wrapper" et "com.api.commons" . Ils incluaient 2 jar différents de BraveJersey et org.Apache.cxf.cxf-rt-frontend-jaxrs (2.5.1) qui utilisaient les versions Jersey et JAX-RS 1.X.

Après avoir exclu les fichiers jar imbriqués et ajouté les nouvelles versions de BraveJersey2/org.Apache.cxf.cxf-rt-frontend-jaxrs (3.1.5), le problème a été résolu.

<dependency>
    <groupId>com.api.commons</groupId>
    <artifactId>transferobjects</artifactId>
    <version>3.0.2</version>
    <exclusions>
        <exclusion>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <groupId>org.Apache.cxf</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.Apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    <version>3.1.5</version>
</dependency>

<dependency>
    <groupId>com.ci.wrapper</groupId>
    <artifactId>client-wrapper</artifactId>
    <version>${clients-wrapper.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
        <exclusion>
            <artifactId>brave-jersey</artifactId>
            <groupId>com.github.kristofa</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.github.kristofa</groupId>
    <artifactId>brave-jersey2</artifactId>
    <version>2.4.2</version>
</dependency>

Si vous rencontrez un problème similaire, veuillez vérifier si le inclus du projet ou du fichier jar utilise peut-être une version incompatible de Jersey/Jax-RS.

8
Bandi Kishore

J'ai rencontré ce problème lorsque j'essayais d'utiliser une bibliothèque (construite sur mesure) dans l'un de mes projets . Le problème se posait donc en raison d'une inadéquation dans les dépendances com.Sun.jersey. Mon projet utilisait la version 2.15 du maillot alors que la bibliothèque personnalisée me fournissait com.Sun.jersey de manière transitoire à la version 1.17.

Alors, comment trouver de tels problèmes.

Utilisez gradle dependencies task pour connaître les dépendances (il donne des résultats de niveau imbriqués, ce qui signifie que toutes les dépendances transitives seront également affichées).

Une fois que vous avez identifié le problème à l'origine des dépendances. Excluez-les en ajoutant les dépendances requises dans le projet.

Par exemple, ____. HttpRestClient est le nom de ma bibliothèque personnalisée que je voulais utiliser dans mon projet . Voici comment j'ai ajouté la dépendance et en même temps exclu les dépendances conflictuelles du groupe 'com.Sun.jersey'

compile(httpRestClient) {
        exclude group: 'com.Sun.jersey'
    }

De cette façon, vous pouvez utiliser n'importe quelle bibliothèque et exclure les bibliothèques en conflit.

Merci.

3
Sanjay Bharwani

Dans mon cas, c'est la combinaison de cxf-rt-frontend-jaxrs et httpclint jar qui doit être supprimée pour résoudre le problème. La classe javax.ws.rs.core.UriBuilder est associée à ces deux fichiers. La version multiple de cette classe est à l'origine du problème. 

Mon pom avait une dépendance transitive sur ces deux pots, après l'avoir retiré, cela fonctionnait.

enter code here
            <exclusion>
                <groupId>org.Apache.cxf</groupId>
                <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.Apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </exclusion>
1
lakshmanas

Dans notre cas, le coupable était cette dépendance

<dependency>
    <groupId>org.Apache.wink</groupId>
    <artifactId>wink-common</artifactId>
    <version>1.0-incubating</version>
</dependency>
0
Rohan