Attempting to get the length of a Unicode string, I found this code on RosettaCode [1] called grapheme-length :
(def grapheme-length
#(->> (doto (BreakIterator/getCharacterInstance)
(.setText %))
(partial (memfn next))
repeatedly
(take-while (partial not= BreakIterator/DONE))
count))
I invoked it from the REPL to test it like this:
(star-traders.util/grapheme-length "\uD83D\uDE04⌘\uD83D\uDE00") ; Expecting 3
While it did return the expected value, I also got an unexpected warning in red text asking me to "consider reporting this to the maintainers of clojure.lang.InjectedInvoker"...
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x0000000800cc8440 (file:/Users/myusername/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar) to method sun.text.RuleBasedBreakIterator.setText(java.text.CharacterIterator)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x0000000800cc8440
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Apparently this is a known issue with the JVM due to the addition of the Java 9 module system and is mentioned in the Clojure FAQ. [2]
While the problem does go away if --illegal-access=deny
is added to the JVM Args, it appears that the recommended solution is to fix the code with type hinting.
I've tried using --illegal-access=warn
to locate the spot and fix it, like this:
(.setText ^java.text.BreakIterator %)) ; Problem happens here (I think)
However, the problem still occurs, and this has me curious what the right type I should be using is.
How do I fix the code to get rid of the compiler warning, rather than suppress warnings?
[1] https://rosettacode.org/wiki/String_length#Grapheme_Length_2
[2] https://clojure.org/guides/faq#illegal_access