Я использую Invesdwin (https://github.com/subes/invesdwin-instrument) для динамической загрузки java агентов в мой проект Spring Boot в основном методе до запуска контекста:
DynamicInstrumentationLoader.waitForInitialized();
DynamicInstrumentationLoader.initLoadTimeWeavingContext();
ApplicationContext springContext = SpringApplication.run(Some_Service.class);
...
Это отлично работает, поскольку устраняет необходимость добавления параметров -javaagent при запуске команды java -jar из командной строки.
Проблема возникает, когда дело доходит до юнит-тестов. Поскольку у них нет основного метода (который я могу использовать), я не могу заставить эти две строки работать до инициализации Spring Context. Без этих аргументов каждый тест приведет к невозможности загрузки контекста с этой ошибкой:
ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:spring-instrument-{version}.jar
Я могу обойти это во время окончательной сборки, настроив плагин Surefire таким образом в моем POM:
<!--Maven Surefire Plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<argLine>
-javaagent:lib/aspectjweaver-1.9.5.jar
-javaagent:lib/spring-instrument-5.2.3.RELEASE.jar
</argLine>
</configuration>
</plugin>
К сожалению, это работает только во время финальной фазы сборки. Запуск отдельного метода тестирования в Eclipse завершится неудачей, если я не добавлю эти параметры вручную в конфигурацию запуска для этого теста, что, по меньшей мере, является болью.
Я создал собственный класс runner, пытаясь заставить код выполняться до инициализации контекста Spring, например:
public class WeavingRunner extends SpringJUnit4ClassRunner
{
public WeavingRunner(Class<?> clazz) throws InitializationError
{
super(clazz);
DynamicInstrumentationLoader.waitForInitialized();
DynamicInstrumentationLoader.initLoadTimeWeavingContext();
}
}
Хотя консоль Eclipse дает мне подсказки о том, что происходит переплетение Когда мой базовый тест использует этот класс бегуна вместо SpringRunner, я получаю всевозможные ошибки ткачества, которые, по-видимому, указывают на то, что динамическое ткачество c произошло не достаточно скоро:
java.lang.NoSuchMethodException: com.something.SomeAspectClass.aspectOf()
Есть ли известный способ реплицировать код, выполняемый в основном методе, при запуске тестов JUnit?
****** РЕДАКТИРОВАТЬ ******
Я заметил нечто чрезвычайно странное с этим. Если я запускаю пакет, содержащий тесты как тест JUnit, это работает! Вышеуказанные ошибки переплетения появляются только при запуске папки src / test / java в качестве теста JUnit в Eclipse или при запуске самого приложения в качестве теста JUnit (который мне в конечном счете необходим). Динамическое плетение c работает, но почему-то что-то заставляет его работать только при выполнении отдельных тестов или до включения пакета в качестве теста JUnit. Я надеюсь, что это имеет смысл!
Я начинал подозревать проблемы с моим файлом aop. xml, но как это могло быть проблемой, если запуск отдельных тестов и даже целых пакетов работает нормально?!