From 6605b4abe3e837247656f741815eed7222a980f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A5=BF=E4=B8=9C?= Date: Wed, 13 Nov 2024 14:30:01 +0800 Subject: [PATCH 01/19] Fixed 'PackageInternalsFinder.fuse' throws an exception when jar in jar is empty (#2941) --- .../compiler/PackageInternalsFinder.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java b/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java index 471afc690c4..917c8cc9275 100644 --- a/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java +++ b/memorycompiler/src/main/java/com/taobao/arthas/compiler/PackageInternalsFinder.java @@ -98,18 +98,22 @@ private List fuse(URL packageFolderURL) { JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection(); String rootEntryName = jarConn.getEntryName(); - int rootEnd = rootEntryName.length() + 1; - Enumeration entryEnum = jarConn.getJarFile().entries(); - while (entryEnum.hasMoreElements()) { - JarEntry jarEntry = entryEnum.nextElement(); - String name = jarEntry.getName(); - if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE_EXTENSION)) { - URI uri = URI.create(jarUri + "!/" + name); - String binaryName = name.replaceAll("/", "."); - binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", ""); + if (rootEntryName != null) { + //可能为 null(自己没有类文件时) + int rootEnd = rootEntryName.length() + 1; - result.add(new CustomJavaFileObject(binaryName, uri)); + Enumeration entryEnum = jarConn.getJarFile().entries(); + while (entryEnum.hasMoreElements()) { + JarEntry jarEntry = entryEnum.nextElement(); + String name = jarEntry.getName(); + if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE_EXTENSION)) { + URI uri = URI.create(jarUri + "!/" + name); + String binaryName = name.replaceAll("/", "."); + binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", ""); + + result.add(new CustomJavaFileObject(binaryName, uri)); + } } } } catch (Exception e) { From a5fa6df5f2d8a236a982c6983b0029456a7d8480 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 13 Nov 2024 16:27:31 +0800 Subject: [PATCH 02/19] improve quit message. #2936 --- .../arthas/core/shell/handlers/shell/ShellLineHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/com/taobao/arthas/core/shell/handlers/shell/ShellLineHandler.java b/core/src/main/java/com/taobao/arthas/core/shell/handlers/shell/ShellLineHandler.java index 70d09aa0b32..24eb3711f29 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/handlers/shell/ShellLineHandler.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/handlers/shell/ShellLineHandler.java @@ -8,6 +8,7 @@ import com.taobao.arthas.core.shell.system.Job; import com.taobao.arthas.core.shell.term.Term; import com.taobao.arthas.core.util.TokenUtils; +import com.taobao.arthas.core.view.Ansi; import java.util.List; @@ -166,6 +167,10 @@ private void handleJobs() { } private void handleExit() { + String msg = Ansi.ansi().fg(Ansi.Color.GREEN).a("Session has been terminated.\n" + + "Arthas is still running in the background.\n" + + "To completely shutdown arthas, please execute the 'stop' command.\n").reset().toString(); + term.write(msg); term.close(); } } From ba380bbc8acd2f01ade8dc295ce02224720e808d Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 13 Nov 2024 16:45:46 +0800 Subject: [PATCH 03/19] =?UTF-8?q?Revert=20"Improve=20token=20parsing=20and?= =?UTF-8?q?=20better=20support=20control=20operators=20such=20as=20pi?= =?UTF-8?q?=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit eede2aacf64154bf89eacac31a8a5f0cc1e4d968. --- .../core/shell/cli/impl/CliTokenImpl.java | 73 ++- .../core/shell/cli/impl/CliTokenImplTest.java | 420 ++---------------- 2 files changed, 58 insertions(+), 435 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImpl.java index 175f4cd824e..ca956e5566c 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImpl.java @@ -11,9 +11,6 @@ * @author Julien Viet */ public class CliTokenImpl implements CliToken { - private static final String PIPE = "|"; - private static final String REDIRECT = ">"; - private static final String REDIRECT_APPEND = ">>"; final boolean text; final String raw; @@ -74,7 +71,7 @@ public static List tokenize(String s) { tokenize(s, 0, tokens); - tokens = adjustTokensForSpecialSymbols(tokens); + tokens = correctPipeChar(tokens); return tokens; } @@ -90,53 +87,35 @@ public static List tokenize(String s) { * unsupported: * 3) thread|grep xxx * 4) trace -E classA|classB methodA|methodB|grep classA - * - * Also handles redirection of '>' and '>>' in the similar way - * - * @param tokens original tokens - * @return adjusted tokens + * @param tokens + * @return */ - private static List adjustTokensForSpecialSymbols(List tokens) { - return separateLeadingAndTailingSymbol(tokens, PIPE, REDIRECT_APPEND, REDIRECT); - } - - private static List separateLeadingAndTailingSymbol(List tokens, String... symbols) { - List adjustedTokens = new ArrayList<>(); + private static List correctPipeChar(List tokens) { + List newTokens = new ArrayList(tokens.size()+4); for (CliToken token : tokens) { - String value = token.value(); - String raw = token.raw(); - boolean handled = false; - for (String symbol : symbols) { - if (value.equals(symbol)) { - break; - } else if (value.endsWith(symbol)) { - handled = true; - int lastIndexOfSymbol = raw.lastIndexOf(symbol); - adjustedTokens.add(new CliTokenImpl( - token.isText(), - raw.substring(0, lastIndexOfSymbol), - value.substring(0, value.length() - symbol.length()) - )); - adjustedTokens.add(new CliTokenImpl(true, raw.substring(lastIndexOfSymbol), symbol)); - break; - } else if (value.startsWith(symbol)) { - handled = true; - int firstIndexOfSymbol = raw.indexOf(symbol); - adjustedTokens.add(new CliTokenImpl(true, - raw.substring(0, firstIndexOfSymbol + symbol.length()), symbol)); - adjustedTokens.add(new CliTokenImpl( - token.isText(), - raw.substring(firstIndexOfSymbol + symbol.length()), - value.substring(symbol.length()) - )); - break; - } - } - if (!handled) { - adjustedTokens.add(token); + String tokenValue = token.value(); + if (tokenValue.length()>1 && tokenValue.endsWith("|")) { + //split last char '|' + tokenValue = tokenValue.substring(0, tokenValue.length()-1); + String rawValue = token.raw(); + rawValue = rawValue.substring(0, rawValue.length()-1); + newTokens.add(new CliTokenImpl(token.isText(), rawValue, tokenValue)); + //add '|' char + newTokens.add(new CliTokenImpl(true, "|", "|")); + + } else if (tokenValue.length()>1 && tokenValue.startsWith("|")) { + //add '|' char + newTokens.add(new CliTokenImpl(true, "|", "|")); + //remove first char '|' + tokenValue = tokenValue.substring(1); + String rawValue = token.raw(); + rawValue = rawValue.substring(1); + newTokens.add(new CliTokenImpl(token.isText(), rawValue, tokenValue)); + } else { + newTokens.add(token); } } - return adjustedTokens; + return newTokens; } private static void tokenize(String s, int index, List builder) { diff --git a/core/src/test/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImplTest.java b/core/src/test/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImplTest.java index 8e347d3adf5..fbaeb1b230c 100644 --- a/core/src/test/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImplTest.java +++ b/core/src/test/java/com/taobao/arthas/core/shell/cli/impl/CliTokenImplTest.java @@ -4,7 +4,7 @@ import org.junit.Assert; import org.junit.Test; -import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class CliTokenImplTest { @@ -25,86 +25,14 @@ public class CliTokenImplTest { @Test public void testSupportedPipeCharWithoutRegex() { String[] expectedTextTokenValue = new String[]{"thread", "|", "grep", "xxx"}; - String cmd = "thread| grep xxx"; - List actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread | grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread |grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread'|' grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread '|' grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread '|'grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread\"|\" grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread \"|\" grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread \"|\"grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"thread| grep", "xxx"}; - cmd = "thread'| 'grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread\"| \"grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"thread |grep", "xxx"}; - cmd = "thread' |'grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "thread\" |\"grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"thread \"|\"grep", "xxx"}; - cmd = "thread' \"|\"'grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"thread '|'grep", "xxx"}; - cmd = "thread\" '|'\"grep xxx"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + List actualTokens = CliTokenImpl.tokenize("thread| grep xxx"); + assertEquals(expectedTextTokenValue, actualTokens); + actualTokens = CliTokenImpl.tokenize("thread | grep xxx"); + assertEquals(expectedTextTokenValue, actualTokens); + actualTokens = CliTokenImpl.tokenize("thread |grep xxx"); + assertEquals(expectedTextTokenValue, actualTokens); } /** @@ -123,85 +51,14 @@ public void testSupportedPipeCharWithoutRegex() { @Test public void testSupportedPipeCharWithRegex() { String[] expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB", "|", "grep", "classA"}; - String cmd = "trace -E classA|classB methodA|methodB| grep classA"; - List actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB | grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB |grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB'|' grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB '|' grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB '|'grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - + List actualTokens = CliTokenImpl.tokenize("trace -E classA|classB methodA|methodB| grep classA"); + assertEquals(expectedTextTokenValue, actualTokens); - cmd = "trace -E classA|classB methodA|methodB\"|\" grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + actualTokens = CliTokenImpl.tokenize("trace -E classA|classB methodA|methodB | grep classA"); + assertEquals(expectedTextTokenValue, actualTokens); - cmd = "trace -E classA|classB methodA|methodB \"|\" grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB \"|\"grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB| grep", "classA"}; - cmd = "trace -E classA|classB methodA|methodB'| 'grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB\"| \"grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB |grep", "classA"}; - cmd = "trace -E classA|classB methodA|methodB' |'grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "trace -E classA|classB methodA|methodB\" |\"grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB '|'grep", "classA"}; - cmd = "trace -E classA|classB methodA|methodB\" '|'\"grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB \"|\"grep", "classA"}; - cmd = "trace -E classA|classB methodA|methodB' \"|\"'grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + actualTokens = CliTokenImpl.tokenize("trace -E classA|classB methodA|methodB |grep classA"); + assertEquals(expectedTextTokenValue, actualTokens); } /** @@ -220,247 +77,34 @@ public void testSupportedPipeCharWithRegex() { @Test public void testUnSupportedPipeChar() { String[] expectedTextTokenValue = new String[]{"thread|grep", "xxx"}; - String cmd = "thread|grep xxx"; - List actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + List actualTokens = CliTokenImpl.tokenize("thread|grep xxx"); + assertEquals(expectedTextTokenValue, actualTokens); expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "methodA|methodB|grep", "classA"}; - cmd = "trace -E classA|classB methodA|methodB|grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + actualTokens = CliTokenImpl.tokenize("trace -E classA|classB methodA|methodB|grep classA"); + assertEquals(expectedTextTokenValue, actualTokens); expectedTextTokenValue = new String[]{"trace", "-E", "classA|classB", "|", "methodA|methodB", "|", "grep", "classA"}; - cmd = "trace -E classA|classB| methodA|methodB | grep classA"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); + actualTokens = CliTokenImpl.tokenize("trace -E classA|classB| methodA|methodB | grep classA"); + assertEquals(expectedTextTokenValue, actualTokens); } - @Test - public void testSeparateRedirect() { - String[] expectedTextTokenValue = new String[]{"jad", "aaa", ">", "bbb"}; - String cmd = "jad aaa> bbb"; - List actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa > bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa >bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa'>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa '>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa '>'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\">\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - - cmd = "jad aaa \">\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa \">\"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa >bbb"}; - - cmd = "jad aaa' >'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\" >\"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa> bbb"}; - - cmd = "jad aaa\"> \"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa'> 'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa\\r", ">", "bbb"}; - - cmd = "jad aaa'\\r>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\"\\r>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa'", ">", "bbb"}; - cmd = "jad aaa\"'>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa'>'", "bbb"}; - cmd = "jad aaa\"'>'\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa\">\"", "bbb"}; - cmd = "jad aaa'\">\"' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - } - - @Test - public void testSeparateRedirectAppend() { - String[] expectedTextTokenValue = new String[]{"jad", "aaa", ">>", "bbb"}; - String cmd = "jad aaa>> bbb"; - List actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa >> bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa >>bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa'>>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa '>>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa '>>'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\">>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - - cmd = "jad aaa \">>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa \">>\"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa >>bbb"}; - - cmd = "jad aaa' >>'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\" >>\"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa>> bbb"}; - - cmd = "jad aaa\">> \"bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa'>> 'bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa\\r", ">>", "bbb"}; - - cmd = "jad aaa'\\r>>' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - cmd = "jad aaa\"\\r>>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa'", ">>", "bbb"}; - cmd = "jad aaa\"'>>\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa'>>'", "bbb"}; - cmd = "jad aaa\"'>>'\" bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - - expectedTextTokenValue = new String[]{"jad", "aaa\">>\"", "bbb"}; - cmd = "jad aaa'\">>\"' bbb"; - actualTokens = CliTokenImpl.tokenize(cmd); - assertEqualsIgnoreBlank(expectedTextTokenValue, actualTokens); - Assert.assertEquals(cmd, concatRaw(actualTokens)); - } - - private void assertEqualsIgnoreBlank(String[] expectedTextTokenValue, List actualTokens) { - Assert.assertArrayEquals(expectedTextTokenValue, removeBlankToken(actualTokens)); - } - - private static String[] removeBlankToken(List cliTokens) { - List copy = new ArrayList<>(cliTokens); - return copy.stream() - .filter(token -> !token.isBlank()) - .map(CliToken::value) - .toArray(String[]::new); + private void assertEquals(String[] expectedTextTokenValue, List actualTokens) { + removeBlankToken(actualTokens); + for (int i = 0; i < expectedTextTokenValue.length; i++) { + Assert.assertEquals(expectedTextTokenValue[i], actualTokens.get(i).value()); + } } - private static String concatRaw(List tokens) { - StringBuilder builder = new StringBuilder(); - for (CliToken token : tokens) { - builder.append(token.raw()); + private void removeBlankToken(List cliTokens) { + CliToken blankToken = new CliTokenImpl(false, " "); + Iterator it = cliTokens.iterator(); + while (it.hasNext()) { + CliToken token = it.next(); + if (blankToken.equals(token)) { + it.remove(); + } } - return builder.toString(); } } From 19112782053182cc87ce736b2197bba5151ec835 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 13 Nov 2024 16:57:01 +0800 Subject: [PATCH 04/19] watch/trace support completion. #2945 --- .../java/com/taobao/arthas/core/shell/cli/CompletionUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java b/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java index b95b5ea0dcd..15d1f70cbdc 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/cli/CompletionUtils.java @@ -238,6 +238,7 @@ public static boolean completeMethodName(Completion completion) { res.add(method.getName()); } } + res.add(""); if (res.size() == 1) { completion.complete(res.get(0).substring(lastToken.length()), true); From fd1cb270150699b85ac86022eb363d20bb60aee5 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 13 Nov 2024 17:19:14 +0800 Subject: [PATCH 05/19] fix project name --- labs/cluster-management/native-agent-common/pom.xml | 1 + labs/cluster-management/native-agent-management-web/pom.xml | 1 + labs/cluster-management/native-agent-proxy/pom.xml | 1 + labs/cluster-management/native-agent/pom.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/labs/cluster-management/native-agent-common/pom.xml b/labs/cluster-management/native-agent-common/pom.xml index a769d2edcc3..1439c2062a9 100644 --- a/labs/cluster-management/native-agent-common/pom.xml +++ b/labs/cluster-management/native-agent-common/pom.xml @@ -10,6 +10,7 @@ 4.0.0 native-agent-common + native-agent-common 8 diff --git a/labs/cluster-management/native-agent-management-web/pom.xml b/labs/cluster-management/native-agent-management-web/pom.xml index 1a781346422..02b43aaf5bb 100644 --- a/labs/cluster-management/native-agent-management-web/pom.xml +++ b/labs/cluster-management/native-agent-management-web/pom.xml @@ -10,6 +10,7 @@ 4.0.0 native-agent-management-web + native-agent-management-web 8 diff --git a/labs/cluster-management/native-agent-proxy/pom.xml b/labs/cluster-management/native-agent-proxy/pom.xml index 77423baae6a..b8f50e7474c 100644 --- a/labs/cluster-management/native-agent-proxy/pom.xml +++ b/labs/cluster-management/native-agent-proxy/pom.xml @@ -10,6 +10,7 @@ 4.0.0 native-agent-proxy + native-agent-proxy 8 diff --git a/labs/cluster-management/native-agent/pom.xml b/labs/cluster-management/native-agent/pom.xml index e9ac3b042ba..cfd9087f564 100644 --- a/labs/cluster-management/native-agent/pom.xml +++ b/labs/cluster-management/native-agent/pom.xml @@ -10,6 +10,7 @@ 4.0.0 native-agent + native-agent 8 From 2a16ff1b3a652368be9e83af65ee203ac3207007 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 13 Nov 2024 17:00:36 +0800 Subject: [PATCH 06/19] release 4.0.3 --- Dockerfile | 2 +- Dockerfile-No-Jdk | 2 +- bin/as.sh | 6 +++--- boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java | 2 +- pom.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 63cb217aa1c..5fe6ae2ccca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM openjdk:8-jdk-alpine -ARG ARTHAS_VERSION="4.0.2" +ARG ARTHAS_VERSION="4.0.3" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ diff --git a/Dockerfile-No-Jdk b/Dockerfile-No-Jdk index 825f1ea2395..fabf210293b 100644 --- a/Dockerfile-No-Jdk +++ b/Dockerfile-No-Jdk @@ -1,7 +1,7 @@ # Stage 1: Build FROM openjdk:8-jdk-alpine AS builder -ARG ARTHAS_VERSION="4.0.2" +ARG ARTHAS_VERSION="4.0.3" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ MIRROR_MAVEN_HOST=https://maven.aliyun.com/repository/public diff --git a/bin/as.sh b/bin/as.sh index 161bac3ccf9..4194e45c852 100755 --- a/bin/as.sh +++ b/bin/as.sh @@ -8,10 +8,10 @@ # program : Arthas # author : Core Engine @ Taobao.com -# date : 2024-10-17 +# date : 2024-11-13 # current arthas script version -ARTHAS_SCRIPT_VERSION=4.0.2 +ARTHAS_SCRIPT_VERSION=4.0.3 # SYNOPSIS # rreadlink @@ -476,7 +476,7 @@ EXAMPLES: ./as.sh --stat-url 'http://192.168.10.11:8080/api/stat' ./as.sh -c 'sysprop; thread' ./as.sh -f batch.as - ./as.sh --use-version 4.0.2 + ./as.sh --use-version 4.0.3 ./as.sh --session-timeout 3600 ./as.sh --attach-only ./as.sh --disabled-commands stop,dump diff --git a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java index 56aa988dca7..00519c0f42f 100644 --- a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java +++ b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java @@ -54,7 +54,7 @@ + " java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'\n" + " java -jar arthas-boot.jar -c 'sysprop; thread' \n" + " java -jar arthas-boot.jar -f batch.as \n" - + " java -jar arthas-boot.jar --use-version 4.0.2\n" + + " java -jar arthas-boot.jar --use-version 4.0.3\n" + " java -jar arthas-boot.jar --versions\n" + " java -jar arthas-boot.jar --select math-game\n" + " java -jar arthas-boot.jar --session-timeout 3600\n" + " java -jar arthas-boot.jar --attach-only\n" diff --git a/pom.xml b/pom.xml index 3250fdb1354..31830bd7c19 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ - 4.0.2 + 4.0.3 UTF-8 1.8 1.8 From 4369b39c67522229f1681be0f698402bd68d6d40 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 14 Nov 2024 11:08:56 +0800 Subject: [PATCH 07/19] add update-doc workflow --- .github/workflows/update-doc.yaml | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 .github/workflows/update-doc.yaml diff --git a/.github/workflows/update-doc.yaml b/.github/workflows/update-doc.yaml new file mode 100644 index 00000000000..7202ea0f62b --- /dev/null +++ b/.github/workflows/update-doc.yaml @@ -0,0 +1,80 @@ +name: Update docs on gh-pages + +on: + workflow_dispatch: + inputs: + version: + description: "The version number to download and update (e.g., 4.0.3)" + required: true + +jobs: + update-assets: + runs-on: ubuntu-latest + + steps: + # 步骤 1:检出 gh-pages 分支的代码 + - name: Checkout gh-pages branch + uses: actions/checkout@v3 + with: + ref: gh-pages + + # 步骤 2:下载指定版本的文档 ZIP 文件到 /tmp 目录 + - name: Download documentation ZIP file + run: | + VERSION="${{ github.event.inputs.version }}" + DOC_DOWNLOAD_URL="https://repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/${VERSION}/arthas-packaging-${VERSION}-doc.zip" + echo "Downloading documentation from $DOC_DOWNLOAD_URL" + curl -L "$DOC_DOWNLOAD_URL" -o "/tmp/arthas-doc.zip" + + # 步骤 3:解压文档 ZIP 文件 + - name: Unzip documentation file + run: | + unzip -o /tmp/arthas-doc.zip -d /tmp/arthas-doc + + # 步骤 4:删除仓库中的 assets 目录 + - name: Remove assets directory + run: | + rm -rf assets + + # 步骤 5:复制解压后的文档文件到仓库 + - name: Copy documentation files to repository + run: | + cp -r /tmp/arthas-doc/* ./ + + # 步骤 6:下载指定版本的二进制 ZIP 文件到 /tmp 目录 + - name: Download binary ZIP file + run: | + VERSION="${{ github.event.inputs.version }}" + BIN_DOWNLOAD_URL="https://repo1.maven.org/maven2/com/taobao/arthas/arthas-packaging/${VERSION}/arthas-packaging-${VERSION}-bin.zip" + echo "Downloading binary files from $BIN_DOWNLOAD_URL" + curl -L "$BIN_DOWNLOAD_URL" -o "/tmp/arthas-bin.zip" + + # 步骤 7:解压二进制 ZIP 文件 + - name: Unzip binary file + run: | + unzip -o /tmp/arthas-bin.zip -d /tmp/arthas-bin + + # 步骤 8:复制指定文件到仓库目录 + - name: Copy binary files to repository + run: | + cp /tmp/arthas-bin/as.sh ./ + cp /tmp/arthas-bin/arthas-boot.jar ./ + cp /tmp/arthas-bin/math-game.jar ./ + + # 步骤 9:赋予 as.sh 可执行权限 + - name: Make as.sh executable + run: | + chmod +x as.sh + + # 步骤 10:设置 Git 用户信息 + - name: Set Git user + run: | + git config user.name "${{ github.actor }}" + git config user.email "${{ github.actor }}@users.noreply.github.com" + + # 步骤 11:提交并推送更改到远程仓库 + - name: Commit and push changes + run: | + git add . + git commit -m "Update docs to version ${{ github.event.inputs.version }}" + git push origin gh-pages From baed34483e75babda6294ec5a3b994a7d103c868 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 14 Nov 2024 14:31:09 +0800 Subject: [PATCH 08/19] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4632446731b..b68cdccd719 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,7 +147,7 @@ Tip: you can use `--versions` to list all available versions. 版本号信息地址: https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/maven-metadata.xml * 打上tag,push tag到仓库上 -* 需要更新 gh-pages 分支下面的 arthas-boot.jar/math-game.jar/as.sh ,下载 doc.zip,解压覆盖掉文档的更新 +* 需要更新 gh-pages 分支下面的 arthas-boot.jar/math-game.jar/as.sh ,下载 doc.zip,解压覆盖掉文档的更新,可以通过 github action 更新: https://github.com/alibaba/arthas/actions/workflows/update-doc.yaml * 需要更新docker镜像,push新的tag:https://hub.docker.com/r/hengyunabc/arthas/tags?page=1&ordering=last_updated 以 3.6.5 版本为例: From 6cee2d33f3997a6974075a1a099ed33db163dd6a Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 20 Nov 2024 16:39:08 +0800 Subject: [PATCH 09/19] update web-ui/arthasWebConsole/yarn.lock --- web-ui/arthasWebConsole/yarn.lock | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/web-ui/arthasWebConsole/yarn.lock b/web-ui/arthasWebConsole/yarn.lock index f9815dcf2c7..599bc03cc49 100644 --- a/web-ui/arthasWebConsole/yarn.lock +++ b/web-ui/arthasWebConsole/yarn.lock @@ -235,6 +235,11 @@ arg@^5.0.2: resolved "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + autoprefixer@^10.4.7: version "10.4.13" resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" @@ -247,6 +252,15 @@ autoprefixer@^10.4.7: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -334,6 +348,13 @@ color@^4.2: color-convert "^2.0.1" color-string "^1.9.0" +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + css-selector-tokenizer@^0.8.0: version "0.8.0" resolved "https://registry.npmmirror.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd" @@ -377,6 +398,11 @@ defined@^1.0.0: resolved "https://registry.npmmirror.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + detective@^5.2.1: version "5.2.1" resolved "https://registry.npmmirror.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034" @@ -576,6 +602,20 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" @@ -683,6 +723,18 @@ micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + minimatch@^5.1.0: version "5.1.0" resolved "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" @@ -806,6 +858,11 @@ postcss@^8.1.10, postcss@^8.4.13, postcss@^8.4.14, postcss@^8.4.18: picocolors "^1.0.0" source-map-js "^1.0.2" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" From aa23a4acc9aeefbcedb2f2a9f7ecb18584cb6cdc Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 20 Nov 2024 17:12:37 +0800 Subject: [PATCH 10/19] downgrade ognl to 3.3.5. #2954, #2953 --- .../command/express/ArthasObjectPropertyAccessor.java | 5 +++-- .../command/express/ClassLoaderClassResolver.java | 6 ++---- .../core/command/express/CustomClassResolver.java | 5 ++--- .../core/command/express/DefaultMemberAccess.java | 11 +++++++---- pom.xml | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java b/core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java index f83d330448d..7562705fdef 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java +++ b/core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java @@ -1,9 +1,10 @@ package com.taobao.arthas.core.command.express; +import java.util.Map; + import com.taobao.arthas.core.GlobalOptions; import ognl.ObjectPropertyAccessor; -import ognl.OgnlContext; import ognl.OgnlException; /** @@ -12,7 +13,7 @@ public class ArthasObjectPropertyAccessor extends ObjectPropertyAccessor { @Override - public Object setPossibleProperty(OgnlContext context, Object target, String name, Object value) throws OgnlException { + public Object setPossibleProperty(Map context, Object target, String name, Object value) throws OgnlException { if (GlobalOptions.strict) { throw new IllegalAccessError(GlobalOptions.STRICT_MESSAGE); } diff --git a/core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java b/core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java index e69cf743bef..7409d2916d1 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java +++ b/core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java @@ -4,7 +4,6 @@ import java.util.concurrent.ConcurrentHashMap; import ognl.ClassResolver; -import ognl.OgnlContext; /** * @author hengyunabc 2018-10-18 @@ -20,9 +19,8 @@ public ClassLoaderClassResolver(ClassLoader classLoader) { this.classLoader = classLoader; } - @Override - public Class classForName(String className, OgnlContext ognlContext) throws ClassNotFoundException { + public Class classForName(String className, Map context) throws ClassNotFoundException { Class result = null; if ((result = classes.get(className)) == null) { @@ -39,6 +37,6 @@ public Class classForName(String className, OgnlContext ognlContext) thro } classes.put(className, result); } - return (Class) result; + return result; } } diff --git a/core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java b/core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java index 81c9c174b66..7512e92a4f0 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java +++ b/core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java @@ -1,7 +1,6 @@ package com.taobao.arthas.core.command.express; import ognl.ClassResolver; -import ognl.OgnlContext; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -21,7 +20,7 @@ private CustomClassResolver() { } @Override - public Class classForName(String className, OgnlContext ognlContext) throws ClassNotFoundException { + public Class classForName(String className, Map context) throws ClassNotFoundException { Class result = null; if ((result = classes.get(className)) == null) { @@ -40,6 +39,6 @@ public Class classForName(String className, OgnlContext ognlContext) thro } classes.put(className, result); } - return (Class) result; + return result; } } diff --git a/core/src/main/java/com/taobao/arthas/core/command/express/DefaultMemberAccess.java b/core/src/main/java/com/taobao/arthas/core/command/express/DefaultMemberAccess.java index 2f5abb4c88f..3384a863c39 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/express/DefaultMemberAccess.java +++ b/core/src/main/java/com/taobao/arthas/core/command/express/DefaultMemberAccess.java @@ -1,11 +1,11 @@ package com.taobao.arthas.core.command.express; import ognl.MemberAccess; -import ognl.OgnlContext; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Member; import java.lang.reflect.Modifier; +import java.util.Map; /** * ognl.DefaultMemberAccess (ognl:ognl:3.1.19) @@ -58,7 +58,8 @@ public void setAllowPackageProtectedAccess(boolean value) { allowPackageProtectedAccess = value; } - public Object setup(OgnlContext context, Object target, Member member, String propertyName) { + @Override + public Object setup(Map context, Object target, Member member, String propertyName) { Object result = null; if (isAccessible(context, target, member, propertyName)) { @@ -72,7 +73,8 @@ public Object setup(OgnlContext context, Object target, Member member, String pr return result; } - public void restore(OgnlContext context, Object target, Member member, String propertyName, Object state) { + @Override + public void restore(Map context, Object target, Member member, String propertyName, Object state) { if (state != null) { ((AccessibleObject)member).setAccessible((Boolean)state); } @@ -88,7 +90,8 @@ public void restore(OgnlContext context, Object target, Member member, String pr * @param propertyName the property to test accessibility for (not used). * @return true if the member is accessible in the context, false otherwise. */ - public boolean isAccessible(OgnlContext context, Object target, Member member, String propertyName) { + @Override + public boolean isAccessible(Map context, Object target, Member member, String propertyName) { int modifiers = member.getModifiers(); boolean result = Modifier.isPublic(modifiers); diff --git a/pom.xml b/pom.xml index 31830bd7c19..f8bd8e64261 100644 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ ognl ognl - 3.4.2 + 3.3.5 org.junit From 4e931cbe83dcdee7cbd935e7e0048527624de597 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 20 Nov 2024 17:13:03 +0800 Subject: [PATCH 11/19] add OgnlTest. #2954 --- .../core/command/express/FlowAttribute.java | 9 ++++ .../core/command/express/FlowContext.java | 9 ++++ .../arthas/core/command/express/OgnlTest.java | 46 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 core/src/test/java/com/taobao/arthas/core/command/express/FlowAttribute.java create mode 100644 core/src/test/java/com/taobao/arthas/core/command/express/FlowContext.java create mode 100644 core/src/test/java/com/taobao/arthas/core/command/express/OgnlTest.java diff --git a/core/src/test/java/com/taobao/arthas/core/command/express/FlowAttribute.java b/core/src/test/java/com/taobao/arthas/core/command/express/FlowAttribute.java new file mode 100644 index 00000000000..1848b650ca1 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/command/express/FlowAttribute.java @@ -0,0 +1,9 @@ +package com.taobao.arthas.core.command.express; + +public class FlowAttribute { + private String bxApp = "aaa"; + + public String getBxApp() { + return this.bxApp ; + } +} diff --git a/core/src/test/java/com/taobao/arthas/core/command/express/FlowContext.java b/core/src/test/java/com/taobao/arthas/core/command/express/FlowContext.java new file mode 100644 index 00000000000..c1991bdbe79 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/command/express/FlowContext.java @@ -0,0 +1,9 @@ +package com.taobao.arthas.core.command.express; + +public class FlowContext { + private FlowAttribute flowAttribute = new FlowAttribute(); + + public FlowAttribute getFlowAttribute() { + return this.flowAttribute ; + } +} diff --git a/core/src/test/java/com/taobao/arthas/core/command/express/OgnlTest.java b/core/src/test/java/com/taobao/arthas/core/command/express/OgnlTest.java new file mode 100644 index 00000000000..7148ebbbb2a --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/command/express/OgnlTest.java @@ -0,0 +1,46 @@ +package com.taobao.arthas.core.command.express; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import com.taobao.arthas.core.advisor.Advice; +import ognl.OgnlException; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * https://github.com/alibaba/arthas/issues/2954 + */ +public class OgnlTest { + + private Express express; + + @BeforeEach + public void setUp() throws OgnlException, ExpressException { + FlowContext context = new FlowContext(); + Object[] params = new Object[4]; + params[0] = context; + Advice advice = Advice.newForAfterReturning(null, getClass(), null, null, params, null); + express = ExpressFactory.unpooledExpress(null).bind(advice).bind("cost", 123); + } + + @Test + public void testStringEquals() throws OgnlException, ExpressException { + String conditionExpress = "\"aaa\".equals(params[0].flowAttribute.getBxApp())"; + boolean result = express.is(conditionExpress); + assertTrue(result); + } + + @Test + public void testObjectEquals() throws OgnlException, ExpressException { + String conditionExpress = "params[0].flowAttribute.getBxApp().equals(\"aaa\")"; + boolean result = express.is(conditionExpress); + assertTrue(result); + } + + @Test + public void testEqualSign() throws OgnlException, ExpressException { + String conditionExpress = "\"aaa\" == params[0].flowAttribute.getBxApp()"; + boolean result = express.is(conditionExpress); + assertTrue(result); + } +} From 797baf5b04f28855b1cf8205f4764aa3f89977d8 Mon Sep 17 00:00:00 2001 From: haidao Date: Wed, 20 Nov 2024 22:27:42 +0800 Subject: [PATCH 12/19] upgrade termd to 1.1.7.14 and maven-shade-plugin to 3.6.0 (#2949) --- core/pom.xml | 2 +- labs/cluster-management/native-agent-management-web/pom.xml | 4 ++-- labs/cluster-management/native-agent-proxy/pom.xml | 4 ++-- labs/cluster-management/native-agent/pom.xml | 4 ++-- pom.xml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index cfda902b71d..69c39b47e04 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.3 + 3.6.0 package diff --git a/labs/cluster-management/native-agent-management-web/pom.xml b/labs/cluster-management/native-agent-management-web/pom.xml index 02b43aaf5bb..873a168b770 100644 --- a/labs/cluster-management/native-agent-management-web/pom.xml +++ b/labs/cluster-management/native-agent-management-web/pom.xml @@ -58,7 +58,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.6.0 package @@ -79,4 +79,4 @@ - \ No newline at end of file + diff --git a/labs/cluster-management/native-agent-proxy/pom.xml b/labs/cluster-management/native-agent-proxy/pom.xml index b8f50e7474c..317d68ada6d 100644 --- a/labs/cluster-management/native-agent-proxy/pom.xml +++ b/labs/cluster-management/native-agent-proxy/pom.xml @@ -36,7 +36,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.6.0 package @@ -57,4 +57,4 @@ - \ No newline at end of file + diff --git a/labs/cluster-management/native-agent/pom.xml b/labs/cluster-management/native-agent/pom.xml index cfd9087f564..34ae0e3dc41 100644 --- a/labs/cluster-management/native-agent/pom.xml +++ b/labs/cluster-management/native-agent/pom.xml @@ -63,7 +63,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.6.0 package @@ -82,4 +82,4 @@ - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index f8bd8e64261..a7ab8b3f5a1 100644 --- a/pom.xml +++ b/pom.xml @@ -111,7 +111,7 @@ com.alibaba.middleware termd-core - 1.1.7.13 + 1.1.7.14 com.alibaba.middleware From dec5c1cdd5dab704ace35be5add03dc128fb15ba Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 20 Nov 2024 22:32:39 +0800 Subject: [PATCH 13/19] release 4.0.4 --- Dockerfile | 2 +- Dockerfile-No-Jdk | 2 +- bin/as.sh | 4 ++-- boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java | 2 +- pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5fe6ae2ccca..eeaada21254 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM openjdk:8-jdk-alpine -ARG ARTHAS_VERSION="4.0.3" +ARG ARTHAS_VERSION="4.0.4" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ diff --git a/Dockerfile-No-Jdk b/Dockerfile-No-Jdk index fabf210293b..317b300813c 100644 --- a/Dockerfile-No-Jdk +++ b/Dockerfile-No-Jdk @@ -1,7 +1,7 @@ # Stage 1: Build FROM openjdk:8-jdk-alpine AS builder -ARG ARTHAS_VERSION="4.0.3" +ARG ARTHAS_VERSION="4.0.4" ARG MIRROR=false ENV MAVEN_HOST=https://repo1.maven.org/maven2 \ MIRROR_MAVEN_HOST=https://maven.aliyun.com/repository/public diff --git a/bin/as.sh b/bin/as.sh index 4194e45c852..c5992788c04 100755 --- a/bin/as.sh +++ b/bin/as.sh @@ -11,7 +11,7 @@ # date : 2024-11-13 # current arthas script version -ARTHAS_SCRIPT_VERSION=4.0.3 +ARTHAS_SCRIPT_VERSION=4.0.4 # SYNOPSIS # rreadlink @@ -476,7 +476,7 @@ EXAMPLES: ./as.sh --stat-url 'http://192.168.10.11:8080/api/stat' ./as.sh -c 'sysprop; thread' ./as.sh -f batch.as - ./as.sh --use-version 4.0.3 + ./as.sh --use-version 4.0.4 ./as.sh --session-timeout 3600 ./as.sh --attach-only ./as.sh --disabled-commands stop,dump diff --git a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java index 00519c0f42f..502e4369544 100644 --- a/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java +++ b/boot/src/main/java/com/taobao/arthas/boot/Bootstrap.java @@ -54,7 +54,7 @@ + " java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'\n" + " java -jar arthas-boot.jar -c 'sysprop; thread' \n" + " java -jar arthas-boot.jar -f batch.as \n" - + " java -jar arthas-boot.jar --use-version 4.0.3\n" + + " java -jar arthas-boot.jar --use-version 4.0.4\n" + " java -jar arthas-boot.jar --versions\n" + " java -jar arthas-boot.jar --select math-game\n" + " java -jar arthas-boot.jar --session-timeout 3600\n" + " java -jar arthas-boot.jar --attach-only\n" diff --git a/pom.xml b/pom.xml index a7ab8b3f5a1..3fabb644ba2 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ - 4.0.3 + 4.0.4 UTF-8 1.8 1.8 From e6e95dfa56fa2cc0427c320dda462fd4aa2d2e49 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 20 Nov 2024 23:55:25 +0800 Subject: [PATCH 14/19] add workflows/push-docker.yaml --- .github/workflows/push-docker.yaml | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/push-docker.yaml diff --git a/.github/workflows/push-docker.yaml b/.github/workflows/push-docker.yaml new file mode 100644 index 00000000000..e5ff306224a --- /dev/null +++ b/.github/workflows/push-docker.yaml @@ -0,0 +1,34 @@ +name: Push arthas images to Docker Hub + +on: + workflow_dispatch: + inputs: + version: + description: "The version number to push (e.g., 4.0.3)" + required: true + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + # 步骤 1:检出 master 分支的代码 + - name: Checkout gh-pages branch + uses: actions/checkout@v3 + with: + ref: master + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build Docker image + run: | + VERSION="${{ github.event.inputs.version }}" + docker buildx build . --build-arg ARTHAS_VERSION=$VERSION --build-arg MIRROR=true -t hengyunabc/arthas:$VERSION -t hengyunabc/arthas:latest --platform=linux/arm64,linux/amd64 --push + docker buildx build . --build-arg ARTHAS_VERSION=$VERSION --build-arg MIRROR=true -f Dockerfile-No-Jdk -t hengyunabc/arthas:$VERSION-no-jdk --platform=linux/arm64,linux/amd64 --push From 9f6cc8e4fc4b1bcbb7239174f33e5470468bbc04 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 21 Nov 2024 00:14:58 +0800 Subject: [PATCH 15/19] Update CONTRIBUTING.md --- CONTRIBUTING.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b68cdccd719..7d99d8b499e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -150,12 +150,8 @@ Tip: you can use `--versions` to list all available versions. * 需要更新 gh-pages 分支下面的 arthas-boot.jar/math-game.jar/as.sh ,下载 doc.zip,解压覆盖掉文档的更新,可以通过 github action 更新: https://github.com/alibaba/arthas/actions/workflows/update-doc.yaml * 需要更新docker镜像,push新的tag:https://hub.docker.com/r/hengyunabc/arthas/tags?page=1&ordering=last_updated - 以 3.6.5 版本为例: - ``` - docker buildx build . --build-arg ARTHAS_VERSION=3.6.5 --build-arg MIRROR=true -t hengyunabc/arthas:3.6.5 -t hengyunabc/arthas:latest --platform=linux/arm64,linux/amd64 --push + 可以通过 github action push: https://github.com/alibaba/arthas/actions/workflows/push-docker.yaml - docker buildx build . --build-arg ARTHAS_VERSION=3.6.5 --build-arg MIRROR=true -f Dockerfile-No-Jdk -t hengyunabc/arthas:3.6.5-no-jdk --platform=linux/arm64,linux/amd64 --push - ``` * 更新README.md,比如增加了新命令,要加上说明,更新wiki的链接 * 更新release页面的 issue信息,修改信息等 * 更新 https://arthas.aliyun.com/api/latest_version api From 375220cb9295ef8c40f146e543b890d97408cfc6 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 21 Nov 2024 17:23:54 +0800 Subject: [PATCH 16/19] support ognl strict. #2955 --- .../com/taobao/arthas/core/GlobalOptions.java | 24 ++++++++++++++++++- .../command/basic1000/OptionsCommand.java | 5 ++++ .../taobao/arthas/core/GlobalOptionsTest.java | 18 ++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 core/src/test/java/com/taobao/arthas/core/GlobalOptionsTest.java diff --git a/core/src/main/java/com/taobao/arthas/core/GlobalOptions.java b/core/src/main/java/com/taobao/arthas/core/GlobalOptions.java index 6e623e00c0c..f9b9f0df36c 100644 --- a/core/src/main/java/com/taobao/arthas/core/GlobalOptions.java +++ b/core/src/main/java/com/taobao/arthas/core/GlobalOptions.java @@ -1,6 +1,11 @@ package com.taobao.arthas.core; +import java.lang.reflect.Field; + import com.taobao.arthas.common.JavaVersionUtils; +import com.taobao.arthas.common.UnsafeUtils; + +import ognl.OgnlRuntime; /** * 全局开关 @@ -128,7 +133,8 @@ public class GlobalOptions { public static volatile boolean verbose = false; /** - * 是否打开strict 开关 + * 是否打开strict 开关。更新时注意 ognl 里的配置需要同步修改 + * @see ognl.OgnlRuntime#getUseStricterInvocationValue() */ @Option(level = 1, name = "strict", @@ -136,4 +142,20 @@ public class GlobalOptions { description = STRICT_MESSAGE ) public static volatile boolean strict = true; + + public static void updateOnglStrict(boolean strict) { + try { + Field field = OgnlRuntime.class.getDeclaredField("_useStricterInvocation"); + field.setAccessible(true); + // 获取字段的内存偏移量和基址 + Object staticFieldBase = UnsafeUtils.UNSAFE.staticFieldBase(field); + long staticFieldOffset = UnsafeUtils.UNSAFE.staticFieldOffset(field); + + // 修改字段的值 + UnsafeUtils.UNSAFE.putBoolean(staticFieldBase, staticFieldOffset, strict); + } catch (NoSuchFieldException | SecurityException e) { + // ignore + } + } + } diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java index 14a0a6174ad..b463975394f 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java @@ -155,6 +155,11 @@ private ExitStatus processChangeNameValue(CommandProcess process) throws Illegal return ExitStatus.failure(-1, format("Options[%s] type[%s] was unsupported.", optionName, type.getSimpleName())); } + // FIXME hack for ongl strict + if (field.getName().equals("strict")) { + GlobalOptions.updateOnglStrict(Boolean.valueOf(optionValue)); + logger.info("update ongl strict to: {}", optionValue); + } } catch (Throwable t) { return ExitStatus.failure(-1, format("Cannot cast option value[%s] to type[%s].", optionValue, type.getSimpleName())); } diff --git a/core/src/test/java/com/taobao/arthas/core/GlobalOptionsTest.java b/core/src/test/java/com/taobao/arthas/core/GlobalOptionsTest.java new file mode 100644 index 00000000000..f915d6c616a --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/GlobalOptionsTest.java @@ -0,0 +1,18 @@ +package com.taobao.arthas.core; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import ognl.OgnlRuntime; + +class GlobalOptionsTest { + + @Test + void test() { + GlobalOptions.updateOnglStrict(true); + Assertions.assertThat(OgnlRuntime.getUseStricterInvocationValue()).isTrue(); + GlobalOptions.updateOnglStrict(false); + Assertions.assertThat(OgnlRuntime.getUseStricterInvocationValue()).isFalse(); + } + +} From 534b822a0bf207249055e5c39dc051a5a75c7f32 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 27 Nov 2024 00:35:15 +0800 Subject: [PATCH 17/19] remove profiler collect action. fix loop NullPointerException #2961 --- .../command/monitor200/ProfilerCommand.java | 38 ++++++++----------- site/docs/doc/profiler.md | 6 +-- site/docs/en/doc/profiler.md | 6 +-- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java index 90e2c14603d..04bc43a2226 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java @@ -38,7 +38,7 @@ import one.profiler.Counter; /** - * + * https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilerOptions.md 具体参数说明,以及哪些参数可以传递给 async-profiler agent * @author hengyunabc 2019-10-31 * */ @@ -524,18 +524,12 @@ public void setChunktime(String chunktime) { @Description("run profiler in a loop (continuous profiling)") public void setLoop(String loop) { this.loop = loop; - if (this.action.equals("collect")) { - this.action = "start"; - } } @Option(longName = "timeout") @Description("automatically stop profiler at TIME (absolute or relative)") public void setTimeout(String timeout) { this.timeout = timeout; - if (this.action.equals("collect")) { - this.action = "start"; - } } @@ -581,11 +575,11 @@ private AsyncProfiler profilerInstance() { } /** - * https://github.com/async-profiler/async-profiler/blob/v2.9/profiler.sh#L154 + * https://github.com/async-profiler/async-profiler/blob/v3.0/src/arguments.cpp#L131 */ public enum ProfilerAction { - // start, resume, stop, dump, check, status, meminfo, list, collect, - start, resume, stop, dump, check, status, meminfo, list, collect, + // start, resume, stop, dump, check, status, meminfo, list, + start, resume, stop, dump, check, status, meminfo, list, version, load, @@ -747,13 +741,16 @@ public void process(final CommandProcess process) { } String result = execute(asyncProfiler, this.actionArg); appendExecuteResult(process, result); - } else if (ProfilerAction.collect.equals(profilerAction)) { - String executeArgs = executeArgs(ProfilerAction.collect); - String result = execute(asyncProfiler, executeArgs); - ProfilerModel profilerModel = createProfilerModel(result); - - if (this.duration != null) { + } else if (ProfilerAction.start.equals(profilerAction)) { + if (this.duration == null) { + String executeArgs = executeArgs(ProfilerAction.start); + String result = execute(asyncProfiler, executeArgs); + appendExecuteResult(process, result); + } else { // 设置延时执行 stop final String outputFile = outputFile(); + String executeArgs = executeArgs(ProfilerAction.start); + String result = execute(asyncProfiler, executeArgs); + ProfilerModel profilerModel = createProfilerModel(result); profilerModel.setOutputFile(outputFile); profilerModel.setDuration(duration); @@ -761,7 +758,7 @@ public void process(final CommandProcess process) { ArthasBootstrap.getInstance().getScheduledExecutorService().schedule(new Runnable() { @Override public void run() { - //在异步线程执行,profiler命令已经结束,不能输出到客户端 + // 在异步线程执行,profiler命令已经结束,不能输出到客户端 try { logger.info("stopping profiler ..."); ProfilerModel model = processStop(asyncProfiler, ProfilerAction.stop); @@ -772,12 +769,9 @@ public void run() { } } }, this.duration, TimeUnit.SECONDS); + process.appendResult(profilerModel); } - process.appendResult(profilerModel); - } else if (ProfilerAction.start.equals(profilerAction)) { - String executeArgs = executeArgs(ProfilerAction.start); - String result = execute(asyncProfiler, executeArgs); - appendExecuteResult(process, result); + } else if (ProfilerAction.stop.equals(profilerAction)) { ProfilerModel profilerModel = processStop(asyncProfiler, profilerAction); process.appendResult(profilerModel); diff --git a/site/docs/doc/profiler.md b/site/docs/doc/profiler.md index 430937f0f3c..8e3bee33f77 100644 --- a/site/docs/doc/profiler.md +++ b/site/docs/doc/profiler.md @@ -228,10 +228,10 @@ profiler stop --include 'java/*' --include 'com/demo/*' --exclude '*Unsafe.park* ## 指定执行时间 -比如,希望 profiler 执行 300 秒自动结束,可以用 `-d`/`--duration` 参数为 collect action 指定时间: +比如,希望 profiler 执行 300 秒自动结束,可以用 `-d`/`--duration` 参数为 start action 指定时间: ```bash -profiler collect --duration 300 +profiler start --duration 300 ``` ## 生成 jfr 格式结果 @@ -383,7 +383,7 @@ profiler start --loop 1h -f /var/log/profile-%t.jfr ## `--timeout` 选项 -这个选项指定 profiling 自动在多久后停止。该选项和 `--loop` 选项的格式一致,可以是时间点,也可以是一个时间间隔。这两个选项都是用于 `start` action 而不是 `collect` action 的。可参考 [async-profiler Github Discussions](https://github.com/async-profiler/async-profiler/discussions/789) 了解更多信息。 +这个选项指定 profiling 自动在多久后停止。该选项和 `--loop` 选项的格式一致,可以是时间点,也可以是一个时间间隔。这两个选项都是用于 `start` action。可参考 [async-profiler docs](https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilerOptions.md) 了解更多信息。 ## `--wall` 选项 diff --git a/site/docs/en/doc/profiler.md b/site/docs/en/doc/profiler.md index d01ad979d39..924278b251d 100644 --- a/site/docs/en/doc/profiler.md +++ b/site/docs/en/doc/profiler.md @@ -228,10 +228,10 @@ profiler stop --include'java/*' --include 'com/demo/*' --exclude'*Unsafe.park*' ## Specify execution time -For example, if you want the profiler to automatically end after 300 seconds, you can specify it with the `-d`/`--duration` parameter in collect action: +For example, if you want the profiler to automatically end after 300 seconds, you can specify it with the `-d`/`--duration` parameter in start action: ```bash -profiler collect --duration 300 +profiler start --duration 300 ``` ## Generate jfr format result @@ -387,7 +387,7 @@ profiler start --loop 1h -f /var/log/profile-%t.jfr This option specifies the time when profiling will automatically stop. The format is the same as in loop: it is either a wall clock time (12:34:56) or a relative time interval (2h). -Both `--loop` and `--timeout` are used for `start` action but not for `collect` action, for further information refer to [async-profiler Github Discussions](https://github.com/async-profiler/async-profiler/discussions/789). +Both `--loop` and `--timeout` are used for `start` action, for further information refer to [async-profiler docs](https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilerOptions.md). ## `--wall` option From 8e4dd907ff26c429b4d0712f5bc22d98adfd58c3 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 27 Nov 2024 00:41:28 +0800 Subject: [PATCH 18/19] log profiler execute args --- .../taobao/arthas/core/command/monitor200/ProfilerCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java index 04bc43a2226..e9f4df108a5 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java @@ -714,6 +714,7 @@ private String executeArgs(ProfilerAction action) { private static String execute(AsyncProfiler asyncProfiler, String arg) throws IllegalArgumentException, IOException { + logger.info("profiler execute args: {}", arg); String result = asyncProfiler.execute(arg); if (!result.endsWith("\n")) { result += "\n"; From 3bc5053c698491f52d410d19183d7372d8522004 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 27 Nov 2024 02:39:12 +0000 Subject: [PATCH 19/19] Prettified Code! --- site/docs/.vuepress/theme/components/NavbarDropdown.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/site/docs/.vuepress/theme/components/NavbarDropdown.vue b/site/docs/.vuepress/theme/components/NavbarDropdown.vue index 4aabb7f1d0c..512388a8f01 100644 --- a/site/docs/.vuepress/theme/components/NavbarDropdown.vue +++ b/site/docs/.vuepress/theme/components/NavbarDropdown.vue @@ -86,8 +86,8 @@ const isLastItemOfArray = (item, arr) => arr[arr.length - 1] === item; :item="child" @focusout=" isLastItemOfArray(child, item.children) && - child.children.length === 0 && - (open = false) + child.children.length === 0 && + (open = false) " /> @@ -104,8 +104,8 @@ const isLastItemOfArray = (item, arr) => arr[arr.length - 1] === item; :item="grandchild" @focusout=" isLastItemOfArray(grandchild, child.children) && - isLastItemOfArray(child, item.children) && - (open = false) + isLastItemOfArray(child, item.children) && + (open = false) " />