alibaba / arthas

Alibaba Java Diagnostic Tool Arthas/Alibaba Java诊断利器Arthas
https://arthas.aliyun.com/
Apache License 2.0
35.4k stars 7.44k forks source link

jad: fail to decompile class: #385

Closed xinrongVy closed 5 years ago

xinrongVy commented 5 years ago

环境信息

重现问题的步骤

  1. sc StrBuild
  2. jad com.swyc.core.jfinal.util.str.StrBuilderUtil

期望的结果

正确反编译class

实际运行的结果

Affect(row-cnt:0) cost in 152 ms.

01 2018-12-20 10:48:03.586 ERROR [as-command-execute-daemon:arthas] [] [] [] jad: fail to decompile class: com.swyc.core.jfinal.util.str.StrBuilderUtil
jd.core.DecompilerException: cannot decompile /Users/cydu/logs/arthas/classdump/sun.misc.Launcher$AppClassLoader-18b4aac2!com.swyc.core.jfinal.util.str.StrBuilderUtil.class
    at jd.core.Decompiler.decompileClass(Decompiler.java:70) ~[arthas-core.jar:na]
    at com.taobao.arthas.core.command.klass100.JadCommand.processExactMatch(JadCommand.java:131) [arthas-core.jar:na]
    at com.taobao.arthas.core.command.klass100.JadCommand.process(JadCommand.java:115) [arthas-core.jar:na]
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:96) [arthas-core.jar:na]
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:27) [arthas-core.jar:na]
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:125) [arthas-core.jar:na]
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:122) [arthas-core.jar:na]
    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:332) [arthas-core.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_141]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_141]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_141]

com.swyc.core.jfinal.util.str.StrBuilderUtil source


import java.util.Iterator;
import java.util.Objects;

/**
 *
 * 字符串拼接工具类,每个线程共享一个StringBuilder,将少字符串 + 时的性能损耗,以及对最终字符长度估计不足造成数组成倍扩充造成的内存浪费。
 * 如果同一个线程中嵌套使用的,后面直接new 一个
 */
public final class StrBuilderUtil {
    private StringBuilder curSb = null;
    private boolean useThreadBuilder;
    private static final ThreadLocal<StringBuilder> THREAD_BUILDER
            = ThreadLocal.withInitial(() -> new StringBuilder(64));

    private static final ThreadLocal<Integer> BUILDER_STATUS = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return NOT_USE;
        }
    };

    public static final Integer NOT_USE = -1;
    public static final Integer USING = 1;

    private StrBuilderUtil() {
        setUseThreadBuilder(false);
        curSb = tryLock() ? THREAD_BUILDER.get() : new StringBuilder();
    }

    public static StrBuilderUtil me() {
        return new StrBuilderUtil();
    }

    public StrBuilderUtil append(Object str) {
        try {
            curSb.append(str);
        } catch (Exception e) {
            unlock();
            throw new RuntimeException(e);
        }
        return this;
    }

    @Override
    public synchronized String toString() {
        if (curSb == null) {
            return StrUtils.EMPTY_STR;
        }
        String str = curSb.toString();
        unlock();
        return str;
    }

    /**
     * 直接获取 制定位置之间的字符,位置 可为 负数
     */
    public String substring(int start, int end) {

        int length = curSb.length();
        if (length < 1) {
            unlock();
            return StrUtils.EMPTY_STR;
        }
        if (end < 0) {
            end = length + end;
        }
        if (start < 0) {
            start = length + start;
        }
        if (start > end) {
            unlock();
            return StrUtils.EMPTY_STR;
        }
        String substring = curSb.substring(start, end);
        unlock();
        return substring;
    }

    public static String concat(Object... args) {
        if (args == null || args.length == 0) {
            return StrUtils.EMPTY_STR;
        }
        StrBuilderUtil me = StrBuilderUtil.me();
        for (int i = 0; i < args.length; i++) {
            me.curSb.append(StrUtils.nvl(args[i]));
        }
        return me.toString();
    }

    public static String concat(String separator, Iterator iterator) {
        if (iterator == null || !iterator.hasNext()) {
            return StrUtils.EMPTY_STR;
        }
        StrBuilderUtil me = StrBuilderUtil.me();
        me.curSb.append(iterator.next());
        while (iterator.hasNext()) {
            me.curSb.append(separator).append(iterator.next());
        }

        return me.toString();
    }

    private boolean tryLock() {
        if (Objects.equals(BUILDER_STATUS.get(), NOT_USE)) {
            BUILDER_STATUS.set(USING);
            setUseThreadBuilder(true);
            return getUseThreadBuilder();
        }
        return false;
    }

    private void unlock() {
        if (useThreadBuilder) {
            BUILDER_STATUS.set(NOT_USE);
            curSb.setLength(0);
            setUseThreadBuilder(false);
        }
    }

    public int length() {
        return curSb.length();
    }

    public StrBuilderUtil delete(int start, int end) {
        curSb.delete(start, end);
        return this;
    }

    synchronized public void  setUseThreadBuilder(boolean used){
        this.useThreadBuilder=used;
    }
    synchronized public boolean getUseThreadBuilder(){
        return this.useThreadBuilder;
    }

}
hengyunabc commented 5 years ago

上面发的不能编绎,我改了下,jad可以正常工作。


import java.util.Iterator;
import java.util.Objects;

/**
 *
 * 字符串拼接工具类,每个线程共享一个StringBuilder,将少字符串 + 时的性能损耗,以及对最终字符长度估计不足造成数组成倍扩充造成的内存浪费。
 * 如果同一个线程中嵌套使用的,后面直接new 一个
 */
public final class StrBuilderUtil {
    private StringBuilder curSb = null;
    private boolean useThreadBuilder;
    private static final ThreadLocal<StringBuilder> THREAD_BUILDER
            = ThreadLocal.withInitial(() -> new StringBuilder(64));

    private static final ThreadLocal<Integer> BUILDER_STATUS = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return NOT_USE;
        }
    };

    public static final Integer NOT_USE = -1;
    public static final Integer USING = 1;

    private StrBuilderUtil() {
        setUseThreadBuilder(false);
        curSb = tryLock() ? THREAD_BUILDER.get() : new StringBuilder();
    }

    public static StrBuilderUtil me() {
        return new StrBuilderUtil();
    }

    public StrBuilderUtil append(Object str) {
        try {
            curSb.append(str);
        } catch (Exception e) {
            unlock();
            throw new RuntimeException(e);
        }
        return this;
    }

    @Override
    public synchronized String toString() {
        if (curSb == null) {
            return "";
        }
        String str = curSb.toString();
        unlock();
        return str;
    }

    /**
     * 直接获取 制定位置之间的字符,位置 可为 负数
     */
    public String substring(int start, int end) {

        int length = curSb.length();
        if (length < 1) {
            unlock();
            return "";
        }
        if (end < 0) {
            end = length + end;
        }
        if (start < 0) {
            start = length + start;
        }
        if (start > end) {
            unlock();
            return "";
        }
        String substring = curSb.substring(start, end);
        unlock();
        return substring;
    }

    public static String concat(Object... args) {
        if (args == null || args.length == 0) {
            return "";
        }
        StrBuilderUtil me = StrBuilderUtil.me();
        for (int i = 0; i < args.length; i++) {
//            me.curSb.append(StrUtils.nvl(args[i]));
        }
        return me.toString();
    }

    public static String concat(String separator, Iterator iterator) {
        if (iterator == null || !iterator.hasNext()) {
            return "";
        }
        StrBuilderUtil me = StrBuilderUtil.me();
        me.curSb.append(iterator.next());
        while (iterator.hasNext()) {
            me.curSb.append(separator).append(iterator.next());
        }

        return me.toString();
    }

    private boolean tryLock() {
        if (Objects.equals(BUILDER_STATUS.get(), NOT_USE)) {
            BUILDER_STATUS.set(USING);
            setUseThreadBuilder(true);
            return getUseThreadBuilder();
        }
        return false;
    }

    private void unlock() {
        if (useThreadBuilder) {
            BUILDER_STATUS.set(NOT_USE);
            curSb.setLength(0);
            setUseThreadBuilder(false);
        }
    }

    public int length() {
        return curSb.length();
    }

    public StrBuilderUtil delete(int start, int end) {
        curSb.delete(start, end);
        return this;
    }

    synchronized public void  setUseThreadBuilder(boolean used){
        this.useThreadBuilder=used;
    }
    synchronized public boolean getUseThreadBuilder(){
        return this.useThreadBuilder;
    }

}