Skip to content

[BUG] Hashmap to Map Cast Exception in TargetingFilter.java when using Application Configuration #35823

Description

@noah-msft-brabec

Describe the bug
When checking if a feature flag is enabled the exception java.lang.ClassCastException is thrown.

Exception or Stack Trace

Caused by: java.lang.ClassCastException: java.util.HashMap$Values cannot be cast to java.util.Map
	at com.azure.spring.cloud.feature.management.filters.TargetingFilter.evaluate(TargetingFilter.java:134) ~[spring-cloud-azure-feature-management-4.8.0.jar:4.8.0]
	at com.azure.spring.cloud.feature.management.FeatureManager.isFeatureOn(FeatureManager.java:114) ~[spring-cloud-azure-feature-management-4.8.0.jar:4.8.0]
	at com.azure.spring.cloud.feature.management.FeatureManager.lambda$checkFeature$2(FeatureManager.java:106) ~[spring-cloud-azure-feature-management-4.8.0.jar:4.8.0]
	at java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90) ~[?:1.8.0_332]
	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_332]
	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_332]
	at java.util.HashMap$ValueSpliterator.tryAdvance(HashMap.java:1673) ~[?:1.8.0_332]
	at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) ~[?:1.8.0_332]
	at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499) ~[?:1.8.0_332]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) ~[?:1.8.0_332]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_332]
	at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~[?:1.8.0_332]
	at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196) ~[?:1.8.0_332]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_332]
	at java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:516) ~[?:1.8.0_332]
	at com.azure.spring.cloud.feature.management.FeatureManager.checkFeature(FeatureManager.java:106) ~[spring-cloud-azure-feature-management-4.8.0.jar:4.8.0]
	at com.azure.spring.cloud.feature.management.FeatureManager.isEnabledAsync(FeatureManager.java:63) ~[spring-cloud-azure-feature-management-4.8.0.jar:4.8.0]
	at our java code

To Reproduce
Setup an http request or a piece of code that attempts to check if a feature flag is enabled. Make sure the feature flag has a feature filter with the default percentage set to 0% and an allowed group that is set to 100%. Running this code will cause the cast exception to fire.

Code Snippet
Here is my Java code that initiates the call to check if a flag is enabled:
Boolean.TRUE.equals(featureManager.isEnabledAsync("someFeatureFlag").block())

This is the decompiled code that is throwing the exception from TargetingFilter.java:

Map<String, Map<String, Object>> exclusionMap = (Map<String, Map<String, Object>>) parameters
    .get(EXCLUSION);
Map<String, Object> exclusionAsLists = new HashMap<>();
if (exclusionMap != null) {
    exclusionAsLists.put(USERS, exclusionMap.getOrDefault(USERS, new HashMap<String, Object>()).values());
    exclusionAsLists.put(GROUPS, exclusionMap.getOrDefault(GROUPS, new HashMap<String, Object>()).values());
}

The error is specifically thrown on this line when the default branch is taken:
exclusionAsLists.put(USERS, exclusionMap.getOrDefault(USERS, new HashMap<String, Object>()).values());

Expected behavior
No cast exception is thrown, and that the feature flag check returns either a true or false.

Screenshots
Here is the state of the debugger right before the exception is thrown:
Screenshot 2023-07-11 at 10 32 55 AM

Setup (please complete the following information):

  • OS: MacOS 13.4.1 (22F82)
  • IDE: IntelliJ
  • Library/Libraries: spring-cloud-azure-feature-management-4.8.0.jar
  • Java version: 8
  • App Server/Environment: Tomcat
  • Frameworks: Spring Boot 2.7.12

If you suspect a dependency version mismatch (e.g. you see NoClassDefFoundError, NoSuchMethodError or similar), please check out Troubleshoot dependency version conflict article first. If it doesn't provide solution for the problem, please provide:

  • verbose dependency tree (mvn dependency:tree -Dverbose)
  • exception message, full stack trace, and any available logs

Additional context
I am using a remote configuration store. My local app is talking with a config store in the portal. It connects via a connection string.

Here are the related configured properties:

spring.cloud.azure.appconfiguration.enabled=true
spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=true
spring.cloud.azure.appconfiguration.stores[0].connection-string=<Connection string redacted>
spring.cloud.azure.appconfiguration.stores[0].enabled=true
spring.cloud.azure.appconfiguration.stores[0].monitoring.enabled=true
spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval=30s
spring.cloud.azure.appconfiguration.stores[0].monitoring.triggers[0].key=sentinel
spring.cloud.azure.appconfiguration.stores[0].monitoring.feature-flag-refresh-interval=30s
spring.cloud.azure.appconfiguration.stores[0].feature-flags.selects[0].label-filter=,${spring.profiles.active}

The config store has one key/value called sentinel that allows for dynamic refresh and one feature flag with a feature filter. Here is a screenshot of the details. The value past Tenant: is a guid:
Screenshot 2023-07-11 at 10 41 15 AM

Information Checklist
Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • [-] Bug Description Added
  • [-] Repro Steps Added
  • [-] Setup information Added

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ClientThis issue points to a problem in the data-plane of the library.azure-springAll azure-spring related issuescustomer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-triageWorkflow: This issue needs the team to triage.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions