skip to Main Content

I try using Twitter API via Spring library spring-social-twitter. However I’m when calling sendDirectMessage(String toScreenName, String text) function I get the following exception:

java.lang.NoSuchMethodError: 'org.springframework.http.HttpStatus org.springframework.http.client.ClientHttpResponse.getStatusCode()'
    at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleError(TwitterErrorHandler.java:56) ~[spring-social-twitter-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:915) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:864) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:804) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:503) ~[spring-web-6.0.4.jar:6.0.4]
    at org.springframework.social.twitter.api.impl.DirectMessageTemplate.sendDirectMessage(DirectMessageTemplate.java:77) ~[spring-social-twitter-1.1.0.RELEASE.jar:1.1.0.RELEASE]
    at com.example.twittertest.TwitterController.send(TwitterController.java:17) ~[classes/:na]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:731) ~[tomcat-embed-core-10.1.5.jar:6.0]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:814) ~[tomcat-embed-core-10.1.5.jar:6.0]

I have the my TwitterTemplate configured as following:

@Component
public class TwitterTemplateCreator {
    public Twitter getTwitterTemplate() {
        return new TwitterTemplate(
                "<cosumerKey>",
                "<consumerSecret>",
                "<accessToken>",
                "<accessTokenSecret>");
    }
}

TwitterController:

@RestController
@RequestMapping(("/api"))
public class TwitterController {
    @Autowired
    private TwitterTemplateCreator twitterTemplateCreator;

    @PostMapping(value = "/send")
    public void send(@RequestParam("name") String name, @RequestParam("text") String text) {
        twitterTemplateCreator.getTwitterTemplate().directMessageOperations().sendDirectMessage(name, text);
    }
}

And finally pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>twitter-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>twitter-test</name>
    <description>twitter-test</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-twitter</artifactId>
            <version>1.1.0.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

My guess is that there is inconsistency with dependencies versions but after trying different Spring Boot versions I still can’t figure out what causes this issue.

2

Answers


  1. Chosen as BEST ANSWER

    Solved by defining my own OAuth1 Rest Template using spring-social. First included following dependencies:

    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-core</artifactId>
        <version>1.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-web</artifactId>
        <version>1.1.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.social</groupId>
        <artifactId>spring-social-security</artifactId>
        <version>1.1.6.RELEASE</version>
    </dependency>
    

    Then create new temlate which extends AbstractOAuth1ApiBinding:

    public class TwitterTemplate extends AbstractOAuth1ApiBinding {
        public static final String TWITTER_API = "https://api.twitter.com/1.1";
        public TwitterTemplate(String consumerKey, String consumerSecret, String accessToken,
                               String accessTokenSecret) {
            super(consumerKey, consumerSecret, accessToken, accessTokenSecret);
        }
        public TwitterUserResponse getUser(String name) {
            return getRestTemplate().getForObject(
                    TWITTER_API + "/users/show.json?screen_name={name}", TwitterUserResponse.class, name);
        }
    }
    
    

    Then just instantiate TwitterTemplate and call needed method.


  2. Your guess is correct. Spring Social Twitter is no longer maintained. The last release, 1.1.2.RELEASE, was made in October 2015 and it depends on Spring Framework 4. Spring Boot 1.x is based on Spring Framework 4.x but it has been out of support since 2019.

    I would recommend that you find an alternative to Spring Social Twitter. The alternative would be to use it with Spring Boot 1.x but then you will be using unsupported software for which bug fixes won’t be available. Even if you’re happy to take that risk, there’s also a good chance that Spring Social Twitter isn’t compatible with the current version of Twitter’s API.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search