2016-04-26 3 views
2

Я пытаюсь сделать OGM для перевода объекта в Vertex для OrientDB. В настоящее время я использую GCLib, но я читаю, что ByteBuddy может реализовать две критические вещи, которые, если они работают, улучшат скорость OGM.ByteBuddy: Как реализовать перехватчик доступа к полю?

  1. Может ли ByteBuddy реализовать контроль доступа к полю? Я читал документ, но это не ясно или я не понимаю.

  2. Динамически добавлять пустой конструктор по умолчанию.

Текущая проблема заключается в следующем: мы не знаем определения класса, которое будет передано как параметр. Идея состоит в том, чтобы переопределить класс и реализовать пустой конструктор, если он его не имеет, добавьте поле с именем __BB__Dirty, чтобы установить объект как грязный, если была обнаружена операция назначения, и заставить реализацию интерфейса взаимодействовать с объектом.

Пример: Общий класс:

public class Example { 
    int i = 0; 
    String stringField; 

    public Example(Strinf s) { 
     stringField = s; 
    } 

    public void addToI(){ 
     i++; 
    } 
} 

Теперь у нас есть интерфейс вроде этого:

public interface DirtyCheck { 
    public boolean isDirty(); 
} 

Итак, я хочу, чтобы заставить Пример класса для реализации интерфейса, метод isDirty(), поле для работы и конструктор по умолчанию, поэтому класс следует перевести на:

public class Example implements DirtyCheck { 
    int i = 0; 
    String stringField; 

    boolean __BB__dirty = false; 

    public Example() { 

    } 

    public Example(Strinf s) { 
     stringField = s; 
    } 

    public void addToI(){ 
     i++; 
    } 

    public boolean isDirty() { 
     return this.__BB__dirty; 
    } 
} 

и некоторое магическое задание, поэтому, если какое-либо поле (кроме __BB__dirty) изменено, поле __BB__dirty установлено на True;

Я попробовал первую часть этого, но я не :(

... 
ByteBuddyAgent.install(); 

Example ex = new ByteBuddy() 
       .redefine(Example.class) 
       .defineField("__BB__Dirty", boolean.class, Visibility.PUBLIC) 
       .make() 
       .load(Example.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent()) 
       .getLoaded().newInstance(); 
.... 

ex.addToI(); // <--- this should set __BB__dirty to true since it 
       //  assign a value to i. 

Но я получаю эту ошибку:

Exception in thread "main" java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields) 
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method) 
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170) 
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy$Strategy$1.apply(ClassReloadingStrategy.java:297) 
at net.bytebuddy.dynamic.loading.ClassReloadingStrategy.load(ClassReloadingStrategy.java:173) 
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4350) 
at Test.TestBB.<init>(TestBB.java:33) 
at Test.TestBB.main(TestBB.java:23) 

i'am застрял в самом первом этапе, чтобы решить эту проблему с BB. Thanks

ответ

0

Виртуальная машина Java не поддерживает изменение макета классов, которые уже загружены при переопределении класса. Это не ограничение te Buddy, но реализация VM.

Для того, чтобы сделать то, что вы хотите, вы должны посмотреть на API AgentBuilder, который позволяет вам изменять классы до. Создание агента тем не менее требует, чтобы добавить его в явном виде в качестве агента при запуске (в отличие от добавления библиотеки в пути класса

Вы можете реализовать интерфейс по телефону:.

.implement(DirtyCheck.class).intercept(FieldAccessor.of("__dirty__"); 

Вы можете также добавить конструктор по умолчанию, просто определив одно:

.defineConstructor(Visibility.PUBLIC).intercept(SuperMethodCall.INSTANCE) 

Последнее определение требует высшего класса, чтобы определить конструктор по умолчанию

+0

Спасибо за ответ..Javadoc efectivelly говорит, что до сих пор не допускается добавление поля или метода, и эта функция будет добавлена ​​в будущую версию. Я полагаю, что мне нужно найти другой путь. Я закончу OGM с помощью GCLib и в ближайшее время вернусь, чтобы увидеть, могу ли я реализовать его в BB в ясной форме. –

+0

Добро пожаловать. Обратите внимание, что вы можете делать все возможное с помощью cglib также с Byte Buddy только, что Byte Buddy предлагает лучшую производительность во время выполнения. –

Смежные вопросы