AbstractMethodError using UriBuilder on JAX-RS

84,672

Solution 1

AbstractMethodError are thrown when an application tries to call an abstract method.

uri is an abstract method in UriBuilder, so you need an implementation of this. This method (with String parameter) is from version 2.0 of JAX-RS specification.

You're trying to use JAX-RS 2.0 with Jersey 1.*. Instead, you need to use Jersey 2.* that implements JAX-RS 2.0 and contains an implementation to uri method.

In your pom.xml you may remove these dependencies:

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

And use these dependencies:

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

Using this, uri method is implemented in JerseyUriBuilder class from jersey-common.

EDIT:

You need to change, in your web.xml, servlet com.sun.jersey.spi.container.servlet.ServletContainer to org.glassfish.jersey.servlet.ServletContainer and init-param from com.sun.jersey.config.property.packages to jersey.config.server.provider.packages

Solution 2

I would like to add one answer to this post. I faced a similar problem today and found the root cause to be another dependent jar which was Internally using an older version of Jersey/JAX-RS.

My POM before fix was:

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

The problem was with "com.ci.wrapper" and "com.api.commons". They inturn included 2 different JAR's of BraveJersey and org.apache.cxf.cxf-rt-frontend-jaxrs (2.5.1) which were using Jersey and JAX-RS 1.X versions.

After excluding the nested jar's and adding the newer version's of BraveJersey2/org.apache.cxf.cxf-rt-frontend-jaxrs(3.1.5) it got resolved.

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

In case you're facing a similar issue, please check if the project's or jar's included could be using an incompatible version of Jersey/Jax-RS.

Solution 3

In my case it's combination of both cxf-rt-frontend-jaxrs and httpclint jar needed to be removed to resolve the issue. Both of these jars have the class javax.ws.rs.core.UriBuilder, the multiple version of this class caused the issue.

My pom had a transitive dependency on both these jars, after removing it worked.

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>

Solution 4

I have faced this problem when I was trying to use a library (custom built) in one of my project. So the problem was happening due to mismatch in the com.sun.jersey dependencies. My project was using jersey version 2.15 whereas the custom library was giving me com.sun.jersey transitively of version 1.17.

So how to find such problems.

Use gradle dependencies task to find out the dependencies (it gives nested level results which means all the transitive dependencies will also be shown)

Once you identify the problem causing dependencies. Exclude them while adding the required dependencies in the project.

For e.g. httpRestClient is name of my custom library which I wanted to use in my project. So here is how I have added the dependency and at the same time excluded the conflicting dependencies of group 'com.sun.jersey'

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

This way you can use whatever library and exclude the conflicting libraries.

Thanks.

Solution 5

In our case culprit was this dependency

<dependency>
    <groupId>org.apache.wink</groupId>
    <artifactId>wink-common</artifactId>
    <version>1.0-incubating</version>
</dependency>
Share:
84,672
Admin
Author by

Admin

Updated on July 12, 2022

Comments

  • Admin
    Admin almost 2 years

    I am trying to build a REST webservice using an asynchronous response.

    I have looked around this error on the web, however, none of the solutions have worked for me. I am not sure on how to go about it.

    This is the code for the REST service, it has AsyncResponse, and @Suspended which are taken from jar file specified in the pom.xml, which I will provide below. The problem is, on deploying the war, I get an 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
    

    My class is as follows:

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

    My pom.xml file for maven is as follow:

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