AspectJ с загрузчиком классов jar - PullRequest
2 голосов
/ 03 июля 2019

Я пытаюсь использовать Oracle Rest Data Service (ORDS), которая построена на Jetty.Аспект должен отслеживать вызовы JDBC.Я не вижу, чтобы ткачество происходило.

Я пробовал AspectJ в другом автономном приложении, которое использовало JDBC, а также профилированные вызовы сервлетов в приложении, работающем в автономном Jetty, и все это работало для меня.Но в этом случае есть исключение и не похоже, что ткачество происходит.Само приложение работает, как и ожидалось, со всеми примененными конфигурациями AspectJ.

Были опробованы две опции:

  • Класс аспектов и файл конфигурации AOP были помещены в jar, и этот jar был помещен в WEB-INF / Lib.aspectjrt.jar также был скопирован в этот каталог.
  • класс аспектов и конфигурация аспектов были скопированы в WEB-INF / классы, подобные этому
   ├── WEB-INF
   │   ├── beans.xml
   │   ├── classes
   │   │   ├── META-INF
   │   │   │   ├── MANIFEST.MF
   │   │   │   └── aop-ajc.xml
   │   │   └── WhereTheStatementTimeGo.class 

Было исключение, подобноениже в обоих случаях.

Вот командная строка и исключение:

$JAVA_HOME/bin/java -javaagent:/DATA/PROJECTS/ASPECTJ19/lib/aspectjweaver.jar -Dorg.aspectj.tracing.enabled=true -Dorg.aspectj.tracing.factory=defaug.aspectj.tracing.messages=true   -jar ords.war standalone

[JarClassLoader@17f052a3] warning parse definitions failed -- (IllegalStateException) sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
java.lang.IllegalStateException: sun.misc.Launcher$AppClassLoader@18b4aac2
    at oracle.dbtools.jarcl.NestedResourceHandler.jarClassLoader(NestedResourceHandler.java:36)
    at oracle.dbtools.jarcl.NestedResourceHandler.openConnection(NestedResourceHandler.java:23)
    at java.net.URL.openConnection(URL.java:979)
    at java.net.URL.openStream(URL.java:1045)
    at org.aspectj.weaver.loadtime.definition.DocumentParser.saxParsing(DocumentParser.java:157)
    at org.aspectj.weaver.loadtime.definition.DocumentParser.parse(DocumentParser.java:123)
    at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.parseDefinitions(ClassLoaderWeavingAdaptor.java:290)
    at org.aspectj.weaver.loadtime.DefaultWeavingContext.getDefinitions(DefaultWeavingContext.java:130)
    at org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor.initialize(ClassLoaderWeavingAdaptor.java:174)
    at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.initialize(Aj.java:337)
    at org.aspectj.weaver.loadtime.Aj$ExplicitlyInitializedClassLoaderWeavingAdaptor.getWeavingAdaptor(Aj.java:342)
    at org.aspectj.weaver.loadtime.Aj$WeaverContainer.getWeaver(Aj.java:316)
    at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:108)
    at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:51)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at oracle.dbtools.jarcl.JarClassLoader.findClass(JarClassLoader.java:77)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at oracle.dbtools.jarcl.Entrypoint.invoke(Entrypoint.java:50)
    at oracle.dbtools.jarcl.Entrypoint.main(Entrypoint.java:77)

2019-07-02 16:47:29.822:INFO::main: Logging initialized @3375ms to org.eclipse.jetty.util.log.StdErrLog
Jul 02, 2019 4:47:29 PM  
INFO: HTTP and HTTP/2 cleartext listening on port: 8080
Jul 02, 2019 4:47:29 PM  
INFO: Disabling document root because the specified folder does not exist: /Users/slinetsk/Downloads/ORDS/ords/standalone/doc_root
2019-07-02 16:47:30.632:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-02-20T15:50:58.683Z; git: 3285c4dd4bb00caddcded77f8e44e72c61b9ab72; jvm 1.8.0_211-b12
2019-07-02 16:47:30.693:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2019-07-02 16:47:30.693:INFO:oejs.session:main: No SessionScavenger set, using defaults
2019-07-02 16:47:30.694:INFO:oejs.session:main: node0 Scavenging every 600000ms

В выводе не было никакой информации, связанной с трассировкой AspectJ

1 Ответ

0 голосов
/ 06 июля 2019

Я нашел обходной путь, который позволяет мне запускать сервер без проблем, а также использовать различные типы точек наложения аспектов для всех видов классов, таких как внутренние классы Jetty:

Скопируйте ткач AspectJ и вашу библиотеку аспектов (JAR, содержащий аспекты и META-INF / aop.xml ) в подкаталог lib , где вы начинаете свои орды .war . Затем добавьте библиотеку аспектов в путь к классу загрузки JVM. Вам нужно использовать версию JRE / JDK, такую ​​как Java 8, которая на самом деле все еще поддерживает загрузочный путь к классам. (На самом деле я только что проверил, JDK 11 все еще поддерживает его.) Я не знаю, как это сделать с модульными JRE. Затем начните свою WAR так:

java -Xbootclasspath/a:lib/aspect.jar -javaagent:lib/aspectjweaver.jar -jar ords.war standalone

Еще раз с вставленными переносами строк:

java
  -Xbootclasspath/a:lib/aspect.jar
  -javaagent:lib/aspectjweaver.jar
  -jar ords.war standalone

Этот подход гарантирует, что ткач присоединен и его классы, а также классы аспектов найдены до того, как загрузчик классов JAR Oracle выполнит магию точки входа.

Обратите внимание, что вам вообще не нужно изменять файл WAR.


Обновление: В качестве альтернативы вы можете подключить ткацкий агент AspectJ динамически, а не через -javaagent, см.

Я быстро проверил, все работает. Это довольно сложно, хотя:

  • Вы должны поместить свой собственный основной класс, аналогичный тому, который есть в AspectJ read-me, в WAR как основной класс. Этот класс прикрепит ткача и затем запустит загрузчик классов JAR. Теперь ткач уже на месте, и все работает, как ожидалось.
  • Предостережение заключается в том, что вам нужно запустить JVM с tools.jar, myaspect.jar и aspectjweaver.jar на пути к классам,
    • либо при загрузке classpath, если вы хотите запустить приложение с java -jar my.war
    • или по обычному classpath Вам, если можно запустить приложение с -cp ...;my.war my.own.MainClass.
  • Также, поскольку в Java 9 больше нет tools.jar, но вам нужно сделать свой собственный класс точки входа зависимым от модуля jdk.attach, а также убедиться, что вы действительно запускаете приложение с JDK, а не с JRE. В противном случае вы не сможете использовать API для динамического подключения агентов.

В целом, я все еще предпочитаю оригинальное решение, его гораздо проще реализовать.

...