2013-10-12 5 views
1

Я пытаюсь ввести код в класс JDK, Integer. Инъекция работает до тех пор, пока я остаюсь внутри Groovy, но не пытаюсь использовать введенный код с Java-клиента.Groovy/Java: инъекция метода в классе JDK, не видном из Java

Произошла демонстрация проблемы.

Следующая Groovy код ...

// File: g.groovy 
class G { 
    public static void init() { 
     println 'Constructor injected'; 
     java.lang.Integer.metaClass.constructor = { i -> 
      println "My constructor called for Integer($i)" 
      def constructor = Integer.class.getConstructor(int.class) 
      constructor.newInstance(i) 
     } 
    } 

    public static void main(String[] args) { 
     G.init(); 
    } 
} 

println 'Before injection' 
new Integer(1); 

G.init() 

new Integer(1); 

... дает мне правильный вывод:

$ groovy g.groovy 
Before injection 
Constructor injected 
My constructor called for Integer(1) 
$ 

Теперь я удаляю все от g.groovy КРОМЕ class G:

// File: g.groovy 
class G { 
    public static void init() { 
     println 'Constructor injected'; 
     java.lang.Integer.metaClass.constructor = { i -> 
      println "My constructor called for Integer($i)" 
      def constructor = Integer.class.getConstructor(int.class) 
      constructor.newInstance(i) 
     } 
    } 

    public static void main(String[] args) { 
     G.init(); 
    } 
} 

Затем компилирую g.groovy:

$ groovyc g.groovy 
$ ls *.class 
G.class G$_init_closure1.class 
$ 

Затем я пытаюсь использовать инъекции из U.java:

// U.java 
public class U { 
    public static void main(String[] args) { 
     System.out.println("Creating a new integer"); 
     new Integer(1); 

     G.init(); 

     System.out.println("Creating a new integer"); 
     new Integer(1); 
    } 
} 

И результат я получаю это:

$ javac U.java 
$ java -cp .:/path/to/groovy/embeddable/groovy-all-2.1.7.jar U 
Creating a new integer 
Constructor injected 
Creating a new integer 
$ 

Инъекция явно не работает!

ответ

3

Java не имеет понятия о метаклассе, так что это не будет работать со стороны Java, как вы видели

+0

О, мальчик! Мне нужно перехватить и переопределить некоторые устаревшие приложения Java, для которых у меня нет исходного кода. Я думал, что Groovy каким-то образом вложил бы свой материал, связанный с MOP, в файлы Java '.class', и я закончу! Что мне теперь делать?? – Harry

+2

@ Харри взглянуть на aspectj. Я не эксперт, но я уверен, что вы можете сплести аспекты в байт-код без доступа к соответствующему источнику. –

+0

Я знал об аспекте, но пытался/не пытался использовать его, потому что никогда не использовал его, и поэтому мне было бы сложно (относительно Groovy MOP) понять и использовать его в таком коротком уведомлении :-( – Harry