提交 5b73b288 编写于 作者: S sla

8039173: Propagate errors from Diagnostic Commands as exceptions in the attach framework

Reviewed-by: alanb, dsamersoff, jbachorik
上级 04edbd33
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.attach;
import java.io.IOException;
/**
* Exception type to signal that an attach operation failed in the target VM.
*
* <p> This exception can be thrown by the various operations of
* {@link com.sun.tools.attach.VirtualMachine} when the operation
* fails in the target VM. If there is a communication error,
* a regular IOException will be thrown.
*
* @since 1.9
*/
@jdk.Exported
public class AttachOperationFailedException extends IOException {
private static final long serialVersionUID = 2140308168167478043L;
/**
* Constructs an <code>AttachOperationFailedException</code> with
* the specified detail message.
*
* @param s the detail message.
*/
public AttachOperationFailedException(String message) {
super(message);
}
}
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -564,8 +564,15 @@ public abstract class VirtualMachine { ...@@ -564,8 +564,15 @@ public abstract class VirtualMachine {
* *
* @return The system properties * @return The system properties
* *
* @throws AttachOperationFailedException
* If the target virtual machine is unable to complete the
* attach operation. A more specific error message will be
* given by {@link AttachOperationFailedException#getMessage()}.
*
* @throws IOException * @throws IOException
* If an I/O error occurs * If an I/O error occurs, a communication error for example,
* that cannot be identified as an error to indicate that the
* operation failed in the target VM.
* *
* @see java.lang.System#getProperties * @see java.lang.System#getProperties
* @see #loadAgentLibrary * @see #loadAgentLibrary
...@@ -591,8 +598,15 @@ public abstract class VirtualMachine { ...@@ -591,8 +598,15 @@ public abstract class VirtualMachine {
* *
* @return The agent properties * @return The agent properties
* *
* @throws AttachOperationFailedException
* If the target virtual machine is unable to complete the
* attach operation. A more specific error message will be
* given by {@link AttachOperationFailedException#getMessage()}.
*
* @throws IOException * @throws IOException
* If an I/O error occurs * If an I/O error occurs, a communication error for example,
* that cannot be identified as an error to indicate that the
* operation failed in the target VM.
*/ */
public abstract Properties getAgentProperties() throws IOException; public abstract Properties getAgentProperties() throws IOException;
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -257,6 +257,20 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { ...@@ -257,6 +257,20 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine {
return value; return value;
} }
/*
* Utility method to read data into a String.
*/
String readErrorMessage(InputStream sis) throws IOException {
byte b[] = new byte[1024];
int n;
StringBuffer message = new StringBuffer();
while ((n = sis.read(b)) != -1) {
message.append(new String(b, 0, n, "UTF-8"));
}
return message.toString();
}
// -- attach timeout support // -- attach timeout support
private static long defaultAttachTimeout = 5000; private static long defaultAttachTimeout = 5000;
......
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,10 +33,12 @@ import java.util.ArrayList; ...@@ -33,10 +33,12 @@ import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor; import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import sun.tools.attach.HotSpotVirtualMachine; import sun.tools.attach.HotSpotVirtualMachine;
import sun.tools.jstat.JStatLogger; import sun.tools.jstat.JStatLogger;
import sun.jvmstat.monitor.Monitor; import sun.jvmstat.monitor.Monitor;
...@@ -119,6 +121,7 @@ public class JCmd { ...@@ -119,6 +121,7 @@ public class JCmd {
pids.add(arg.getPid() + ""); pids.add(arg.getPid() + "");
} }
boolean success = true;
for (String pid : pids) { for (String pid : pids) {
System.out.println(pid + ":"); System.out.println(pid + ":");
if (arg.isListCounters()) { if (arg.isListCounters()) {
...@@ -126,11 +129,16 @@ public class JCmd { ...@@ -126,11 +129,16 @@ public class JCmd {
} else { } else {
try { try {
executeCommandForPid(pid, arg.getCommand()); executeCommandForPid(pid, arg.getCommand());
} catch(AttachOperationFailedException ex) {
System.err.println(ex.getMessage());
success = false;
} catch(Exception ex) { } catch(Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
success = false;
} }
} }
} }
System.exit(success ? 0 : 1);
} }
private static void executeCommandForPid(String pid, String command) private static void executeCommandForPid(String pid, String command)
...@@ -150,13 +158,18 @@ public class JCmd { ...@@ -150,13 +158,18 @@ public class JCmd {
// read to EOF and just print output // read to EOF and just print output
byte b[] = new byte[256]; byte b[] = new byte[256];
int n; int n;
boolean messagePrinted = false;
do { do {
n = in.read(b); n = in.read(b);
if (n > 0) { if (n > 0) {
String s = new String(b, 0, n, "UTF-8"); String s = new String(b, 0, n, "UTF-8");
System.out.print(s); System.out.print(s);
messagePrinted = true;
} }
} while (n > 0); } while (n > 0);
if (!messagePrinted) {
System.out.println("Command executed successfully");
}
} }
} }
vm.detach(); vm.detach();
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,14 +24,14 @@ ...@@ -24,14 +24,14 @@
*/ */
package sun.tools.attach; package sun.tools.attach;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.spi.AttachProvider; import com.sun.tools.attach.spi.AttachProvider;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.File; import java.io.File;
import java.util.Properties;
/* /*
* Bsd implementation of HotSpotVirtualMachine * Bsd implementation of HotSpotVirtualMachine
...@@ -191,6 +191,8 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine { ...@@ -191,6 +191,8 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
} }
if (completionStatus != 0) { if (completionStatus != 0) {
// read from the stream and use that as the error message
String message = readErrorMessage(sis);
sis.close(); sis.close();
// In the event of a protocol mismatch then the target VM // In the event of a protocol mismatch then the target VM
...@@ -205,7 +207,11 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine { ...@@ -205,7 +207,11 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
if (cmd.equals("load")) { if (cmd.equals("load")) {
throw new AgentLoadException("Failed to load agent library"); throw new AgentLoadException("Failed to load agent library");
} else { } else {
throw new IOException("Command failed in target VM"); if (message == null) {
throw new AttachOperationFailedException("Command failed in target VM");
} else {
throw new AttachOperationFailedException(message);
}
} }
} }
...@@ -237,8 +243,9 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine { ...@@ -237,8 +243,9 @@ public class BsdVirtualMachine extends HotSpotVirtualMachine {
if ((off < 0) || (off > bs.length) || (len < 0) || if ((off < 0) || (off > bs.length) || (len < 0) ||
((off + len) > bs.length) || ((off + len) < 0)) { ((off + len) > bs.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} else if (len == 0) } else if (len == 0) {
return 0; return 0;
}
return BsdVirtualMachine.read(s, bs, off, len); return BsdVirtualMachine.read(s, bs, off, len);
} }
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,14 +24,14 @@ ...@@ -24,14 +24,14 @@
*/ */
package sun.tools.attach; package sun.tools.attach;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.spi.AttachProvider; import com.sun.tools.attach.spi.AttachProvider;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.File; import java.io.File;
import java.util.Properties;
/* /*
* Linux implementation of HotSpotVirtualMachine * Linux implementation of HotSpotVirtualMachine
...@@ -207,6 +207,8 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine { ...@@ -207,6 +207,8 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
} }
if (completionStatus != 0) { if (completionStatus != 0) {
// read from the stream and use that as the error message
String message = readErrorMessage(sis);
sis.close(); sis.close();
// In the event of a protocol mismatch then the target VM // In the event of a protocol mismatch then the target VM
...@@ -221,7 +223,11 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine { ...@@ -221,7 +223,11 @@ public class LinuxVirtualMachine extends HotSpotVirtualMachine {
if (cmd.equals("load")) { if (cmd.equals("load")) {
throw new AgentLoadException("Failed to load agent library"); throw new AgentLoadException("Failed to load agent library");
} else { } else {
throw new IOException("Command failed in target VM"); if (message == null) {
throw new AttachOperationFailedException("Command failed in target VM");
} else {
throw new AttachOperationFailedException(message);
}
} }
} }
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,15 +24,15 @@ ...@@ -24,15 +24,15 @@
*/ */
package sun.tools.attach; package sun.tools.attach;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.spi.AttachProvider; import com.sun.tools.attach.spi.AttachProvider;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.Properties;
/* /*
* Solaris implementation of HotSpotVirtualMachine. * Solaris implementation of HotSpotVirtualMachine.
...@@ -147,11 +147,17 @@ public class SolarisVirtualMachine extends HotSpotVirtualMachine { ...@@ -147,11 +147,17 @@ public class SolarisVirtualMachine extends HotSpotVirtualMachine {
// If non-0 it means an error but we need to special-case the // If non-0 it means an error but we need to special-case the
// "load" command to ensure that the right exception is thrown. // "load" command to ensure that the right exception is thrown.
if (completionStatus != 0) { if (completionStatus != 0) {
// read from the stream and use that as the error message
String message = readErrorMessage(sis);
sis.close(); sis.close();
if (cmd.equals("load")) { if (cmd.equals("load")) {
throw new AgentLoadException("Failed to load agent library"); throw new AgentLoadException("Failed to load agent library");
} else { } else {
throw new IOException("Command failed in target VM"); if (message == null) {
throw new AttachOperationFailedException("Command failed in target VM");
} else {
throw new AttachOperationFailedException(message);
}
} }
} }
......
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -198,14 +198,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_read ...@@ -198,14 +198,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_BsdVirtualMachine_read
len = remaining; len = remaining;
} }
RESTARTABLE(read(fd, buf+off, len), n); RESTARTABLE(read(fd, buf, len), n);
if (n == -1) { if (n == -1) {
JNU_ThrowIOExceptionWithLastError(env, "read"); JNU_ThrowIOExceptionWithLastError(env, "read");
} else { } else {
if (n == 0) { if (n == 0) {
n = -1; // EOF n = -1; // EOF
} else { } else {
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off)); (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
} }
} }
return n; return n;
......
...@@ -416,14 +416,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_LinuxVirtualMachine_read ...@@ -416,14 +416,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_LinuxVirtualMachine_read
len = remaining; len = remaining;
} }
RESTARTABLE(read(fd, buf+off, len), n); RESTARTABLE(read(fd, buf, len), n);
if (n == -1) { if (n == -1) {
JNU_ThrowIOExceptionWithLastError(env, "read"); JNU_ThrowIOExceptionWithLastError(env, "read");
} else { } else {
if (n == 0) { if (n == 0) {
n = -1; // EOF n = -1; // EOF
} else { } else {
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off)); (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
} }
} }
return n; return n;
......
/* /*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -161,14 +161,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_SolarisVirtualMachine_read ...@@ -161,14 +161,14 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_SolarisVirtualMachine_read
len = remaining; len = remaining;
} }
RESTARTABLE(read(fd, buf+off, len), n); RESTARTABLE(read(fd, buf, len), n);
if (n == -1) { if (n == -1) {
JNU_ThrowIOExceptionWithLastError(env, "read"); JNU_ThrowIOExceptionWithLastError(env, "read");
} else { } else {
if (n == 0) { if (n == 0) {
n = -1; // EOF n = -1; // EOF
} else { } else {
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off)); (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf));
} }
} }
return n; return n;
......
/* /*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,15 +24,15 @@ ...@@ -24,15 +24,15 @@
*/ */
package sun.tools.attach; package sun.tools.attach;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AttachOperationFailedException;
import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AgentLoadException;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.spi.AttachProvider; import com.sun.tools.attach.spi.AttachProvider;
import sun.tools.attach.HotSpotVirtualMachine; import sun.tools.attach.HotSpotVirtualMachine;
import java.io.IOException; import java.io.IOException;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Properties;
import java.util.Random; import java.util.Random;
public class WindowsVirtualMachine extends HotSpotVirtualMachine { public class WindowsVirtualMachine extends HotSpotVirtualMachine {
...@@ -105,11 +105,17 @@ public class WindowsVirtualMachine extends HotSpotVirtualMachine { ...@@ -105,11 +105,17 @@ public class WindowsVirtualMachine extends HotSpotVirtualMachine {
// read completion status // read completion status
int status = readInt(is); int status = readInt(is);
if (status != 0) { if (status != 0) {
// read from the stream and use that as the error message
String message = readErrorMessage(is);
// special case the load command so that the right exception is thrown // special case the load command so that the right exception is thrown
if (cmd.equals("load")) { if (cmd.equals("load")) {
throw new AgentLoadException("Failed to load agent library"); throw new AgentLoadException("Failed to load agent library");
} else { } else {
throw new IOException("Command failed in target VM"); if (message == null) {
throw new AttachOperationFailedException("Command failed in target VM");
} else {
throw new AttachOperationFailedException(message);
}
} }
} }
......
...@@ -341,7 +341,7 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_WindowsVirtualMachine_readPipe ...@@ -341,7 +341,7 @@ JNIEXPORT jint JNICALL Java_sun_tools_attach_WindowsVirtualMachine_readPipe
if (nread == 0) { if (nread == 0) {
return (jint)-1; // EOF return (jint)-1; // EOF
} else { } else {
(*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf+off)); (*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf));
} }
} }
......
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -569,7 +569,7 @@ public class JMXStartStopTest { ...@@ -569,7 +569,7 @@ public class JMXStartStopTest {
final boolean[] checks = new boolean[3]; final boolean[] checks = new boolean[3];
jcmd( jcmd(
line -> { line -> {
if (line.equals("java.lang.RuntimeException: Invalid agent state")) { if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
checks[0] = true; checks[0] = true;
} }
}, },
...@@ -580,7 +580,7 @@ public class JMXStartStopTest { ...@@ -580,7 +580,7 @@ public class JMXStartStopTest {
jcmd( jcmd(
line -> { line -> {
if (line.equals("java.lang.RuntimeException: Invalid agent state")) { if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
checks[1] = true; checks[1] = true;
} }
}, },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册