← 输入框|github.com|刷新
Skip to content

AppiumDriverLocalService.addLogMessageConsumer(Consumer<String>) supply garbled characters in chinese words , 中文字符乱码 #1617

Closed

Description

@jasonjiang9527

Description

AppiumDriverLocalService supply garbled characters in chinese words when call the method addLogMessageConsumer

Environment

  • Java client build version or git revision if you use some snapshot: java-client-v7.5.1.jar
  • Appium server version or git revision if you use some snapshot: 1.22.1
  • Desktop OS/version used to run Appium if necessary: win10
  • Node.js version (unless using Appium.app|exe) or Appium CLI or Appium.app|exe: v16.13.0
  • Mobile platform/version under test: android8/11
  • Real device or emulator/simulator: UIAutomator2

Details

Code To Reproduce Issue [ Good To Have ]

when you use driver.findElementByXPath("//*[@text='发现' ]") , your log got this @text='¥マム￧ホᄚ'
image

        final AppiumServiceBuilder warn = new AppiumServiceBuilder().usingPort(port).withArgument(GeneralServerFlag.LOG_LEVEL, "info");
        final AppiumDriverLocalService appiumDriverLocalService = AppiumDriverLocalService.buildService(warn);
        appiumDriverLocalService.addLogMessageConsumer(s -> log.info("appium log: {}", s));
        appiumDriverLocalService.addLogMessageConsumer(s -> System.out.println(s));
        appiumDriverLocalService.start();

Exception Stacktraces

Please create a gist with the pasted stacktrace of the exception thrown by java.

Link To Appium Logs

Please create a gist which is a paste of your full Appium logs, and link them here. Do not paste your full Appium logs here, as it will make this issue very long and hard to read!
If you are reporting a bug, always include Appium logs as linked gists! It helps to define the problem correctly and clearly.

Activity

  1. jasonjiang9527 commented on Dec 24, 2021

    @jasonjiang9527
    ContributorAuthor

    I debug this method , and i fixed it.
    this is because the method used the wrong way to collect the byte[].
    it collect byte[] as char[] within StringBuilder.write(char) and StringBuilder.toString() use String(char[],int,int) , but the correct way is to use OutputStream.write(byte) such as ByteArrayOutputStream.write(byte) and ByteArrayOutputStream.toString()

    public void addLogMessageConsumer(Consumer<String> consumer) {
            checkNotNull(consumer, "consumer parameter is NULL!");
            addOutPutStream(new OutputStream() {
                StringBuilder lineBuilder = new StringBuilder();
    
                @Override
                public void write(int chr) {
                    try {
                        //collect byte as char 
                        lineBuilder.append((char) chr);
                         // lineBuilder.toString() use String(char[],int,int)
                        Matcher matcher = LOG_MESSAGE_PATTERN.matcher(lineBuilder.toString());
                        if (matcher.matches()) {
                            consumer.accept(matcher.group(1));
                            lineBuilder = new StringBuilder();
                        }
                    } catch (Exception e) {
                        // log error and continue
                        LOG.warn("Log message consumer crashed!", e);
                    }
                }
            });
        }
    

    here is a demo show that how char[] and byte[] is totally different

            String wrong = "¥マム\uFFE7ホᄚ";
            System.out.println("wrong = " + wrong);
            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            for (char c : wrong.toCharArray()) {
                outputStream.write(c);
            }
            final String correct = outputStream.toString();
            System.out.println("correct = " + correct);
    

    output is

    wrong = ¥マム￧ホᄚ
    correct = 发现
    

    also it is easy to avoid this without change the version of appium, just instead of AppiumDriverLocalService.addLogMessageConsumer(Consumer<String>) with appiumDriverLocalService.addOutPutStream(OutputStream)

    appiumDriverLocalServiceInstance.addOutPutStream(new OutputStream() {
                private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    
                @Override
                public void write(int chr) {
                    try {
                        byteArrayOutputStream.write(chr);
                        if ((chr == '\n')) {
                            log.info("appium log :", byteArrayOutputStream.toString());
                            byteArrayOutputStream.reset();
                        }
                    } catch (Exception e) {
                        // TODO: 2021/12/24  
                    }
                }
            });
    
  2. changed the title [-]AppiumDriverLocalService.addLogMessageConsumer(Consumer<String>) supply garbled characters in chinese words[/-] [+]AppiumDriverLocalService.addLogMessageConsumer(Consumer<String>) supply garbled characters in chinese words , 中文字符乱码[/+] on Dec 24, 2021
  3. mykola-mokhnach commented on Dec 24, 2021

    @mykola-mokhnach
    Contributor

    Thanks for creating the patch. I've added a couple of comments there

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions