Тестовое задание для летней практики JetBrains 2017.
-
JVM bytecode https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
Можно начать отсюда http://www.javaworld.com/article/2077233/core-java/bytecode-basics.html
И посмотреть сюда https://www.slideshare.net/CharlesNutter/javaone-2011-jvm-bytecode-for-dummies -
Манипуляция байткодом через библиотеку ASM http://asm.ow2.org
Введение здесь http://asm.ow2.org/doc/tutorial.html -
Написание Java Agent-ов https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html
Пример инструментации кода здесь https://www.captechconsulting.com/blogs/not-so-secret-java-agents---part-1 -
Язык Kotlin https://kotlinlang.org
Очень рекомендуется https://kotlinlang.org/docs/tutorials/koans.html -
Корутины в языке Kotlin https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md
А также библиотека к ним https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md -
Любить и использовать IntelliJ IDEA (Community Edition) https://www.jetbrains.com/idea/
Котлин поддерживается "из коробки" -
Работать с проектом на Gradle https://gradle.org
Работа с Котлином описана здесь https://kotlinlang.org/docs/reference/using-gradle.html
В этом репозитории содержится проект-затравка (открывать в IntelliJ IDEA):
- Файл Agent.kt содержит минимальныое тело Java Agent-а.
- Файл CoroutineExample.kt содержит код тестового приложения.
Сборка и запуск приложения
gradlew runApp
При этом запускается код тестового приложения, которое выводит на консоль:
Agent started.
Started!
Done.
Первая строчка выводится внутри Agent
, а остальные две внутри CoroutineExample
.
Ваша задача модифицировать Agent
так, чтобы все подгужаемые классы приложения трансформировались используя ASM.
При этом, внутри байткода CoroutineExample
есть вот такой вызов:
INVOKESTATIC example/CoroutineExampleKt.test (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
Посмотреть байткод можно в IntelliJ перейдя на строку
test()
вCoroutineExample
и сделав через Ctrl/Cmd-Shift-A акцию "Show Kotlin Bytecode"
В процессе трансформации ваш агент должен искать именно этот вызов (в любом загружаемом коде) и вставлять прямо перед ним вывод на экран строки "Test detected". В результате, при запуске приложения должно получиться:
Agent started.
Started!
Test detected
Done.
Обратите внимание, что при модификации тестового приложения (добавление более сложной логики, множественные вызовы test()
)
транформация должна продолжать перехватывать все вызовы test()
и помечать их выводом на экран "Test detected".