Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Replace `BiMap` with plain maps

Open
#861 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Refactor
Clarity
Mostly clear
Activity status
Active
Tech stack
java, kotlin

Research direction

Start by tracing how SchemaClassScanner builds TypeClassDictionary and how SchemaParser uses it in both directions, including resolver return types. Then review SchemaParserDictionary.getDictionary() and the graphql-spring-boot call to builder.dictionary(); done means duplicate classes produce a SchemaClassScannerError naming the class and types, the new map-returning method is used without breaking the old API, and BiMap can be removed in a later major release.

Written by the indexing model from the issue text.

Description

graphql.kickstart.tools.util.BiMap is a copy of Guava's BiMap we added when we dropped Guava (661769e). Neither Java nor Kotlin has a bidirectional map, so it stuck around. After #851 it doesn't really pull its weight anymore.

Where it's used:

  • SchemaClassScanner builds a BiMap<TypeDefinition, JavaType> (TypeClassDictionary). SchemaParser reads it both ways: dictionary[definition] for enum classes and dictionary.inverse() for InterfaceTypeResolver and UnionTypeResolver.
  • BiMap#put throwing value already present is the only thing that enforces one class per output type. It shows up as Error creating bimap of type => class, which isn't a very helpful message. It also catches classes found through resolver return types, not just dictionary entries, so a replacement needs an explicit check.
  • SchemaParserDictionary stores a plain map since #851. getDictionary() still returns a BiMap for backwards compatibility (graphql-spring-boot calls builder.dictionary(dictionary.getDictionary())), but its inverse() only keeps the first name when several input types share a class.

Proposal:

  1. Internally, use two plain maps plus an explicit duplicate check that throws a SchemaClassScannerError naming the class and the types. No API change.
typeToClass.entries.groupBy({ it.value }, { it.key })
    .filterValues { it.size > 1 }
    .forEach { (clazz, types) -> throw SchemaClassScannerError("...") }
val classToType = typeToClass.entries.associate { (type, clazz) -> clazz to type }
  1. Add a replacement for getDictionary() that returns Map<String, Class<*>> under a new name, and deprecate getDictionary(). Changing the return type in place would break binary compatibility.
  2. Switch graphql-spring-boot to the new method.
  3. Remove BiMap in the next major.
Dominant language
Kotlin
Stars
824
Forks
175
Avg merge
2d 5h
Merged PRs (30d)
52

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from graphql-java-kickstart/graphql-java-tools

All issues in graphql-java-kickstart/graphql-java-tools

Similar issues

More Kotlin issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.