инструментарий класса Java System - PullRequest
0 голосов
/ 02 ноября 2018

Я новичок в приборостроении. Мне нужно добавить статическую переменную и, возможно, статический метод позже в одном из классов начальной загрузки, java.lang.String. Я пробовал Javassist и ASM, но оба сообщают об ошибке,

> Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(Unknown Sou
rce)
        at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown So
urce)

Caused by: java.lang.UnsupportedOperationException: class redefinition failed: a
ttempted to change the schema (add/remove fields)
        at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)

        at sun.instrument.InstrumentationImpl.retransformClasses(Unknown Source)

вот мой метод преобразования и код ASM,

        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                                ProtectionDomain domain, byte[] classfileBuffer) 

      {

        if (className.startsWith("java/lang/String")) {
            try {
                classfileBuffer = modifyField(classfileBuffer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        return classfileBuffer
    }

public static byte[] modifyField(byte[] origClassData) throws Exception {
    ClassReader cr = new ClassReader(origClassData);
    final ClassWriter cw = new ClassWriter(cr, ASM5);
    // add the static final fields
    cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "bVal","Z", null, new Boolean("false")).visitEnd();
    // wrap the ClassWriter with a ClassVisitor that adds the static block to
    // initialize the above fields
    ClassVisitor cv = new CustomVisitor(ASM5, cw);
    // feed the original class to the wrapped ClassVisitor
    cr.accept(cv, 0);
    // produce the modified class
    byte[] newClassData = cw.toByteArray();
    return newClassData;
}

Я также установил значение ИСТИНА для классов Can-Redefine-Classes и Can-Retransform-Classes.

Спасибо за вашу помощь

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

У меня была такая же проблема некоторое время назад. Я могу указать вам на мой вопрос, который может вам помочь.

Похоже, что с Javassist вы можете изменить тело нативного метода, но не можете добавлять методы или поля . Посмотрите на этот вопрос: Агент Java не может преобразовать все классы в моем проекте

0 голосов
/ 04 ноября 2018

JVM не позволяет добавлять поля или любые другие изменения в формате файла класса, как указывает исключение. Существуют специальные сборки OpenJDK, такие как JVM с динамическим развитием кода, которые позволяют это, но большинство JVM не поддерживают это.

...