Context: A new class, say Bar, is injected into the JVM at runtime. This class belongs to the say com.foo package. A reference to this class is entered in another class that belongs to the same package. A new class may have a different name each time it is loaded - therefore, it cannot be specified as part of any configuration file - for example, it cannot be specified in the build.xml file, which will be included as part of the jar file.
Question: At the moment the jvm class is loaded, it generates an error - java Result 1. Although I can’t definitively determine the root cause, it seems that the newly introduced class was not found by the class loader. The server was started in verbose mode, which shows a list of classes loaded by the JVM, and this newly introduced class will be loaded.
Question: Is a newly introduced class already in classpath? If you do not install it?
[Change] - adding some code to the question.
Code Segment - 1: This code segment below is called from the PreMain method. The Premain method will be called by the JVM agent and will enter a reference to the hardware at runtime. The Premain method introduces 1 new class - Bar - and 1 reference to this new class from the method - returnsABool () - to the existing class - ExistingClass.
public static void premain(String agentArgs, Instrumentation inst) {
String className = "Bar";
byte [] b = getBytesForNewClass();
Class clazz = null;
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class cls = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method =
cls.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class });
method.setAccessible(true);
try {
Object[] args = new Object[] { className, b, new Integer(0), new Integer(b.length)};
clazz = (Class) method.invoke(loader, args);
} finally {
method.setAccessible(false);
}
} catch (Exception e) {
System.err.println(
"AllocationInstrumenter was unable to create new class" + e.getMessage());
e.printStackTrace();
}
inst.addTransformer(new CustomInstrumenter(), true);
}
Sement 2 code: the returnsABool () method should be entered in the line comment bytes shown below. The code for entering the byte is also called from the PreMain method.
public class ExistingClass{
public static boolean returnsABool() {
return false;
}
}
Insert byte code for ExistingClass - performed using asm library
{
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/Bar", "get", "()Ljava/lang/String;");
mv.visitLdcInsn("some constant here");
Label l1 = new Label();
mv.visitJumpInsn(Opcodes.IF_ACMPNE, l1);
mv.visitInsn(Opcodes.ICONST_0); Label l2 = new Label();
mv.visitJumpInsn(Opcodes.GOTO, l2);
mv.visitLabel(l1);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(Opcodes.ICONST_1);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {Opcodes.INTEGER});
mv.visitInsn(Opcodes.IRETURN);
mv.visitMaxs(2, 0);
mv.visitEnd();
}