Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Administrator
Arthas
Commits
5d7c4150
Commit
5d7c4150
authored
Dec 21, 2023
by
shengnan hu
Browse files
init
parents
Pipeline
#4715
failed with stage
in 30 seconds
Changes
457
Pipelines
620
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1248 additions
and
0 deletions
+1248
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java
.../taobao/arthas/core/command/basic1000/OptionsCommand.java
+232
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/PwdCommand.java
.../com/taobao/arthas/core/command/basic1000/PwdCommand.java
+20
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/ResetCommand.java
...om/taobao/arthas/core/command/basic1000/ResetCommand.java
+60
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java
.../taobao/arthas/core/command/basic1000/SessionCommand.java
+49
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/StopCommand.java
...com/taobao/arthas/core/command/basic1000/StopCommand.java
+42
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/SystemEnvCommand.java
...aobao/arthas/core/command/basic1000/SystemEnvCommand.java
+63
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/SystemPropertyCommand.java
.../arthas/core/command/basic1000/SystemPropertyCommand.java
+77
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/TeeCommand.java
.../com/taobao/arthas/core/command/basic1000/TeeCommand.java
+47
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java
...taobao/arthas/core/command/basic1000/VMOptionCommand.java
+110
-0
core/src/main/java/com/taobao/arthas/core/command/basic1000/VersionCommand.java
.../taobao/arthas/core/command/basic1000/VersionCommand.java
+28
-0
core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java
...as/core/command/express/ArthasObjectPropertyAccessor.java
+25
-0
core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java
...arthas/core/command/express/ClassLoaderClassResolver.java
+45
-0
core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java
...obao/arthas/core/command/express/CustomClassResolver.java
+43
-0
core/src/main/java/com/taobao/arthas/core/command/express/Express.java
.../java/com/taobao/arthas/core/command/express/Express.java
+52
-0
core/src/main/java/com/taobao/arthas/core/command/express/ExpressException.java
.../taobao/arthas/core/command/express/ExpressException.java
+30
-0
core/src/main/java/com/taobao/arthas/core/command/express/ExpressFactory.java
...om/taobao/arthas/core/command/express/ExpressFactory.java
+33
-0
core/src/main/java/com/taobao/arthas/core/command/express/OgnlExpress.java
...a/com/taobao/arthas/core/command/express/OgnlExpress.java
+73
-0
core/src/main/java/com/taobao/arthas/core/command/hidden/JulyCommand.java
...va/com/taobao/arthas/core/command/hidden/JulyCommand.java
+105
-0
core/src/main/java/com/taobao/arthas/core/command/hidden/ThanksCommand.java
.../com/taobao/arthas/core/command/hidden/ThanksCommand.java
+24
-0
core/src/main/java/com/taobao/arthas/core/command/klass100/ClassDumpTransformer.java
...ao/arthas/core/command/klass100/ClassDumpTransformer.java
+90
-0
No files found.
Too many changes to show.
To preserve performance only
457 of 457+
files are displayed.
Plain diff
Email patch
core/src/main/java/com/taobao/arthas/core/command/basic1000/OptionsCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.GlobalOptions
;
import
com.taobao.arthas.core.Option
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.ChangeResultVO
;
import
com.taobao.arthas.core.command.model.OptionVO
;
import
com.taobao.arthas.core.command.model.OptionsModel
;
import
com.taobao.arthas.core.shell.cli.CliToken
;
import
com.taobao.arthas.core.shell.cli.Completion
;
import
com.taobao.arthas.core.shell.cli.CompletionUtils
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.shell.command.ExitStatus
;
import
com.taobao.arthas.core.util.CommandUtils
;
import
com.taobao.arthas.core.util.StringUtils
;
import
com.taobao.arthas.core.util.TokenUtils
;
import
com.taobao.arthas.core.util.matcher.EqualsMatcher
;
import
com.taobao.arthas.core.util.matcher.Matcher
;
import
com.taobao.arthas.core.util.matcher.RegexMatcher
;
import
com.taobao.arthas.core.util.reflect.FieldUtils
;
import
com.taobao.middleware.cli.annotations.Argument
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
static
com
.
taobao
.
arthas
.
core
.
util
.
ArthasCheckUtils
.
isIn
;
import
static
java
.
lang
.
String
.
format
;
/**
* 选项开关命令
*
* @author vlinux on 15/6/6.
*/
// @formatter:off
@Name
(
"options"
)
@Summary
(
"View and change various Arthas options"
)
@Description
(
Constants
.
EXAMPLE
+
"options # list all options\n"
+
"options json-format true\n"
+
"options dump true\n"
+
"options unsafe true\n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"options"
)
//@formatter:on
public
class
OptionsCommand
extends
AnnotatedCommand
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
OptionsCommand
.
class
);
private
String
optionName
;
private
String
optionValue
;
@Argument
(
index
=
0
,
argName
=
"options-name"
,
required
=
false
)
@Description
(
"Option name"
)
public
void
setOptionName
(
String
optionName
)
{
this
.
optionName
=
optionName
;
}
@Argument
(
index
=
1
,
argName
=
"options-value"
,
required
=
false
)
@Description
(
"Option value"
)
public
void
setOptionValue
(
String
optionValue
)
{
this
.
optionValue
=
optionValue
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
try
{
ExitStatus
status
=
null
;
if
(
isShow
())
{
status
=
processShow
(
process
);
}
else
if
(
isShowName
())
{
status
=
processShowName
(
process
);
}
else
{
status
=
processChangeNameValue
(
process
);
}
CommandUtils
.
end
(
process
,
status
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"processing error"
,
t
);
process
.
end
(-
1
,
"processing error"
);
}
}
/**
* complete first argument(options-name), other case use default complete
*
* @param completion the completion object
*/
@Override
public
void
complete
(
Completion
completion
)
{
int
argumentIndex
=
CompletionUtils
.
detectArgumentIndex
(
completion
);
List
<
CliToken
>
lineTokens
=
completion
.
lineTokens
();
if
(
argumentIndex
==
1
)
{
String
laseToken
=
TokenUtils
.
getLast
(
lineTokens
).
value
().
trim
();
//prefix match options-name
String
pattern
=
"^"
+
laseToken
+
".*"
;
Collection
<
String
>
optionNames
=
findOptionNames
(
new
RegexMatcher
(
pattern
));
CompletionUtils
.
complete
(
completion
,
optionNames
);
}
else
{
super
.
complete
(
completion
);
}
}
private
ExitStatus
processShow
(
CommandProcess
process
)
throws
IllegalAccessException
{
Collection
<
Field
>
fields
=
findOptionFields
(
new
RegexMatcher
(
".*"
));
process
.
appendResult
(
new
OptionsModel
(
convertToOptionVOs
(
fields
)));
return
ExitStatus
.
success
();
}
private
ExitStatus
processShowName
(
CommandProcess
process
)
throws
IllegalAccessException
{
Collection
<
Field
>
fields
=
findOptionFields
(
new
EqualsMatcher
<
String
>(
optionName
));
process
.
appendResult
(
new
OptionsModel
(
convertToOptionVOs
(
fields
)));
return
ExitStatus
.
success
();
}
private
ExitStatus
processChangeNameValue
(
CommandProcess
process
)
throws
IllegalAccessException
{
Collection
<
Field
>
fields
=
findOptionFields
(
new
EqualsMatcher
<
String
>(
optionName
));
// name not exists
if
(
fields
.
isEmpty
())
{
return
ExitStatus
.
failure
(-
1
,
format
(
"options[%s] not found."
,
optionName
));
}
Field
field
=
fields
.
iterator
().
next
();
Option
optionAnnotation
=
field
.
getAnnotation
(
Option
.
class
);
Class
<?>
type
=
field
.
getType
();
Object
beforeValue
=
FieldUtils
.
readStaticField
(
field
);
Object
afterValue
;
try
{
// try to case string to type
if
(
isIn
(
type
,
int
.
class
,
Integer
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Integer
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
long
.
class
,
Long
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Long
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
boolean
.
class
,
Boolean
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Boolean
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
double
.
class
,
Double
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Double
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
float
.
class
,
Float
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Float
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
byte
.
class
,
Byte
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Byte
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
short
.
class
,
Short
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
Short
.
valueOf
(
optionValue
));
}
else
if
(
isIn
(
type
,
short
.
class
,
String
.
class
))
{
FieldUtils
.
writeStaticField
(
field
,
afterValue
=
optionValue
);
}
else
{
return
ExitStatus
.
failure
(-
1
,
format
(
"Options[%s] type[%s] was unsupported."
,
optionName
,
type
.
getSimpleName
()));
}
}
catch
(
Throwable
t
)
{
return
ExitStatus
.
failure
(-
1
,
format
(
"Cannot cast option value[%s] to type[%s]."
,
optionValue
,
type
.
getSimpleName
()));
}
ChangeResultVO
changeResultVO
=
new
ChangeResultVO
(
optionAnnotation
.
name
(),
beforeValue
,
afterValue
);
process
.
appendResult
(
new
OptionsModel
(
changeResultVO
));
return
ExitStatus
.
success
();
}
/**
* 判断当前动作是否需要展示整个options
*/
private
boolean
isShow
()
{
return
StringUtils
.
isBlank
(
optionName
)
&&
StringUtils
.
isBlank
(
optionValue
);
}
/**
* 判断当前动作是否需要展示某个Name的值
*/
private
boolean
isShowName
()
{
return
!
StringUtils
.
isBlank
(
optionName
)
&&
StringUtils
.
isBlank
(
optionValue
);
}
private
Collection
<
Field
>
findOptionFields
(
Matcher
<
String
>
optionNameMatcher
)
{
final
Collection
<
Field
>
matchFields
=
new
ArrayList
<
Field
>();
for
(
final
Field
optionField
:
FieldUtils
.
getAllFields
(
GlobalOptions
.
class
))
{
if
(
isMatchOptionAnnotation
(
optionField
,
optionNameMatcher
))
{
matchFields
.
add
(
optionField
);
}
}
return
matchFields
;
}
private
Collection
<
String
>
findOptionNames
(
Matcher
<
String
>
optionNameMatcher
)
{
final
Collection
<
String
>
matchOptionNames
=
new
ArrayList
<
String
>();
for
(
final
Field
optionField
:
FieldUtils
.
getAllFields
(
GlobalOptions
.
class
))
{
if
(
isMatchOptionAnnotation
(
optionField
,
optionNameMatcher
))
{
final
Option
optionAnnotation
=
optionField
.
getAnnotation
(
Option
.
class
);
matchOptionNames
.
add
(
optionAnnotation
.
name
());
}
}
return
matchOptionNames
;
}
private
boolean
isMatchOptionAnnotation
(
Field
optionField
,
Matcher
<
String
>
optionNameMatcher
)
{
if
(!
optionField
.
isAnnotationPresent
(
Option
.
class
))
{
return
false
;
}
final
Option
optionAnnotation
=
optionField
.
getAnnotation
(
Option
.
class
);
return
optionAnnotation
!=
null
&&
optionNameMatcher
.
matching
(
optionAnnotation
.
name
());
}
private
List
<
OptionVO
>
convertToOptionVOs
(
Collection
<
Field
>
fields
)
throws
IllegalAccessException
{
List
<
OptionVO
>
list
=
new
ArrayList
<
OptionVO
>();
for
(
Field
field
:
fields
)
{
list
.
add
(
convertToOptionVO
(
field
));
}
return
list
;
}
private
OptionVO
convertToOptionVO
(
Field
optionField
)
throws
IllegalAccessException
{
Option
optionAnnotation
=
optionField
.
getAnnotation
(
Option
.
class
);
OptionVO
optionVO
=
new
OptionVO
();
optionVO
.
setLevel
(
optionAnnotation
.
level
());
optionVO
.
setName
(
optionAnnotation
.
name
());
optionVO
.
setSummary
(
optionAnnotation
.
summary
());
optionVO
.
setDescription
(
optionAnnotation
.
description
());
optionVO
.
setType
(
optionField
.
getType
().
getSimpleName
());
optionVO
.
setValue
(
""
+
optionField
.
get
(
null
));
return
optionVO
;
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/PwdCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
java.io.File
;
import
com.taobao.arthas.core.command.model.PwdModel
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
@Name
(
"pwd"
)
@Summary
(
"Return working directory name"
)
public
class
PwdCommand
extends
AnnotatedCommand
{
@Override
public
void
process
(
CommandProcess
process
)
{
String
path
=
new
File
(
""
).
getAbsolutePath
();
process
.
appendResult
(
new
PwdModel
(
path
));
process
.
end
();
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/ResetCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.advisor.Enhancer
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.ResetModel
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.matcher.Matcher
;
import
com.taobao.arthas.core.util.SearchUtils
;
import
com.taobao.arthas.core.util.affect.EnhancerAffect
;
import
com.taobao.middleware.cli.annotations.Argument
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Option
;
import
com.taobao.middleware.cli.annotations.Summary
;
import
java.lang.instrument.Instrumentation
;
import
java.lang.instrument.UnmodifiableClassException
;
/**
* 恢复所有增强类<br/>
*
* @author vlinux on 15/5/29.
*/
@Name
(
"reset"
)
@Summary
(
"Reset all the enhanced classes"
)
@Description
(
Constants
.
EXAMPLE
+
" reset\n"
+
" reset *List\n"
+
" reset -E .*List\n"
)
public
class
ResetCommand
extends
AnnotatedCommand
{
private
String
classPattern
;
private
boolean
isRegEx
=
false
;
@Argument
(
index
=
0
,
argName
=
"class-pattern"
,
required
=
false
)
@Description
(
"Path and classname of Pattern Matching"
)
public
void
setClassPattern
(
String
classPattern
)
{
this
.
classPattern
=
classPattern
;
}
@Option
(
shortName
=
"E"
,
longName
=
"regex"
,
flag
=
true
)
@Description
(
"Enable regular expression to match (wildcard matching by default)"
)
public
void
setRegEx
(
boolean
regEx
)
{
isRegEx
=
regEx
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
Instrumentation
inst
=
process
.
session
().
getInstrumentation
();
Matcher
matcher
=
SearchUtils
.
classNameMatcher
(
classPattern
,
isRegEx
);
try
{
EnhancerAffect
enhancerAffect
=
Enhancer
.
reset
(
inst
,
matcher
);
process
.
appendResult
(
new
ResetModel
(
enhancerAffect
));
process
.
end
();
}
catch
(
UnmodifiableClassException
e
)
{
// ignore
process
.
end
();
}
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.command.model.SessionModel
;
import
com.taobao.arthas.core.server.ArthasBootstrap
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.shell.session.Session
;
import
com.taobao.arthas.core.util.UserStatUtil
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
import
com.alibaba.arthas.tunnel.client.TunnelClient
;
/**
* 查看会话状态命令
*
* @author vlinux on 15/5/3.
*/
@Name
(
"session"
)
@Summary
(
"Display current session information"
)
public
class
SessionCommand
extends
AnnotatedCommand
{
@Override
public
void
process
(
CommandProcess
process
)
{
SessionModel
result
=
new
SessionModel
();
Session
session
=
process
.
session
();
result
.
setJavaPid
(
session
.
getPid
());
result
.
setSessionId
(
session
.
getSessionId
());
//tunnel
TunnelClient
tunnelClient
=
ArthasBootstrap
.
getInstance
().
getTunnelClient
();
if
(
tunnelClient
!=
null
)
{
String
id
=
tunnelClient
.
getId
();
if
(
id
!=
null
)
{
result
.
setAgentId
(
id
);
}
result
.
setTunnelServer
(
tunnelClient
.
getTunnelServerUrl
());
result
.
setTunnelConnected
(
tunnelClient
.
isConnected
());
}
//statUrl
String
statUrl
=
UserStatUtil
.
getStatUrl
();
result
.
setStatUrl
(
statUrl
);
process
.
appendResult
(
result
);
process
.
end
();
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/StopCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.taobao.arthas.core.command.model.MessageModel
;
import
com.taobao.arthas.core.command.model.ResetModel
;
import
com.taobao.arthas.core.command.model.ShutdownModel
;
import
com.taobao.arthas.core.server.ArthasBootstrap
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.affect.EnhancerAffect
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* @author hengyunabc 2019-07-05
*/
@Name
(
"stop"
)
@Summary
(
"Stop/Shutdown Arthas server and exit the console."
)
public
class
StopCommand
extends
AnnotatedCommand
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
StopCommand
.
class
);
@Override
public
void
process
(
CommandProcess
process
)
{
shutdown
(
process
);
}
private
static
void
shutdown
(
CommandProcess
process
)
{
ArthasBootstrap
arthasBootstrap
=
ArthasBootstrap
.
getInstance
();
try
{
// 退出之前需要重置所有的增强类
process
.
appendResult
(
new
MessageModel
(
"Resetting all enhanced classes ..."
));
EnhancerAffect
enhancerAffect
=
arthasBootstrap
.
reset
();
process
.
appendResult
(
new
ResetModel
(
enhancerAffect
));
process
.
appendResult
(
new
ShutdownModel
(
true
,
"Arthas Server is going to shutdown..."
));
}
catch
(
Throwable
e
)
{
logger
.
error
(
"An error occurred when stopping arthas server."
,
e
);
process
.
appendResult
(
new
ShutdownModel
(
false
,
"An error occurred when stopping arthas server."
));
}
finally
{
process
.
end
();
arthasBootstrap
.
destroy
();
}
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/SystemEnvCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.SystemEnvModel
;
import
com.taobao.arthas.core.shell.cli.Completion
;
import
com.taobao.arthas.core.shell.cli.CompletionUtils
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.StringUtils
;
import
com.taobao.middleware.cli.annotations.Argument
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* @author hengyunabc 2018-11-09
*
*/
@Name
(
"sysenv"
)
@Summary
(
"Display the system env."
)
@Description
(
Constants
.
EXAMPLE
+
" sysenv\n"
+
" sysenv USER\n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"sysenv"
)
public
class
SystemEnvCommand
extends
AnnotatedCommand
{
private
String
envName
;
@Argument
(
index
=
0
,
argName
=
"env-name"
,
required
=
false
)
@Description
(
"env name"
)
public
void
setOptionName
(
String
envName
)
{
this
.
envName
=
envName
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
try
{
SystemEnvModel
result
=
new
SystemEnvModel
();
if
(
StringUtils
.
isBlank
(
envName
))
{
// show all system env
result
.
putAll
(
System
.
getenv
());
}
else
{
// view the specified system env
String
value
=
System
.
getenv
(
envName
);
result
.
put
(
envName
,
value
);
}
process
.
appendResult
(
result
);
process
.
end
();
}
catch
(
Throwable
t
)
{
process
.
end
(-
1
,
"Error during setting system env: "
+
t
.
getMessage
());
}
}
/**
* First, try to complete with the sysenv command scope. If completion is
* failed, delegates to super class.
*
* @param completion
* the completion object
*/
@Override
public
void
complete
(
Completion
completion
)
{
CompletionUtils
.
complete
(
completion
,
System
.
getenv
().
keySet
());
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/SystemPropertyCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.MessageModel
;
import
com.taobao.arthas.core.command.model.SystemPropertyModel
;
import
com.taobao.arthas.core.shell.cli.Completion
;
import
com.taobao.arthas.core.shell.cli.CompletionUtils
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.StringUtils
;
import
com.taobao.middleware.cli.annotations.Argument
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* @author ralf0131 2017-01-09 14:03.
*/
@Name
(
"sysprop"
)
@Summary
(
"Display, and change the system properties."
)
@Description
(
Constants
.
EXAMPLE
+
" sysprop\n"
+
" sysprop file.encoding\n"
+
" sysprop production.mode true\n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"sysprop"
)
public
class
SystemPropertyCommand
extends
AnnotatedCommand
{
private
String
propertyName
;
private
String
propertyValue
;
@Argument
(
index
=
0
,
argName
=
"property-name"
,
required
=
false
)
@Description
(
"property name"
)
public
void
setOptionName
(
String
propertyName
)
{
this
.
propertyName
=
propertyName
;
}
@Argument
(
index
=
1
,
argName
=
"property-value"
,
required
=
false
)
@Description
(
"property value"
)
public
void
setOptionValue
(
String
propertyValue
)
{
this
.
propertyValue
=
propertyValue
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
try
{
if
(
StringUtils
.
isBlank
(
propertyName
)
&&
StringUtils
.
isBlank
(
propertyValue
))
{
// show all system properties
process
.
appendResult
(
new
SystemPropertyModel
(
System
.
getProperties
()));
}
else
if
(
StringUtils
.
isBlank
(
propertyValue
))
{
// view the specified system property
String
value
=
System
.
getProperty
(
propertyName
);
if
(
value
==
null
)
{
process
.
end
(
1
,
"There is no property with the key "
+
propertyName
);
return
;
}
else
{
process
.
appendResult
(
new
SystemPropertyModel
(
propertyName
,
value
));
}
}
else
{
// change system property
System
.
setProperty
(
propertyName
,
propertyValue
);
process
.
appendResult
(
new
MessageModel
(
"Successfully changed the system property."
));
process
.
appendResult
(
new
SystemPropertyModel
(
propertyName
,
System
.
getProperty
(
propertyName
)));
}
process
.
end
();
}
catch
(
Throwable
t
)
{
process
.
end
(-
1
,
"Error during setting system property: "
+
t
.
getMessage
());
}
}
/**
* First, try to complete with the sysprop command scope.
* If completion is failed, delegates to super class.
* @param completion the completion object
*/
@Override
public
void
complete
(
Completion
completion
)
{
CompletionUtils
.
complete
(
completion
,
System
.
getProperties
().
stringPropertyNames
());
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/TeeCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.middleware.cli.annotations.*
;
/**
* @author min.yang
*/
@Name
(
"tee"
)
@Summary
(
"tee command for pipes."
)
@Description
(
Constants
.
EXAMPLE
+
" sysprop | tee /path/to/logfile | grep java \n"
+
" sysprop | tee -a /path/to/logfile | grep java \n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"tee"
)
public
class
TeeCommand
extends
AnnotatedCommand
{
private
String
filePath
;
private
boolean
append
;
@Argument
(
index
=
0
,
argName
=
"file"
,
required
=
false
)
@Description
(
"File path"
)
public
void
setFilePath
(
String
filePath
)
{
this
.
filePath
=
filePath
;
}
@Option
(
shortName
=
"a"
,
longName
=
"append"
,
flag
=
true
)
@Description
(
"Append to file"
)
public
void
setRegEx
(
boolean
append
)
{
this
.
append
=
append
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
process
.
end
(-
1
,
"The tee command only for pipes. See 'tee --help'"
);
}
public
String
getFilePath
()
{
return
filePath
;
}
public
boolean
isAppend
()
{
return
append
;
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
java.lang.management.ManagementFactory
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.sun.management.HotSpotDiagnosticMXBean
;
import
com.sun.management.VMOption
;
import
com.taobao.arthas.core.command.Constants
;
import
com.taobao.arthas.core.command.model.ChangeResultVO
;
import
com.taobao.arthas.core.command.model.MessageModel
;
import
com.taobao.arthas.core.command.model.VMOptionModel
;
import
com.taobao.arthas.core.shell.cli.Completion
;
import
com.taobao.arthas.core.shell.cli.CompletionUtils
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.StringUtils
;
import
com.taobao.middleware.cli.annotations.Argument
;
import
com.taobao.middleware.cli.annotations.Description
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* vmoption command
*
* @author hengyunabc 2019-09-02
*
*/
// @formatter:off
@Name
(
"vmoption"
)
@Summary
(
"Display, and update the vm diagnostic options."
)
@Description
(
"\nExamples:\n"
+
" vmoption\n"
+
" vmoption PrintGC\n"
+
" vmoption PrintGC true\n"
+
" vmoption PrintGCDetails true\n"
+
Constants
.
WIKI
+
Constants
.
WIKI_HOME
+
"vmoption"
)
//@formatter:on
public
class
VMOptionCommand
extends
AnnotatedCommand
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
VMOptionCommand
.
class
);
private
String
name
;
private
String
value
;
@Argument
(
index
=
0
,
argName
=
"name"
,
required
=
false
)
@Description
(
"VMOption name"
)
public
void
setOptionName
(
String
name
)
{
this
.
name
=
name
;
}
@Argument
(
index
=
1
,
argName
=
"value"
,
required
=
false
)
@Description
(
"VMOption value"
)
public
void
setOptionValue
(
String
value
)
{
this
.
value
=
value
;
}
@Override
public
void
process
(
CommandProcess
process
)
{
run
(
process
,
name
,
value
);
}
private
static
void
run
(
CommandProcess
process
,
String
name
,
String
value
)
{
try
{
HotSpotDiagnosticMXBean
hotSpotDiagnosticMXBean
=
ManagementFactory
.
getPlatformMXBean
(
HotSpotDiagnosticMXBean
.
class
);
if
(
StringUtils
.
isBlank
(
name
)
&&
StringUtils
.
isBlank
(
value
))
{
// show all options
process
.
appendResult
(
new
VMOptionModel
(
hotSpotDiagnosticMXBean
.
getDiagnosticOptions
()));
}
else
if
(
StringUtils
.
isBlank
(
value
))
{
// view the specified option
VMOption
option
=
hotSpotDiagnosticMXBean
.
getVMOption
(
name
);
if
(
option
==
null
)
{
process
.
end
(-
1
,
"In order to change the system properties, you must specify the property value."
);
return
;
}
else
{
process
.
appendResult
(
new
VMOptionModel
(
Collections
.
singletonList
(
option
)));
}
}
else
{
VMOption
vmOption
=
hotSpotDiagnosticMXBean
.
getVMOption
(
name
);
String
originValue
=
vmOption
.
getValue
();
// change vm option
hotSpotDiagnosticMXBean
.
setVMOption
(
name
,
value
);
process
.
appendResult
(
new
MessageModel
(
"Successfully updated the vm option."
));
process
.
appendResult
(
new
VMOptionModel
(
new
ChangeResultVO
(
name
,
originValue
,
hotSpotDiagnosticMXBean
.
getVMOption
(
name
).
getValue
())));
}
process
.
end
();
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Error during setting vm option"
,
t
);
process
.
end
(-
1
,
"Error during setting vm option: "
+
t
.
getMessage
());
}
}
@Override
public
void
complete
(
Completion
completion
)
{
HotSpotDiagnosticMXBean
hotSpotDiagnosticMXBean
=
ManagementFactory
.
getPlatformMXBean
(
HotSpotDiagnosticMXBean
.
class
);
List
<
VMOption
>
diagnosticOptions
=
hotSpotDiagnosticMXBean
.
getDiagnosticOptions
();
List
<
String
>
names
=
new
ArrayList
<
String
>(
diagnosticOptions
.
size
());
for
(
VMOption
option
:
diagnosticOptions
)
{
names
.
add
(
option
.
getName
());
}
CompletionUtils
.
complete
(
completion
,
names
);
}
}
core/src/main/java/com/taobao/arthas/core/command/basic1000/VersionCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.basic1000
;
import
com.taobao.arthas.core.command.model.VersionModel
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.ArthasBanner
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* 输出版本
*
* @author vlinux
*/
@Name
(
"version"
)
@Summary
(
"Display Arthas version"
)
public
class
VersionCommand
extends
AnnotatedCommand
{
@Override
public
void
process
(
CommandProcess
process
)
{
VersionModel
result
=
new
VersionModel
();
result
.
setVersion
(
ArthasBanner
.
version
());
process
.
appendResult
(
result
);
process
.
end
();
}
}
core/src/main/java/com/taobao/arthas/core/command/express/ArthasObjectPropertyAccessor.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
import
java.util.Map
;
import
com.taobao.arthas.core.GlobalOptions
;
import
ognl.ObjectPropertyAccessor
;
import
ognl.OgnlException
;
/**
*
* @author hengyunabc 2022-03-24
*
*/
public
class
ArthasObjectPropertyAccessor
extends
ObjectPropertyAccessor
{
@Override
public
Object
setPossibleProperty
(
Map
context
,
Object
target
,
String
name
,
Object
value
)
throws
OgnlException
{
if
(
GlobalOptions
.
strict
)
{
throw
new
IllegalAccessError
(
GlobalOptions
.
STRICT_MESSAGE
);
}
return
super
.
setPossibleProperty
(
context
,
target
,
name
,
value
);
}
}
core/src/main/java/com/taobao/arthas/core/command/express/ClassLoaderClassResolver.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
ognl.ClassResolver
;
/**
*
* @author hengyunabc 2018-10-18
* @see ognl.DefaultClassResolver
*/
public
class
ClassLoaderClassResolver
implements
ClassResolver
{
private
ClassLoader
classLoader
;
private
Map
<
String
,
Class
<?>>
classes
=
new
ConcurrentHashMap
<
String
,
Class
<?>>(
101
);
public
ClassLoaderClassResolver
(
ClassLoader
classLoader
)
{
this
.
classLoader
=
classLoader
;
}
@Override
public
Class
<?>
classForName
(
String
className
,
@SuppressWarnings
(
"rawtypes"
)
Map
context
)
throws
ClassNotFoundException
{
Class
<?>
result
=
null
;
if
((
result
=
classes
.
get
(
className
))
==
null
)
{
try
{
result
=
classLoader
.
loadClass
(
className
);
}
catch
(
ClassNotFoundException
ex
)
{
if
(
className
.
indexOf
(
'.'
)
==
-
1
)
{
result
=
Class
.
forName
(
"java.lang."
+
className
);
classes
.
put
(
"java.lang."
+
className
,
result
);
}
}
if
(
result
==
null
)
{
return
null
;
}
classes
.
put
(
className
,
result
);
}
return
result
;
}
}
core/src/main/java/com/taobao/arthas/core/command/express/CustomClassResolver.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
import
ognl.ClassResolver
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* @author diecui1202 on 2017/9/29.
* @see ognl.DefaultClassResolver
*/
public
class
CustomClassResolver
implements
ClassResolver
{
public
static
final
CustomClassResolver
customClassResolver
=
new
CustomClassResolver
();
private
Map
<
String
,
Class
<?>>
classes
=
new
ConcurrentHashMap
<
String
,
Class
<?>>(
101
);
private
CustomClassResolver
()
{
}
public
Class
<?>
classForName
(
String
className
,
Map
context
)
throws
ClassNotFoundException
{
Class
<?>
result
=
null
;
if
((
result
=
classes
.
get
(
className
))
==
null
)
{
try
{
ClassLoader
classLoader
=
Thread
.
currentThread
().
getContextClassLoader
();
if
(
classLoader
!=
null
)
{
result
=
classLoader
.
loadClass
(
className
);
}
else
{
result
=
Class
.
forName
(
className
);
}
}
catch
(
ClassNotFoundException
ex
)
{
if
(
className
.
indexOf
(
'.'
)
==
-
1
)
{
result
=
Class
.
forName
(
"java.lang."
+
className
);
classes
.
put
(
"java.lang."
+
className
,
result
);
}
}
classes
.
put
(
className
,
result
);
}
return
result
;
}
}
core/src/main/java/com/taobao/arthas/core/command/express/Express.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
/**
* 表达式
* Created by vlinux on 15/5/20.
*/
public
interface
Express
{
/**
* 根据表达式获取值
*
* @param express 表达式
* @return 表达式运算后的值
* @throws ExpressException 表达式运算出错
*/
Object
get
(
String
express
)
throws
ExpressException
;
/**
* 根据表达式判断是与否
*
* @param express 表达式
* @return 表达式运算后的布尔值
* @throws ExpressException 表达式运算出错
*/
boolean
is
(
String
express
)
throws
ExpressException
;
/**
* 绑定对象
*
* @param object 待绑定对象
* @return this
*/
Express
bind
(
Object
object
);
/**
* 绑定变量
*
* @param name 变量名
* @param value 变量值
* @return this
*/
Express
bind
(
String
name
,
Object
value
);
/**
* 重置整个表达式
*
* @return this
*/
Express
reset
();
}
core/src/main/java/com/taobao/arthas/core/command/express/ExpressException.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
/**
* 表达式异常
* Created by vlinux on 15/5/20.
*/
public
class
ExpressException
extends
Exception
{
private
final
String
express
;
/**
* 表达式异常
*
* @param express 原始表达式
* @param cause 异常原因
*/
public
ExpressException
(
String
express
,
Throwable
cause
)
{
super
(
cause
);
this
.
express
=
express
;
}
/**
* 获取表达式
*
* @return 返回出问题的表达式
*/
public
String
getExpress
()
{
return
express
;
}
}
core/src/main/java/com/taobao/arthas/core/command/express/ExpressFactory.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
/**
* ExpressFactory
* @author ralf0131 2017-01-04 14:40.
* @author hengyunabc 2018-10-08
*/
public
class
ExpressFactory
{
private
static
final
ThreadLocal
<
Express
>
expressRef
=
new
ThreadLocal
<
Express
>()
{
@Override
protected
Express
initialValue
()
{
return
new
OgnlExpress
();
}
};
/**
* get ThreadLocal Express Object
* @param object
* @return
*/
public
static
Express
threadLocalExpress
(
Object
object
)
{
return
expressRef
.
get
().
reset
().
bind
(
object
);
}
public
static
Express
unpooledExpress
(
ClassLoader
classloader
)
{
if
(
classloader
==
null
)
{
classloader
=
ClassLoader
.
getSystemClassLoader
();
}
return
new
OgnlExpress
(
new
ClassLoaderClassResolver
(
classloader
));
}
}
\ No newline at end of file
core/src/main/java/com/taobao/arthas/core/command/express/OgnlExpress.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.express
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
ognl.ClassResolver
;
import
ognl.DefaultMemberAccess
;
import
ognl.MemberAccess
;
import
ognl.Ognl
;
import
ognl.OgnlContext
;
import
ognl.OgnlRuntime
;
/**
* @author ralf0131 2017-01-04 14:41.
* @author hengyunabc 2018-10-18
*/
public
class
OgnlExpress
implements
Express
{
private
static
final
MemberAccess
MEMBER_ACCESS
=
new
DefaultMemberAccess
(
true
);
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
OgnlExpress
.
class
);
private
static
final
ArthasObjectPropertyAccessor
OBJECT_PROPERTY_ACCESSOR
=
new
ArthasObjectPropertyAccessor
();
private
Object
bindObject
;
private
final
OgnlContext
context
;
public
OgnlExpress
()
{
this
(
CustomClassResolver
.
customClassResolver
);
}
public
OgnlExpress
(
ClassResolver
classResolver
)
{
OgnlRuntime
.
setPropertyAccessor
(
Object
.
class
,
OBJECT_PROPERTY_ACCESSOR
);
context
=
new
OgnlContext
();
context
.
setClassResolver
(
classResolver
);
// allow private field access
context
.
setMemberAccess
(
MEMBER_ACCESS
);
}
@Override
public
Object
get
(
String
express
)
throws
ExpressException
{
try
{
return
Ognl
.
getValue
(
express
,
context
,
bindObject
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"Error during evaluating the expression:"
,
e
);
throw
new
ExpressException
(
express
,
e
);
}
}
@Override
public
boolean
is
(
String
express
)
throws
ExpressException
{
final
Object
ret
=
get
(
express
);
return
ret
instanceof
Boolean
&&
(
Boolean
)
ret
;
}
@Override
public
Express
bind
(
Object
object
)
{
this
.
bindObject
=
object
;
return
this
;
}
@Override
public
Express
bind
(
String
name
,
Object
value
)
{
context
.
put
(
name
,
value
);
return
this
;
}
@Override
public
Express
reset
()
{
context
.
clear
();
context
.
setClassResolver
(
CustomClassResolver
.
customClassResolver
);
// allow private field access
context
.
setMemberAccess
(
MEMBER_ACCESS
);
return
this
;
}
}
core/src/main/java/com/taobao/arthas/core/command/hidden/JulyCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.hidden
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.middleware.cli.annotations.Hidden
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* @author vlinux on 02/11/2016.
*/
@Name
(
"july"
)
@Summary
(
"don't ask why"
)
@Hidden
public
class
JulyCommand
extends
AnnotatedCommand
{
@Override
public
void
process
(
CommandProcess
process
)
{
process
.
write
(
new
String
(
$$
())).
write
(
"\n"
).
end
();
}
private
static
byte
[]
$$
()
{
return
new
byte
[]{
0x49
,
0x20
,
0x77
,
0x69
,
0x6c
,
0x6c
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x6d
,
0x61
,
0x6b
,
0x65
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x61
,
0x6d
,
0x65
,
0x20
,
0x6d
,
0x69
,
0x73
,
0x74
,
0x61
,
0x6b
,
0x65
,
0x73
,
0x20
,
0x74
,
0x68
,
0x61
,
0x74
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x64
,
0x69
,
0x64
,
0x0a
,
0x49
,
0x20
,
0x77
,
0x69
,
0x6c
,
0x6c
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x6c
,
0x65
,
0x74
,
0x20
,
0x6d
,
0x79
,
0x73
,
0x65
,
0x6c
,
0x66
,
0x0a
,
0x43
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6d
,
0x79
,
0x20
,
0x68
,
0x65
,
0x61
,
0x72
,
0x74
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x6d
,
0x75
,
0x63
,
0x68
,
0x20
,
0x6d
,
0x69
,
0x73
,
0x65
,
0x72
,
0x79
,
0x0a
,
0x49
,
0x20
,
0x77
,
0x69
,
0x6c
,
0x6c
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x62
,
0x72
,
0x65
,
0x61
,
0x6b
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x77
,
0x61
,
0x79
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x64
,
0x69
,
0x64
,
0x0a
,
0x59
,
0x6f
,
0x75
,
0x20
,
0x66
,
0x65
,
0x6c
,
0x6c
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x68
,
0x61
,
0x72
,
0x64
,
0x0a
,
0x0a
,
0x49
,
0x20
,
0x76
,
0x65
,
0x20
,
0x6c
,
0x65
,
0x61
,
0x72
,
0x6e
,
0x65
,
0x64
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x68
,
0x61
,
0x72
,
0x64
,
0x20
,
0x77
,
0x61
,
0x79
,
0x0a
,
0x54
,
0x6f
,
0x20
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x20
,
0x6c
,
0x65
,
0x74
,
0x20
,
0x69
,
0x74
,
0x20
,
0x67
,
0x65
,
0x74
,
0x20
,
0x74
,
0x68
,
0x61
,
0x74
,
0x20
,
0x66
,
0x61
,
0x72
,
0x0a
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x20
,
0x73
,
0x74
,
0x72
,
0x61
,
0x79
,
0x20
,
0x74
,
0x6f
,
0x6f
,
0x20
,
0x66
,
0x61
,
0x72
,
0x20
,
0x66
,
0x72
,
0x6f
,
0x6d
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x77
,
0x61
,
0x6c
,
0x6b
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6c
,
0x65
,
0x61
,
0x72
,
0x6e
,
0x65
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x70
,
0x6c
,
0x61
,
0x79
,
0x20
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x61
,
0x66
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x49
,
0x20
,
0x64
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x20
,
0x67
,
0x65
,
0x74
,
0x20
,
0x68
,
0x75
,
0x72
,
0x74
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x66
,
0x69
,
0x6e
,
0x64
,
0x20
,
0x69
,
0x74
,
0x20
,
0x68
,
0x61
,
0x72
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x74
,
0x72
,
0x75
,
0x73
,
0x74
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x6f
,
0x6e
,
0x6c
,
0x79
,
0x20
,
0x6d
,
0x65
,
0x2c
,
0x20
,
0x62
,
0x75
,
0x74
,
0x20
,
0x65
,
0x76
,
0x65
,
0x72
,
0x79
,
0x6f
,
0x6e
,
0x65
,
0x20
,
0x61
,
0x72
,
0x6f
,
0x75
,
0x6e
,
0x64
,
0x20
,
0x6d
,
0x65
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x61
,
0x6d
,
0x20
,
0x61
,
0x66
,
0x72
,
0x61
,
0x69
,
0x64
,
0x0a
,
0x0a
,
0x49
,
0x20
,
0x6c
,
0x6f
,
0x73
,
0x65
,
0x20
,
0x6d
,
0x79
,
0x20
,
0x77
,
0x61
,
0x79
,
0x0a
,
0x41
,
0x6e
,
0x64
,
0x20
,
0x69
,
0x74
,
0x20
,
0x73
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x74
,
0x6f
,
0x6f
,
0x20
,
0x6c
,
0x6f
,
0x6e
,
0x67
,
0x20
,
0x62
,
0x65
,
0x66
,
0x6f
,
0x72
,
0x65
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x70
,
0x6f
,
0x69
,
0x6e
,
0x74
,
0x20
,
0x69
,
0x74
,
0x20
,
0x6f
,
0x75
,
0x74
,
0x0a
,
0x49
,
0x20
,
0x63
,
0x61
,
0x6e
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x63
,
0x72
,
0x79
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x6b
,
0x6e
,
0x6f
,
0x77
,
0x20
,
0x74
,
0x68
,
0x61
,
0x74
,
0x20
,
0x73
,
0x20
,
0x77
,
0x65
,
0x61
,
0x6b
,
0x6e
,
0x65
,
0x73
,
0x73
,
0x20
,
0x69
,
0x6e
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x72
,
0x20
,
0x65
,
0x79
,
0x65
,
0x73
,
0x0a
,
0x49
,
0x20
,
0x6d
,
0x20
,
0x66
,
0x6f
,
0x72
,
0x63
,
0x65
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x66
,
0x61
,
0x6b
,
0x65
,
0x0a
,
0x41
,
0x20
,
0x73
,
0x6d
,
0x69
,
0x6c
,
0x65
,
0x2c
,
0x20
,
0x61
,
0x20
,
0x6c
,
0x61
,
0x75
,
0x67
,
0x68
,
0x20
,
0x65
,
0x76
,
0x65
,
0x72
,
0x79
,
0x64
,
0x61
,
0x79
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x6d
,
0x79
,
0x20
,
0x6c
,
0x69
,
0x66
,
0x65
,
0x0a
,
0x4d
,
0x79
,
0x20
,
0x68
,
0x65
,
0x61
,
0x72
,
0x74
,
0x20
,
0x63
,
0x61
,
0x6e
,
0x27
,
0x74
,
0x20
,
0x70
,
0x6f
,
0x73
,
0x73
,
0x69
,
0x62
,
0x6c
,
0x79
,
0x20
,
0x62
,
0x72
,
0x65
,
0x61
,
0x6b
,
0x0a
,
0x57
,
0x68
,
0x65
,
0x6e
,
0x20
,
0x69
,
0x74
,
0x20
,
0x77
,
0x61
,
0x73
,
0x6e
,
0x27
,
0x74
,
0x20
,
0x65
,
0x76
,
0x65
,
0x6e
,
0x20
,
0x77
,
0x68
,
0x6f
,
0x6c
,
0x65
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x73
,
0x74
,
0x61
,
0x72
,
0x74
,
0x20
,
0x77
,
0x69
,
0x74
,
0x68
,
0x0a
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x20
,
0x73
,
0x74
,
0x72
,
0x61
,
0x79
,
0x20
,
0x74
,
0x6f
,
0x6f
,
0x20
,
0x66
,
0x61
,
0x72
,
0x20
,
0x66
,
0x72
,
0x6f
,
0x6d
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x77
,
0x61
,
0x6c
,
0x6b
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6c
,
0x65
,
0x61
,
0x72
,
0x6e
,
0x65
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x70
,
0x6c
,
0x61
,
0x79
,
0x20
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x61
,
0x66
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x49
,
0x20
,
0x64
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x20
,
0x67
,
0x65
,
0x74
,
0x20
,
0x68
,
0x75
,
0x72
,
0x74
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x66
,
0x69
,
0x6e
,
0x64
,
0x20
,
0x69
,
0x74
,
0x20
,
0x68
,
0x61
,
0x72
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x74
,
0x72
,
0x75
,
0x73
,
0x74
,
0x20
,
0x6e
,
0x6f
,
0x74
,
0x20
,
0x6f
,
0x6e
,
0x6c
,
0x79
,
0x20
,
0x6d
,
0x65
,
0x2c
,
0x20
,
0x62
,
0x75
,
0x74
,
0x20
,
0x65
,
0x76
,
0x65
,
0x72
,
0x79
,
0x6f
,
0x6e
,
0x65
,
0x20
,
0x61
,
0x72
,
0x6f
,
0x75
,
0x6e
,
0x64
,
0x20
,
0x6d
,
0x65
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x61
,
0x6d
,
0x20
,
0x61
,
0x66
,
0x72
,
0x61
,
0x69
,
0x64
,
0x0a
,
0x0a
,
0x49
,
0x20
,
0x77
,
0x61
,
0x74
,
0x63
,
0x68
,
0x65
,
0x64
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x64
,
0x69
,
0x65
,
0x0a
,
0x49
,
0x20
,
0x68
,
0x65
,
0x61
,
0x72
,
0x64
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x20
,
0x63
,
0x72
,
0x79
,
0x20
,
0x65
,
0x76
,
0x65
,
0x72
,
0x79
,
0x20
,
0x6e
,
0x69
,
0x67
,
0x68
,
0x74
,
0x20
,
0x69
,
0x6e
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x72
,
0x20
,
0x73
,
0x6c
,
0x65
,
0x65
,
0x70
,
0x0a
,
0x49
,
0x20
,
0x77
,
0x61
,
0x73
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x6e
,
0x67
,
0x0a
,
0x59
,
0x6f
,
0x75
,
0x20
,
0x73
,
0x68
,
0x6f
,
0x75
,
0x6c
,
0x64
,
0x20
,
0x68
,
0x61
,
0x76
,
0x65
,
0x20
,
0x6b
,
0x6e
,
0x6f
,
0x77
,
0x6e
,
0x20
,
0x62
,
0x65
,
0x74
,
0x74
,
0x65
,
0x72
,
0x20
,
0x74
,
0x68
,
0x61
,
0x6e
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x6c
,
0x65
,
0x61
,
0x6e
,
0x20
,
0x6f
,
0x6e
,
0x20
,
0x6d
,
0x65
,
0x0a
,
0x59
,
0x6f
,
0x75
,
0x20
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x20
,
0x74
,
0x68
,
0x6f
,
0x75
,
0x67
,
0x68
,
0x74
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x61
,
0x6e
,
0x79
,
0x6f
,
0x6e
,
0x65
,
0x20
,
0x65
,
0x6c
,
0x73
,
0x65
,
0x0a
,
0x59
,
0x6f
,
0x75
,
0x20
,
0x6a
,
0x75
,
0x73
,
0x74
,
0x20
,
0x73
,
0x61
,
0x77
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x72
,
0x20
,
0x70
,
0x61
,
0x69
,
0x6e
,
0x0a
,
0x41
,
0x6e
,
0x64
,
0x20
,
0x6e
,
0x6f
,
0x77
,
0x20
,
0x49
,
0x20
,
0x63
,
0x72
,
0x79
,
0x20
,
0x69
,
0x6e
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x6d
,
0x69
,
0x64
,
0x64
,
0x6c
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x6e
,
0x69
,
0x67
,
0x68
,
0x74
,
0x0a
,
0x46
,
0x6f
,
0x72
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x61
,
0x6d
,
0x65
,
0x20
,
0x64
,
0x61
,
0x6d
,
0x6e
,
0x20
,
0x74
,
0x68
,
0x69
,
0x6e
,
0x67
,
0x0a
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6e
,
0x65
,
0x76
,
0x65
,
0x72
,
0x20
,
0x73
,
0x74
,
0x72
,
0x61
,
0x79
,
0x20
,
0x74
,
0x6f
,
0x6f
,
0x20
,
0x66
,
0x61
,
0x72
,
0x20
,
0x66
,
0x72
,
0x6f
,
0x6d
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x77
,
0x61
,
0x6c
,
0x6b
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6c
,
0x65
,
0x61
,
0x72
,
0x6e
,
0x65
,
0x64
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x70
,
0x6c
,
0x61
,
0x79
,
0x20
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x68
,
0x65
,
0x20
,
0x73
,
0x61
,
0x66
,
0x65
,
0x20
,
0x73
,
0x69
,
0x64
,
0x65
,
0x20
,
0x73
,
0x6f
,
0x20
,
0x49
,
0x20
,
0x64
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x20
,
0x67
,
0x65
,
0x74
,
0x20
,
0x68
,
0x75
,
0x72
,
0x74
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x74
,
0x72
,
0x79
,
0x20
,
0x6d
,
0x79
,
0x20
,
0x68
,
0x61
,
0x72
,
0x64
,
0x65
,
0x73
,
0x74
,
0x20
,
0x6a
,
0x75
,
0x73
,
0x74
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x66
,
0x6f
,
0x72
,
0x67
,
0x65
,
0x74
,
0x20
,
0x65
,
0x76
,
0x65
,
0x72
,
0x79
,
0x74
,
0x68
,
0x69
,
0x6e
,
0x67
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x64
,
0x6f
,
0x6e
,
0x20
,
0x74
,
0x20
,
0x6b
,
0x6e
,
0x6f
,
0x77
,
0x20
,
0x68
,
0x6f
,
0x77
,
0x20
,
0x74
,
0x6f
,
0x20
,
0x6c
,
0x65
,
0x74
,
0x20
,
0x61
,
0x6e
,
0x79
,
0x6f
,
0x6e
,
0x65
,
0x20
,
0x65
,
0x6c
,
0x73
,
0x65
,
0x20
,
0x69
,
0x6e
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x6d
,
0x20
,
0x61
,
0x73
,
0x68
,
0x61
,
0x6d
,
0x65
,
0x64
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x6d
,
0x79
,
0x20
,
0x6c
,
0x69
,
0x66
,
0x65
,
0x20
,
0x62
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x69
,
0x74
,
0x20
,
0x73
,
0x20
,
0x65
,
0x6d
,
0x70
,
0x74
,
0x79
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x49
,
0x20
,
0x61
,
0x6d
,
0x20
,
0x61
,
0x66
,
0x72
,
0x61
,
0x69
,
0x64
,
0x0a
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x42
,
0x65
,
0x63
,
0x61
,
0x75
,
0x73
,
0x65
,
0x20
,
0x6f
,
0x66
,
0x20
,
0x79
,
0x6f
,
0x75
,
0x0a
,
0x2e
,
0x2e
,
0x2e
,
0x0a
,
/*0x0a, 0x66, 0x6f, 0x72, 0x20, 0x6a, 0x75, 0x6c, 0x79, 0x0a, 0x0a,*/
};
}
}
core/src/main/java/com/taobao/arthas/core/command/hidden/ThanksCommand.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.hidden
;
import
com.taobao.arthas.core.shell.command.AnnotatedCommand
;
import
com.taobao.arthas.core.shell.command.CommandProcess
;
import
com.taobao.arthas.core.util.ArthasBanner
;
import
com.taobao.middleware.cli.annotations.Hidden
;
import
com.taobao.middleware.cli.annotations.Name
;
import
com.taobao.middleware.cli.annotations.Summary
;
/**
* 工具介绍<br/>
* 感谢
*
* @author vlinux on 15/9/1.
*/
@Name
(
"thanks"
)
@Summary
(
"Credits to all personnel and organization who either contribute or help to this product. Thanks you all!"
)
@Hidden
public
class
ThanksCommand
extends
AnnotatedCommand
{
@Override
public
void
process
(
CommandProcess
process
)
{
process
.
write
(
ArthasBanner
.
credit
()).
write
(
"\n"
).
end
();
}
}
core/src/main/java/com/taobao/arthas/core/command/klass100/ClassDumpTransformer.java
0 → 100644
View file @
5d7c4150
package
com.taobao.arthas.core.command.klass100
;
import
com.alibaba.arthas.deps.org.slf4j.Logger
;
import
com.alibaba.arthas.deps.org.slf4j.LoggerFactory
;
import
com.taobao.arthas.core.util.FileUtils
;
import
com.taobao.arthas.core.util.LogUtil
;
import
java.io.File
;
import
java.io.IOException
;
import
java.lang.instrument.ClassFileTransformer
;
import
java.lang.instrument.IllegalClassFormatException
;
import
java.security.ProtectionDomain
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author beiwei30 on 25/11/2016.
*/
class
ClassDumpTransformer
implements
ClassFileTransformer
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
ClassDumpTransformer
.
class
);
private
Set
<
Class
<?>>
classesToEnhance
;
private
Map
<
Class
<?>,
File
>
dumpResult
;
private
File
arthasLogHome
;
private
File
directory
;
public
ClassDumpTransformer
(
Set
<
Class
<?>>
classesToEnhance
)
{
this
(
classesToEnhance
,
null
);
}
public
ClassDumpTransformer
(
Set
<
Class
<?>>
classesToEnhance
,
File
directory
)
{
this
.
classesToEnhance
=
classesToEnhance
;
this
.
dumpResult
=
new
HashMap
<
Class
<?>,
File
>();
this
.
arthasLogHome
=
new
File
(
LogUtil
.
loggingDir
());
this
.
directory
=
directory
;
}
@Override
public
byte
[]
transform
(
ClassLoader
loader
,
String
className
,
Class
<?>
classBeingRedefined
,
ProtectionDomain
protectionDomain
,
byte
[]
classfileBuffer
)
throws
IllegalClassFormatException
{
if
(
classesToEnhance
.
contains
(
classBeingRedefined
))
{
dumpClassIfNecessary
(
classBeingRedefined
,
classfileBuffer
);
}
return
null
;
}
public
Map
<
Class
<?>,
File
>
getDumpResult
()
{
return
dumpResult
;
}
private
void
dumpClassIfNecessary
(
Class
<?>
clazz
,
byte
[]
data
)
{
String
className
=
clazz
.
getName
();
ClassLoader
classLoader
=
clazz
.
getClassLoader
();
String
classDumpDir
=
"classdump"
;
// 创建类所在的包路径
File
dumpDir
=
null
;
if
(
directory
!=
null
)
{
dumpDir
=
directory
;
}
else
{
dumpDir
=
new
File
(
arthasLogHome
,
classDumpDir
);
}
if
(!
dumpDir
.
mkdirs
()
&&
!
dumpDir
.
exists
())
{
logger
.
warn
(
"create dump directory:{} failed."
,
dumpDir
.
getAbsolutePath
());
return
;
}
String
fileName
;
if
(
classLoader
!=
null
)
{
fileName
=
classLoader
.
getClass
().
getName
()
+
"-"
+
Integer
.
toHexString
(
classLoader
.
hashCode
())
+
File
.
separator
+
className
.
replace
(
"."
,
File
.
separator
)
+
".class"
;
}
else
{
fileName
=
className
.
replace
(
"."
,
File
.
separator
)
+
".class"
;
}
File
dumpClassFile
=
new
File
(
dumpDir
,
fileName
);
// 将类字节码写入文件
try
{
FileUtils
.
writeByteArrayToFile
(
dumpClassFile
,
data
);
dumpResult
.
put
(
clazz
,
dumpClassFile
);
}
catch
(
IOException
e
)
{
logger
.
warn
(
"dump class:{} to file {} failed."
,
className
,
dumpClassFile
,
e
);
}
}
}
Prev
1
…
9
10
11
12
13
14
15
16
17
…
23
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment