Skip to content

Commit

Permalink
#177 bug fix : jdk14报NPE;
Browse files Browse the repository at this point in the history
  • Loading branch information
boxing.yi committed Aug 3, 2020
1 parent 576099c commit 2ea3022
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 50 deletions.
29 changes: 27 additions & 2 deletions vjmxcli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
</properties>

<dependencies>
<dependency>
<!-- <dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${toolsjar}</systemPath>
</dependency>
</dependency> -->
</dependencies>

<build>
Expand Down Expand Up @@ -129,6 +129,31 @@
</plugins>
</build>
</profile>


<profile>
<id>jdk9</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<dependencies/>
</profile>
<profile>
<id>default-jdk</id>
<activation>
<jdk>(,1.8]</jdk>
</activation>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<systemPath>${toolsjar}</systemPath>
</dependency>
</dependencies>
</profile>

</profiles>

<distributionManagement>
Expand Down
58 changes: 52 additions & 6 deletions vjmxcli/src/main/assembly/vjmxcli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,61 @@ if [ ! -d "$JAVA_HOME" ] ; then
exit 1
fi

TOOLSJAR="$JAVA_HOME/lib/tools.jar"

if [ ! -f "$TOOLSJAR" ] ; then
echo "$TOOLSJAR doesn't exist" >&2
exit 1

# returns the JDK version.
# 8 for 1.8.0_nn, 9 for 9-ea etc, and "no_java" for undetected
GET_JDK_VERSION() {
local result
local java_cmd
if [[ -n $(type -p java) ]]
then
java_cmd=java
elif [[ (-n "$JAVA_HOME") && (-x "$JAVA_HOME/bin/java") ]]
then
java_cmd="$JAVA_HOME/bin/java"
fi
local IFS=$'\n'
# remove \r for Cygwin
local lines=$("$java_cmd" -Xms32M -Xmx32M -version 2>&1 | tr '\r' '\n')
if [[ -z $java_cmd ]]
then
result=no_java
else
for line in $lines; do
if [[ (-z $result) && ($line = *"version \""*) ]]
then
local ver=$(echo $line | sed -e 's/.*version "\(.*\)"\(.*\)/\1/; 1q')
# on macOS, sed doesn't support '?'
if [[ $ver = "1."* ]]
then
result=$(echo $ver | sed -e 's/1\.\([0-9]*\)\(.*\)/\1/; 1q')
else
result=$(echo $ver | sed -e 's/\([0-9]*\)\(.*\)/\1/; 1q')
fi
fi
done
fi
echo "$result"
}

JDK_VERSION=$(GET_JDK_VERSION)
echo "JDK_VERSION : $JDK_VERSION"

# jdk 8 and before
if [[ $JDK_VERSION -le 8 ]]; then
TOOLSJAR="$JAVA_HOME/lib/tools.jar"
if [ ! -f "$TOOLSJAR" ] ; then
echo "$TOOLSJAR doesn't exist" >&2
exit 1
fi
JAVA_OPTS="-Xms256m -Xmx256m -XX:NewRatio=1 -Xss256k -XX:+UseSerialGC -XX:CICompilerCount=2 -Xverify:none -XX:AutoBoxCacheMax=20000"
else
# jdk 9 or later
JAVA_OPTS="-Xms256m -Xmx256m -XX:NewRatio=1 -Xss256k -XX:+UseSerialGC -XX:CICompilerCount=2 -XX:AutoBoxCacheMax=20000"
fi

DIR=$( cd $(dirname $0) ; pwd -P )

JAVA_OPTS="-Xms96m -Xmx96m -Xmn64m -Xss256k -XX:+UseSerialGC -Djava.compiler=NONE -Xverify:none -XX:AutoBoxCacheMax=20000"
DIR=$( cd $(dirname $0) ; pwd -P )

"$JAVA_HOME"/bin/java $JAVA_OPTS -cp "$DIR/vjmxcli.jar:$TOOLSJAR" com.vip.vjtools.jmx.Client $*
102 changes: 64 additions & 38 deletions vjmxcli/src/main/java/com/vip/vjtools/jmx/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ protected String[] parseUserpass(final String userpass) {
if (index <= 0) {
throw new RuntimeException("Unable to parse: " + userpass);
}
return new String[] { userpass.substring(0, index), userpass.substring(index + 1) };
return new String[]{userpass.substring(0, index), userpass.substring(index + 1)};
}

/**
Expand All @@ -152,7 +152,7 @@ protected String[] parseUserpass(final String userpass) {
*/
protected static Map formatCredentials(final String login, final String password) {
Map env = null;
String[] creds = new String[] { login, password };
String[] creds = new String[]{login, password};
env = new HashMap(1);
env.put(JMXConnector.CREDENTIALS, creds);
return env;
Expand Down Expand Up @@ -202,39 +202,49 @@ public static String getLocalConnectorAddress(String pid) throws IOException {//
}

// 3. 未启动,尝试启动
// JDK8后有更直接的vm.startLocalManagementAgent()方法
String home = vm.getSystemProperties().getProperty("java.home");

// Normally in ${java.home}/jre/lib/management-agent.jar but might
// be in ${java.home}/lib in build environments.

String agentPath = home + File.separator + "jre" + File.separator + "lib" + File.separator
+ "management-agent.jar";
File f = new File(agentPath);
if (!f.exists()) {
agentPath = home + File.separator + "lib" + File.separator + "management-agent.jar";
f = new File(agentPath);
int version = getJavaMajorVersion(vm.getSystemProperties().getProperty("java.specification.version"));
if (version >= 8) {
vm.startLocalManagementAgent();
agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
} else {
// JDK8后有更直接的vm.startLocalManagementAgent()方法
String home = vm.getSystemProperties().getProperty("java.home");
// Normally in ${java.home}/jre/lib/management-agent.jar but might
// be in ${java.home}/lib in build environments.
String agentPath = home + File.separator + "jre" + File.separator + "lib" + File.separator
+ "management-agent.jar";

File f = new File(agentPath);
if (!f.exists()) {
throw new IOException("Management agent not found");
agentPath = home + File.separator + "lib" + File.separator + "management-agent.jar";
f = new File(agentPath);
if (!f.exists()) {
throw new IOException("Management agent not found");
}
}
}

agentPath = f.getCanonicalPath();
try {
vm.loadAgent(agentPath, "com.sun.management.jmxremote");
} catch (AgentLoadException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
} catch (AgentInitializationException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
}
agentPath = f.getCanonicalPath();
try {
vm.loadAgent(agentPath, "com.sun.management.jmxremote");
} catch (AgentLoadException x) {
// 高版本 attach 低版本jdk 抛异常:com.sun.tools.attach.AgentLoadException: 0,实际上是成功的;
// 根因: HotSpotVirtualMachine.loadAgentLibrary 高版本jdk实现不一样了
if (!"0".equals(x.getMessage())) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
}
} catch (AgentInitializationException x) {
IOException ioe = new IOException(x.getMessage());
ioe.initCause(x);
throw ioe;
}

// 4. 再次获取connector address
agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
// 4. 再次获取connector address
agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
}

if (address == null) {
throw new IOException("Fails to find connector address");
Expand Down Expand Up @@ -311,7 +321,7 @@ protected Object[] execute(final String hostport, final String login, final Stri

public Object[] executeOneCmd(final String hostport, final String login, final String password,
final String beanname, final String command) throws Exception {
return execute(hostport, login, password, beanname, new String[] { command }, true);
return execute(hostport, login, password, beanname, new String[]{command}, true);
}

/**
Expand Down Expand Up @@ -386,7 +396,7 @@ protected static Object[] doBeans(final MBeanServerConnection mbsc, final Object
}
buffer.append("\n");
}
result = new String[] { buffer.toString() };
result = new String[]{buffer.toString()};
}
return result;
}
Expand All @@ -404,7 +414,7 @@ protected static Object[] doBean(MBeanServerConnection mbsc, ObjectInstance inst
throws Exception {
// If no command, then print out list of attributes and operations.
if (command == null || command.length <= 0) {
return new String[] { listOptions(mbsc, instance) };
return new String[]{listOptions(mbsc, instance)};
}

// Maybe multiple attributes/operations listed on one command line.
Expand Down Expand Up @@ -614,8 +624,8 @@ protected static Object doAttributeOperation(MBeanServerConnection mbsc, ObjectI
// Get first attribute of name 'cmd'. Assumption is no method
// overrides. Then, look at the attribute and use its type.
MBeanAttributeInfo info = (MBeanAttributeInfo) getFeatureInfo(infos, parse.getCmd());
java.lang.reflect.Constructor c = Class.forName(info.getType()).getConstructor(new Class[] { String.class });
Attribute a = new Attribute(parse.getCmd(), c.newInstance(new Object[] { parse.getArgs()[0] }));
java.lang.reflect.Constructor c = Class.forName(info.getType()).getConstructor(new Class[]{String.class});
Attribute a = new Attribute(parse.getCmd(), c.newInstance(new Object[]{parse.getArgs()[0]}));
mbsc.setAttribute(instance.getObjectName(), a);
return null;
}
Expand Down Expand Up @@ -644,8 +654,8 @@ protected static Object doBeanOperation(MBeanServerConnection mbsc, ObjectInstan
for (int i = 0; i < paraminfosLength; i++) {
MBeanParameterInfo paraminfo = paraminfos[i];
java.lang.reflect.Constructor c = Class.forName(paraminfo.getType())
.getConstructor(new Class[] { String.class });
params[i] = c.newInstance(new Object[] { parse.getArgs()[i] });
.getConstructor(new Class[]{String.class});
params[i] = c.newInstance(new Object[]{parse.getArgs()[i]});
signature[i] = paraminfo.getType();
}
result = mbsc.invoke(instance.getObjectName(), parse.getCmd(), params, signature);
Expand Down Expand Up @@ -760,4 +770,20 @@ public synchronized String format(LogRecord record) {
}
}

private static int getJavaMajorVersion(String javaSpecificationVersion) {
if (javaSpecificationVersion.startsWith("1.8")) {
return 8;
} else if (javaSpecificationVersion.startsWith("1.7")) {
return 7;
} else if (javaSpecificationVersion.startsWith("1.6")) {
return 6;
} else {
try {
return Integer.parseInt(javaSpecificationVersion);
} catch (NumberFormatException e) {
return 0;
}
}
}

}
12 changes: 8 additions & 4 deletions vjmxcli/src/main/java/com/vip/vjtools/jmx/ExtraCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ private void gcUtilCommand(MBeanServerConnection mbsc, int interval) throws Exce
String[] commands;

if (getJavaVersion(mbsc) > 7) {
commands = new String[] { "S", "S", "E", "O", "M", "CCS", "YGC", "YGCT", "FGC", "FGCT", "GCT" };
commands = new String[]{"S", "S", "E", "O", "M", "CCS", "YGC", "YGCT", "FGC", "FGCT", "GCT"};
} else {
commands = new String[] { "S", "S", "E", "O", "P", "YGC", "YGCT", "FGC", "FGCT", "GCT" };
commands = new String[]{"S", "S", "E", "O", "P", "YGC", "YGCT", "FGC", "FGCT", "GCT"};
}

for (String commmand : commands) {
Expand Down Expand Up @@ -84,14 +84,18 @@ private Object[] executGCutil(final String[] commands, GCutilExpression gcE) thr
public static int getJavaVersion(final MBeanServerConnection mbsc) throws Exception {
Object version = mbsc.getAttribute(Client.getObjectName("java.lang:type=Runtime"), "SpecVersion");
String javaVersion = version.toString();
if (javaVersion.startsWith("1.8") || Double.parseDouble(javaVersion.substring(0, 3)) > 1.7) {
if (javaVersion.startsWith("1.8")) {
return 8;
} else if (javaVersion.startsWith("1.7")) {
return 7;
} else if (javaVersion.startsWith("1.6")) {
return 6;
} else {
return 0;
try {
return Integer.parseInt(javaVersion);
} catch (NumberFormatException e) {
return 0;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,16 @@ public Double getYGCT() throws Exception {
}

public Object getFGC() throws Exception {
if (fgcCollector == null) {
return 0;
}
return getAttribute(fgcCollector, COLLECTION_COUNT_ATTRIBUTE);
}

public Double getFGCT() throws Exception {
if (fgcCollector == null) {
return 0.0;
}
return Double.parseDouble(getAttribute(fgcCollector, COLLECTION_TIME_ATTRIBUTE).toString()) / 1000;
}

Expand Down

0 comments on commit 2ea3022

Please sign in to comment.