【问题标题】:AbstractMethodError using UriBuilder on JAX-RS [duplicate]在 JAX-RS 上使用 UriBuilder 的 AbstractMethodError [重复]
【发布时间】:2015-05-11 20:13:37
【问题描述】:

我正在尝试使用异步响应构建 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>

【问题讨论】:

    标签: java maven jersey jax-rs


    【解决方案1】:

    AbstractMethodError在应用程序尝试调用抽象方法时抛出。

    uri 是UriBuilder 中的一个抽象方法,所以你需要一个实现。此方法(带有String 参数)来自JAX-RS 规范的2.0 版本。

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

    在您的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 的JerseyUriBuilder 类中实现。

    编辑:

    您需要将 web.xml、servlet com.sun.jersey.spi.container.servlet.ServletContainer 更改为 org.glassfish.jersey.servlet.ServletContainer 和 init-param 从 com.sun.jersey.config.property.packages 更改为 jersey.config.server.provider.packages

    【讨论】:

    • 这对我有用。 “编辑”是根本。
    • 谢谢!我试试这个 - 不工作 - medium.com/@jamsesso/…
    • 当应用程序与 Jersey 2 不兼容时,这不是解决方案,不幸的是我们的一个是☹
    • @Pablo 首先,您需要了解 OP 的需求。例如,JAX-RS 1.0 没有异步行为 - 异步响应、暂停等 - 并且问题中的 pom.xml 配置不正确。因此,为了归档 OP 需求,使用 JAX-RS 2.0 是最佳选择,仅基于问题上下文。
    • @BrunoCésar 你说得对,我没有注意到那部分。尽管如此,我还是会留下评论,因为在谷歌搜索该异常时很容易找到这个问题,而且不一定每个人都需要 JAX-RS 2.0 增强功能。
    【解决方案2】:

    我想为这篇文章添加一个答案。我今天遇到了类似的问题,发现根本原因是另一个依赖 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”。 它们又包括 BraveJersey 和 org.apache.cxf.cxf-rt-frontend-jaxrs (2.5.1) 的 2 个不同 JAR,它们使用的是 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 的 included 是否可能使用不兼容的 Jersey/Jax-RS 版本。

    【讨论】:

    • 还想添加一个有趣的陷阱(至少在 Jetty 9 中),如果您部署了在旧 Jersey 中加载的糟糕战争,在没有这些依赖关系的新 WAR 文件中热交换可能仍然看起来像同样的错误;服务器需要完全重启。事后看来是显而易见的,但在一遍又一遍地把我的脑袋撞到这个错误中时却不是。
    • @BandiKishore cxf-bundle-jaxrs-2.2.9 jar 是我的罪魁祸首
    【解决方案3】:

    在我的情况下,需要删除 cxf-rt-frontend-jaxrs 和 httpclint jar 来解决问题。这两个 jar 都有 javax.ws.rs.core.UriBuilder 类,这个类的多个版本导致了这个问题。

    我的 pom 对这两个 jars 有传递依赖,在删除它之后。

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

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

      那么如何发现这样的问题。

      使用gradle dependencies 任务找出依赖关系(它给出嵌套级别的结果,这意味着所有传递依赖关系也将被显示)

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

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

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

      这样您就可以使用任何库并排除冲突的库。

      谢谢。

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-08
          • 2016-04-21
          • 2014-11-06
          • 2011-10-04
          • 2023-03-30
          相关资源
          最近更新 更多