Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 异常上变量的转储状态_Java_Debugging_Exception - Fatal编程技术网

Java 异常上变量的转储状态

Java 异常上变量的转储状态,java,debugging,exception,Java,Debugging,Exception,我想知道是否有一种方法可以在出现异常时转储所有局部变量的状态,以便更好地了解导致异常的环境状态。下面的变量idsToDump在运行时未知,我想找出集合中的值导致NPE的状态 for (Integer employeeId : idsToDump) { System.out.println(employeeId); String name = employees.get(employeeId).toLowerCase(); System.out.println(name + " is

我想知道是否有一种方法可以在出现异常时转储所有局部变量的状态,以便更好地了解导致异常的环境状态。下面的变量
idsToDump
在运行时未知,我想找出集合中的值导致NPE的状态

for (Integer employeeId : idsToDump) {
  System.out.println(employeeId);
  String name = employees.get(employeeId).toLowerCase();
  System.out.println(name + " is employee number: " + employeeId);
}
例如:

public static void main(String[] args) {
    HashMap<Integer, String> employees = new HashMap<Integer, String>();
    employees.put(1, "James");

    Integer[] idsToDump = new Integer[] { 1, 2, 3 };
    for (Integer employeeId : idsToDump) {
        String name = employees.get(employeeId).toLowerCase();
        System.out.println(name + " is employee number: " + employeeId);
    }

}
问题: 我是否可以传递一些JVM参数来转储有关局部变量当前状态的信息?我们得到

java.lang.NullPointerException
(这是我要找的部分)


我希望能够在客户端站点上实现这一点,因此,没有访问Eclipse或调试工具的权限,只查找JVM参数,也无法进行代码更改。我已经看过了,但什么也没找到。与此同时,我也会继续在那里搜索;)

最简单的方法是在调试器中运行此代码并逐步执行。如果无法调试代码,则可以使用try/catch块并将employeeId设置在以下范围之外:

int debugEmployeeId = -1;
try {
    Integer[] idsToDump = new Integer[] { 1, 2, 3 };
    for (Integer employeeId : idsToDump) {
        debugEmployeeId = employeeId;
        ...
} catch (Exception e) {
    throw new Exception("Missing employeeId = " + Integer.toString(debugEmployeeId));
}

您最好的选择,afaik,是旧的手动方式:使用某种类型的日志记录(无论是Log4J,还是仅仅是stdout),并通过
catch
块显式记录您感兴趣的变量。

考虑到您的所有限制,除了jdb之外,我不推荐任何其他方法。启动那个坏家伙,开始逐行检查客户机代码。我知道你说没有调试工具,但是除非它们是一个只有JRE的环境,否则你应该已经安装了jdb。

尽管你提到你不能做任何代码更改,这里有一个关于代码更改仍然可能的提示:获取有关异常的更多信息的一个方便工具是抛出的异常对象的“printStackTrace”方法。你可能想用这样的东西


try {
...
}
catch ( Exception e ) {
  System.out.println( "Exception occured! Reason: " + e.printStackTrace() );
}

和Thomas一样,我不知道当前有哪种方法可以转储变量。但是,我相信您希望这样做是为了帮助您进行调试。以下是一些简单的方法,我仅使用控制台调试代码:

1.学习在异常发生时读取stacktrace。它为您提供了大量可能导致异常的信息。如果stacktrace指向的特定行似乎没有任何错误,请追溯代码并查看是否是导致异常的Previor对象。例如(使用一些示例代码和方法):

类似的东西会导致NPE stacktrace指向
bookshelf
,但实际上正是
book
导致了NPE

for (Integer employeeId : idsToDump) {
  System.out.println(employeeId);
  String name = employees.get(employeeId).toLowerCase();
  System.out.println(name + " is employee number: " + employeeId);
}
2.打印出您怀疑导致NPE的变量

for (Integer employeeId : idsToDump) {
  System.out.println(employeeId);
  String name = employees.get(employeeId).toLowerCase();
  System.out.println(name + " is employee number: " + employeeId);
}
您的输出将是:

1
2
然后你就会知道,
2
导致了NPE

for (Integer employeeId : idsToDump) {
  System.out.println(employeeId);
  String name = employees.get(employeeId).toLowerCase();
  System.out.println(name + " is employee number: " + employeeId);
}
3.注释掉可疑代码并系统地取消注释掉代码,直到出现异常,反之亦然


虽然有时你会发现它很乏味,令人沮丧,但它在你的基础上确实有帮助,因为通过足够的实践,你很快就能直观地发现错误通常发生在哪里(因此在未来调试上花费更少的时间)。.

我遇到了一个商业产品,它通过简单地使用startup-agentlib JVM代理参数来实现这一点。我还没有用过它,但打算尝试一下,因为它看起来很有前途


任何人都有使用此产品的经验吗?

AFAIK没有办法做到这一点,尤其是不使用VM参数。为什么不能使用try/catch并打印catch中的变量?可以使用调试器来完成这一点。您可以在运行异常时添加断点,这样您就可以看到所有的本地变量。注意到
无法访问Eclipse或调试工具,只能查找JVM参数,也无法更改代码
如果您可以访问JVM参数,则可以访问调试工具。请参阅一般异常是坏的。OP说这是一个
NullPointerException
,所以捕获并重新显示它。而且
无法访问Eclipse或调试工具,只查找JVM参数,也无法更改代码。
。一致同意的通用异常形式不好,对于快速调试代码或不向上抛出异常的要求,是使用该类的唯一原因。至少在java <代码> catch(异常)< />是一个选项,在C++中,代码> catch(…)<代码>并不总是有效的。我认为他的请求不需要代码更改或远程调试器就可以完成。这就是我在我(6)年的java开发中所想到的,但是我想我会用一个更高的开发人员来运行它。1.我可以读取stacktrace中的日志,我知道我从地图中得到一个空值。要么键不在映射中,要么映射的值为null,无论哪种情况,我都要转储键。2.无法打印,因为这是一个封闭的罐子。3.无法进行代码更改。我确实有堆栈跟踪,我知道问题是我从Map.get()返回null。嘿,注意,我认为这可能是最好的方法(如果客户端安装了JDK),我们只提供JRE。我将在我的开发环境中尝试这一点,看看它的效果如何。如果成功的话,我将部署一个JDK。Takipi(overops.com)是一个非常有用的java状态捕获和聚合产品。强烈推荐给那些买得起的人。