我正在尝试为Java Runtime Environment编辑java.lang.Object。我意识到可能有更好的方法来做我想做的事情,但这不是我要问的问题。
基本上,我已经向java.lang.Object添加了一个构造函数,每次创建对象时都会调用该构造函数。我正在等待某个类加载,如下所示:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}
}
}
hookEnabled = true;
}
}这可以很好地工作。它为JVM正在运行的任何应用程序添加一个窗口。
但是,当通过将JFrame代码移到单独的类中并调用该调用来进行简单的更改时,JVM就会崩溃:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
(new tvmh.DFVMH()).setup();
}
}
}
}
hookEnabled = true;
}
}--
package tvmh;
public class DFVMH {
public void setup() {
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}当我尝试创建java.util.Timer对象时,也会发生同样的情况。
有趣的是,如果我让DFVMH成为java.lang.Object本身的内联类(内部类),上面的方法就可以工作。
谁能告诉我为什么会发生这样的行为?有没有办法安全地调用这样的自定义类呢?
发布于 2011-02-22 07:24:13
像这样对JVM的内部进行修补是非常危险的。在JVM的低级上有各种各样的隐藏依赖项可能会被破坏。JVM引导是一个非常微妙的过程。
例如,您看到崩溃而不是StackOverflowError的最可能原因是您的更改破坏了所有对象构造……包括错误对象的构造。
我怀疑您的保护代码是无效的,因为this.getClass().getName()可能会导致创建一个字符串对象。所以致命的递归发生在你的守卫之前。
(顺便说一下,您的hasHooked标志引入了竞争条件。)
我的建议是“不要这样做!”
发布于 2011-02-22 06:15:18
你说的‘它崩溃’是什么意思?
不是StackOverflowException吗?你的new tvmh.DFVMH()实际上也是一个构造器。所以它通过你的“重写”对象构造函数来运行。
如果你已经这样玩了,添加tvmh.DFVMH来停止包/类的列表怎么样?
发布于 2011-02-22 06:15:56
简单地想一下:new tvmh.DFVHM()成为一个新对象,它也是从java.lang.Object派生的,这意味着在第一个构造函数完成之前,您的自定义构造函数代码将再次运行。我猜"hasHooked“应该防止这种情况发生,但是这个变量是如何定义的呢?如果该保护不起作用,该序列将无限递归。
如果你让DFVMH成为一个内联类,它的名字可能会以"java.lang...“开头。(毕竟它是在java.lang.Object中),因此无法使用所有的name.startsWith通过长的if语句。
https://stackoverflow.com/questions/5071803
复制相似问题