java 不重启部署_Java是否可以做到修改类而不用重启JVM?

For external users, the answer is YES. For detail, it is not completely YES. The points are:

A class is loaded by a classloader and its content is constant in the Constant Pool. You can not change a class that has already been loaded in a class loader, nor you are not allowed to load the bytecode with the same symbol name in that class loader again (though HotSpot has many hacks to enable developers to breaks this rule by UNSafe ). This should be in JVM specification.

Though #1, you still can generate a bytecode class (e.g., addition, removal, modification of class fields, methods as well as their bodies,ANY CHANGE YOU WANT) at program runtime, and then define the class by a class loader. This means, you can either generate a class from scratch or from byte[] of an existing loaded class (the one from the classloader or external inputstream) without JVM reboot. The frameworks, such as JSP servlet and other dynamic JVM languages are all this case.

Some fundamental libraries can help dynamic bytecode generation (e.g., CGLib, BCEL, Javaassist and ASM). A general approach using ASM is something like (from ASM example):

ClassWriter cw = new ClassWriter(0);

cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null);

mw.visitVarInsn(ALOAD, 0);

mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V",

false);

mw.visitInsn(RETURN);

mw.visitMaxs(1, 1);

mw.visitEnd();

mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",

"([Ljava/lang/String;)V", null, null);

mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",

"Ljava/io/PrintStream;");

mw.visitLdcInsn("Hello world!");

mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",

"(Ljava/lang/String;)V", false);

mw.visitInsn(RETURN);

mw.visitMaxs(2, 2);

mw.visitEnd();

byte[] code = cw.toByteArray();

//Then having a class loader loads it.

The document(http://download.forge.objectweb.org/asm/asm4-guide.pdf) should be helpful though it is obsolete.

In summary, the meanings of "not completely YES" are:

1) Create a new byte[] from byte[] of an existing loaded class, and have it loaded by another class loader. The class newly generated is not completely the same instance as the existing one (the same class name, but different body maybe).

2) //Use Constant Pool Patch to redefine the same Class in one class loader (This is out of scope, I think..)..

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值