在JAX-RS上使用UriBuilder的AbstractMethodError

时间:2015-05-11 20:13:38

标签: java maven jersey jax-rs

我正在尝试使用异步响应构建REST Web服务。

我在网上查看了这个错误,但是,没有一个解决方案对我有用。我不确定如何去做。

这是REST服务的代码,它有AsyncResponse和@Suspended,它们取自pom.xml中指定的jar文件,我将在下面提供。问题是,在部署战争时,我得到一个例外:

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

我的课程如下:

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);
        }

    }

}

我的maven pom.xml文件如下:

<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>

5 个答案:

答案 0 :(得分:54)

当应用程序尝试调用抽象方法时

AbstractMethodError抛出

uriUriBuilder中的抽象方法,因此您需要实现此方法。此方法(带String参数)来自JAX-RS规范的版本2.0

您正在尝试将JAX-RS 2.0与Jersey 1. *一起使用。相反,您需要使用实现JAX-RS 2.0的Jersey 2. *并包含uri方法的实现。

pom.xml中,您可以删除这些依赖项:

<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>

并使用这些依赖项:

<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>

使用此uri方法在jersey-common的{​​{3}}课程中实施。

修改

您需要在web.xml中将servlet com.sun.jersey.spi.container.servlet.ServletContainer更改为org.glassfish.jersey.servlet.ServletContainerinit-paramcom.sun.jersey.config.property.packages更改为jersey.config.server.provider.packages

答案 1 :(得分:8)

我想在这篇文章中添加一个答案。我今天遇到了类似的问题,发现根本原因是另一个依赖的jar,内部使用较旧版本的Jersey / JAX-RS

修复之前我的POM是:

<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>

问题在于“com.ci.wrapper”和“com.api.commons”。 他们包括两个不同的JAR的BraveJersey和org.apache.cxf.cxf-rt-frontend-jaxrs(2.5.1),它们使用Jersey和JAX-RS 1.X版本。

排除嵌套的jar并添加较新版本的BraveJersey2 / org.apache.cxf.cxf-rt-frontend-jaxrs(3.1.5)后,它得到了解决。

<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>

如果您遇到类似问题,请检查项目或jar的包含是否可能使用不兼容的Jersey / Jax-RS版本。

答案 2 :(得分:3)

当我尝试在我的某个项目中使用库(自定义构建)时,我遇到了这个问题。 所以问题是由于com.sun.jersey依赖项不匹配而发生的。我的项目是使用泽西版本2.15,而自定义库给我的com.sun.jersey传递版本1.17。

那么如何找到这样的问题呢。

使用gradle dependencies任务找出依赖项(它提供嵌套级别结果,这意味着还将显示所有传递依赖项)

确定导致依赖关系的问题后。在项目中添加所需的依赖项时排除它们。

例如 httpRestClient是我想在我的项目中使用的自定义库的名称。 所以这是我添加依赖项的方式,同时排除了组'com.sun.jersey'的冲突依赖关系

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

通过这种方式,您可以使用任何库并排除冲突的库。

感谢。

答案 3 :(得分:1)

在我的情况下,需要删除 cxf-rt-frontend-jaxrs httpclint jar的组合以解决此问题。这两个jar都有类javax.ws.rs.core.UriBuilder,这个类的多个版本引起了这个问题。

我的pom在移除它们之后对这两个罐子具有传递依赖性。

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>

答案 4 :(得分:1)

在我们的案例中,罪魁祸首是这种依赖

<dependency>
    <groupId>org.apache.wink</groupId>
    <artifactId>wink-common</artifactId>
    <version>1.0-incubating</version>
</dependency>