Я пытаюсь ввести код в класс 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
$
Инъекция явно не работает!
О, мальчик! Мне нужно перехватить и переопределить некоторые устаревшие приложения Java, для которых у меня нет исходного кода. Я думал, что Groovy каким-то образом вложил бы свой материал, связанный с MOP, в файлы Java '.class', и я закончу! Что мне теперь делать?? – Harry
@ Харри взглянуть на aspectj. Я не эксперт, но я уверен, что вы можете сплести аспекты в байт-код без доступа к соответствующему источнику. –
Я знал об аспекте, но пытался/не пытался использовать его, потому что никогда не использовал его, и поэтому мне было бы сложно (относительно Groovy MOP) понять и использовать его в таком коротком уведомлении :-( – Harry