Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Transcompiling error to iOS #2922

Closed
jsfan3 opened this issue Sep 14, 2019 · 3 comments
Closed

[BUG] Transcompiling error to iOS #2922

jsfan3 opened this issue Sep 14, 2019 · 3 comments
Assignees
Milestone

Comments

@jsfan3
Copy link
Contributor

jsfan3 commented Sep 14, 2019

I have the suspect that the following test case demonstrates a transcompiling error from Java to the iOS native language. The following code works as expected on Android and on Simulator, but it fails with a NullPointerException on iOS because of the line result[0] += character;.
Maybe my split code is not the best, but it should be valid: please correct me if I'm wrong.

public void start() {
        if(current != null){
            current.show();
            return;
        }
        Form hi = new Form("Test Split", BoxLayout.y());
        String text = "Abc-123456-7890";
        String[] tokens = split(text, '-');
        hi.add(new Label("Original string: " + text));
        hi.add(new Label("Token 1: " + tokens[0]));
        hi.add(new Label("Token 2: " + tokens[1]));
        hi.show();
    }
    /**
     * Similar to tokenize, but in this case it splits the string always in two
     * tokens, according to the first occurence of the given separator.
     *
     * @param text
     * @param separator
     * @return a string array of two tokens: if the saparator is not found, the
     * first token is equal to the given text and the second token is an empty
     * string
     */
    public static String[] split(String text, Character separator) {
        String[] result = {"", ""};
        boolean separatorFound = false;
        for (Character character : text.toCharArray()) {
            if (!separatorFound && character.equals(separator)) {
                separatorFound = true;
                continue;
            }
            if (!separatorFound) {
                result[0] += character;
            } else {
                result[1] += character;
            }
        }
        return result;
    }

Android screenshot:
Screenshot_20190914-105504

iOS crash report log:

[EDT] 0:0:0,4 - Codename One revisions: 7dd4e7d08b3442d90959477ee52a5ae8c4361b29

[EDT] 0:0:0,8 - Exception: java.lang.NullPointerException - null
java.lang.NullPointerException
    at net_informaticalibera_tests_MyApplication.split:93
    at net_informaticalibera_tests_MyApplication.start:56
    at net_informaticalibera_tests_MyApplicationStub.run:31
    at com_codename1_ui_Display.processSerialCalls:1298
    at com_codename1_ui_Display.mainEDTLoop:1093
    at com_codename1_ui_RunnableWrapper.run:120
    at com_codename1_impl_CodenameOneThread.run:176
    at java_lang_Thread.runImpl:153
[EDT] 0:0:0,9 - Exception in TestSplit version 1.0
[EDT] 0:0:0,9 - OS ios
[EDT] 0:0:0,9 - Error java.lang.NullPointerException: null
[EDT] 0:0:0,9 - Before the first form!
[EDT] 0:0:0,10 - Exception: java.lang.NullPointerException - null
java.lang.NullPointerException
    at net_informaticalibera_tests_MyApplication.split:93
    at net_informaticalibera_tests_MyApplication.start:56
    at net_informaticalibera_tests_MyApplicationStub.run:31
    at com_codename1_ui_Display.processSerialCalls:1298
    at com_codename1_ui_Display.mainEDTLoop:1093
    at com_codename1_ui_RunnableWrapper.run:120
    at com_codename1_impl_CodenameOneThread.run:176
    at java_lang_Thread.runImpl:153
[Network Thread] 0:0:0,447 - Failed to parse expires date sun 13-sep-20 08:45:20 gmt for cookie
@ramsestom
Copy link

String[] result = new String[] {"", ""};

@jsfan3
Copy link
Contributor Author

jsfan3 commented Sep 14, 2019

@ramsestom Thank you for the suggestion, but in Java 8 String[] result = new String[] {"", ""}; and String[] result = {"", ""}; is exactly the same thing, without any difference. To demonstrate that, I checked that in both cases the bytecode produced by the compiler is the same, that is the following.

(Note the nice optimization of the compiler that makes my split method a lot more efficient replacing my += operator between strings with the use of StringBuilder)

  public static java.lang.String[] split(java.lang.String, java.lang.Character);
    Code:
       0: iconst_2
       1: anewarray     #32                 // class java/lang/String
       4: dup
       5: iconst_0
       6: ldc           #33                 // String
       8: aastore
       9: dup
      10: iconst_1
      11: ldc           #33                 // String
      13: aastore
      14: astore_2
      15: iconst_0
      16: istore_3
      17: aload_0
      18: invokevirtual #34                 // Method java/lang/String.toCharArray:()[C
      21: astore        4
      23: aload         4
      25: arraylength
      26: istore        5
      28: iconst_0
      29: istore        6
      31: iload         6
      33: iload         5
      35: if_icmpge     125
      38: aload         4
      40: iload         6
      42: caload
      43: invokestatic  #17                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      46: astore        7
      48: iload_3
      49: ifne          66
      52: aload         7
      54: aload_1
      55: invokevirtual #35                 // Method java/lang/Character.equals:(Ljava/lang/Object;)Z
      58: ifeq          66
      61: iconst_1
      62: istore_3
      63: goto          119
      66: iload_3
      67: ifne          96
      70: new           #20                 // class java/lang/StringBuilder
      73: dup
      74: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
      77: aload_2
      78: iconst_0
      79: dup2_x1
      80: aaload
      81: invokevirtual #23                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      84: aload         7
      86: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      89: invokevirtual #24                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      92: aastore
      93: goto          119
      96: new           #20                 // class java/lang/StringBuilder
      99: dup
     100: invokespecial #21                 // Method java/lang/StringBuilder."<init>":()V
     103: aload_2
     104: iconst_1
     105: dup2_x1
     106: aaload
     107: invokevirtual #23                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
     110: aload         7
     112: invokevirtual #36                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
     115: invokevirtual #24                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     118: aastore
     119: iinc          6, 1
     122: goto          31
     125: aload_2
     126: areturn

@codenameone codenameone added this to the Version 7.0 milestone Sep 15, 2019
@jsfan3
Copy link
Contributor Author

jsfan3 commented Sep 16, 2019

@shannah Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants