java-sdk-contrib icon indicating copy to clipboard operation
java-sdk-contrib copied to clipboard

[Flagsmith] `getDoubleDetails` expects a `java.lang.Double` from the SDK

Open khvn26 opened this issue 3 months ago • 6 comments

Summary

When calling getDoubleDetails after initialising a Flagsmith provider, a following error happens during value unmarshalling:

Flag value had an unexpected type class java.lang.String, expected class java.lang.Double.

The provider should correctly parse double-like strings to double instead.

Reproduction details

Consider this code example:

// pom.xml dependencies needed:
/*
<dependencies>
    <dependency>
        <groupId>dev.openfeature</groupId>
        <artifactId>sdk</artifactId>
        <version>1.7.4</version>
    </dependency>
    <dependency>
        <groupId>com.flagsmith</groupId>
        <artifactId>flagsmith-openfeature-provider-java</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.flagsmith</groupId>
        <artifactId>flagsmith-java-client</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>
*/

import dev.openfeature.sdk.*;
import dev.openfeature.contrib.providers.flagsmith.FlagsmithProvider;
import dev.openfeature.contrib.providers.flagsmith.FlagsmithProviderOptions;

import java.util.HashMap;
import java.util.Map;

public class FlagsmithOpenFeatureReproduction {

    public static void main(String[] args) {
        try {
            // Create OpenFeature provider with options
            FlagsmithProvider provider = new FlagsmithProvider(
                    FlagsmithProviderOptions.builder()
                            .apiKey("XQjuzDmNmjfhNdDsfg6NLk")
                            .build());

            // Set the provider
            OpenFeatureAPI.getInstance().setProvider(provider);

            // Get client
            Client client = OpenFeatureAPI.getInstance().getClient();

            System.out.println("=== Testing with test=1 context ===");
            testFlags(client, createContext("1"));

            System.out.println("\n=== Testing with test=2 context ===");
            testFlags(client, createContext("2"));

        } catch (Exception e) {
            System.err.println("Setup error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static EvaluationContext createContext(String testValue) {
        Map<String, Value> contextMap = new HashMap<>();
        contextMap.put("test", new Value(testValue));
        return new ImmutableContext(contextMap);
    }

    private static void testFlags(Client client, EvaluationContext context) {
        // Test Double flag - this should fail
        try {
            FlagEvaluationDetails<Double> doubleResult = client.getDoubleDetails(
                    "double_flag", 0.0, context);
            System.out.println("✓ double_flag: " + doubleResult.getValue() + doubleResult.getErrorMessage() +
                    " (reason: " + doubleResult.getReason() + ")");
        } catch (Exception e) {
            System.err.println("✗ double_flag failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Flagsmith environment XQjuzDmNmjfhNdDsfg6NLk contains a double_flag feature with string value "42.42", which I expect to be converted to a double value. However, the output is as follows:

=== Testing with test=1 context ===
✓ double_flag: 0.0Flag value had an unexpected type class java.lang.String, expected class java.lang.Double. (reason: ERROR)

=== Testing with test=2 context ===
✓ double_flag: 0.0Flag value had an unexpected type class java.lang.String, expected class java.lang.Double. (reason: ERROR)

khvn26 avatar Sep 02 '25 12:09 khvn26