j2cl icon indicating copy to clipboard operation
j2cl copied to clipboard

"abc".split("") get error result ["","a","b","c"]

Open xiaoxidashen opened this issue 3 years ago • 2 comments

Describe the bug

"abc".split("") get error array ["","a","b","c"]

To Reproduce

use j2clmavenplugin

//in java MathUtil.java
package cn.util;

import jsinterop.annotations.JsType;

@JsType
public class MathUtil {

    public static native void ppp(String s);

    public static void test() {
        String s = "abc";
        ppp(s);
        String[] split = s.split("");
        ppp("String.valueOf(split)"+"["+String.valueOf(split)+"]");
        ppp("split.length "+split.length+"");
        for (String s1 : split) {
            ppp("["+s1+"]");
        }
    }
}

//MathUtil.native.js
setTimeout(function() {

    MathUtil.ppp = function (s) {
        console.log(s);
    }

    MathUtil.test();

}, 0);

get result in browser console

abc
String.valueOf(split)[,a,b,c]
split.length 4
[]
[a]
[b]
[c]

"abc".split("") The expected result is ["a","b","c"]

xiaoxidashen avatar Apr 20 '22 15:04 xiaoxidashen

As commented in the Javadoc [1], unfortunately java.lang.String.split emulation has a lot of incompatibilities with JDK. String.split is using regular expressions, and it is impractical to ship a complete Java compatible regex emulation to web. Instead we cheat in this method, try to mimic Java split behavior using JS regex. Although it works mostly the same, this results in different behavior for many edge cases.

Depend on your use case, one alternative API that would work consistently with JVM is the Guava's Splitter which doesn't use regex.

(Being said that split("") is surprisingly uncommon so maybe it is worthwhile special case that scenario 😞 )

[1]

Regular expressions vary from the standard implementation. The regex parameter is interpreted by JavaScript as a JavaScript regular expression. For consistency, use only the subset of regular expression syntax common to both Java and JavaScript.

gkdn avatar Apr 23 '22 07:04 gkdn

(Note: in offline discussion rluble@ pointed out that the JDK behavior is actually changed from Java 7 to Java 8 where J2CL is following the earlier behavior)

gkdn avatar Apr 25 '22 19:04 gkdn