S1874 FP "@Deprecated" code should not be used java:S1874, in ObjectNode

False positive with rule java:S1874 “@ Deprecated” code should not be used

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

In class com.fasterxml.jackson.databind.node.ObjectNode the put method with JsonNode as value is deprecated:

public JsonNode put(String propertyName, JsonNode value)

But all other put methods are not, like this one with a String value:

public ObjectNode put(String fieldName, String v)

Example:

ObjectNode node = new ObjectMapper().createObjectNode();
node.put("field", "value");

SonarQube Enterprise generates an issue ‘Remove this use of “put”; it is deprecated.’ but the put method with a String value is not deprecated.


Eduardo Ito.

Hey there.

What version of SonarQube are you using? You should be able to find this in the footer of your SonarQube instance.

I’m using SonarQube Enterpise Edition 9.9.1 (build 69595)

(Sorry for the late response)

Hi @Eduardo_Ito,
We usually pick up the deprecation information as we parse the code and match the types and methods we encounter with classes found in the classpath.

Could it be that multiple versions of jackson-data-bind live within that classpath?

Could you run the analysis with debug logs enabled? That should give us an idea of whether were seeing the right version of the library.

Cheers

I’ve encountered the same issue. I don’t think it’s to do with the multiple versions of Jackson-data-bind since the alternative method never been marked as deprecated since its first introduction.

v2.9:

v2.17:

I have the same issue in IntelliJ with SonarLint version 10.2.1.77304, the jackson-databind version is 2.15.3

    /**
     * Method for setting value of a field to specified String value.
     *
     * @return This node (to allow chaining)
     */
    public ObjectNode put(String fieldName, String v) {
        return _put(fieldName, (v == null) ? nullNode()
                : textNode(v));
    }

The SonarLink scan issue: “SonarLint: Remove this use of “put”; it is deprecated.”

Hello @yumingtao, welcome to the Sonar Community.

I couldn’t reproduce the issue, and looking at the implementation and the previous answer, I’m not surprised. To continue the investigation, I will ask you to provide a reproducer.

It would be fantastic if you could zip a small project that reproduces your situation! It’s enough to have a maven or gradle project with the specific dependency you’re using and a class that uses the put method being reported as an issue.

Cheers,
Angelo

Hi Angelo, here is an example that can be used to reproduce the SonarLint (Java:S1874) issue, the GitHub link is https://github.com/yumingtao/sonarlint-java-s1874.git, and it is reproduced in my local IntelliJ, here is the screenshot.

1 Like

Hi @yumingtao, thank you for providing all the information required.

The investigation result is that the FP positive is caused by using Lombok @Getter.

The Java Analyzer relies on the AST built by Eclipse Compiler for Java that is unaware of Lombok autogenerated code. To be more precise, Lombok works by manipulating the AST, previously created by the ECJ (more details in “Lombok: The Good, The Bad, and The Controversial” and Good and Bad usage of Lombok).

The debugging shows that the AST binds the detailsNode.put(“errorCode”, getErrorCode());to the wrong definition ofObjectNode#put`:

public com.fasterxml.jackson.databind.JsonNode put(java.lang.String, com.fasterxml.jackson.databind.JsonNode)

Since the getErrorCode() definition is unknown to the ECJ, because it was generated afterward by Lombok, it cannot infer the correct ObjectNode#put. I assume that ECJ picks the first definition found in com.fasterxml.jackson.databind.node.ObjectNode, which happens to be annotated as deprecated.

Wrapping up, your code is fine, so please ignore the issue reported. Alternatively, you could:

  1. use directly the errorCode field instead of the getter
  2. assign the value returned by getErrorCode() to a local variable (not specify the type explicitly, instead of using var)

Unfortunately, this is a nasty corner case caused by the combination of several different circumstances.

Cheers,
Angelo

1 Like

Thank you for your detailed investigation and clear explanation. I will proceed by utilizing the “errorCode” field as suggested.

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.