aspectjload-time-weaving

AspectJ with jar classloader


I am trying to instrument Oracle Rest Data Service (ORDS) which is built on Jetty. The aspect should trace JDBC calls. I do not see the weaving happening.

I have tried AspectJ in a different standalone application which used JDBC and also profiled Servlet calls in an application running in standalone Jetty and all this worked for me. But in this case there is an exception and it does not look that weaving is happening. Application itself works as expected with all AspectJ configurations applied.

Two options have been tried:

   ├── WEB-INF
   │   ├── beans.xml
   │   ├── classes
   │   │   ├── META-INF
   │   │   │   ├── MANIFEST.MF
   │   │   │   └── aop-ajc.xml
   │   │   └── WhereTheStatementTimeGo.class 

There was an exception like below in both cases.

Here is the command line and the exception:

$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

There was no any AspectJ tracing related info in the output


Solution

  • I found a workaround which lets me run the server without problems and also use different types of aspect pointcuts on all sorts of classes such as internal Jetty classes:

    Copy the AspectJ weaver and your aspect library (JAR containing aspects and META-INF/aop.xml) to a subdirectory lib of where you are starting your ords.war. Then append the aspect library to the JVM boot classpath. You need to use a JRE/JDK version like Java 8 which actually still supports the boot classpath. (Actually I just checked, JDK 11 still supports it.) I don't know how to do this with modularised JREs. Then start your WAR like this:

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

    One more time, with line breaks inserted:

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

    This approach makes sure that the weaver is attached and its as well as the aspect classes are found before the Oracle JAR classloader does its entry point magic.

    Please note that you do not need to modify the WAR file at all here.


    Update: As an alternative you could attach the AspectJ weaving agent dynamically instead of via -javaagent, see

    I quickly tested it, it works. It is kind of tricky, though:

    All in all I still favour the original solution, it is much easier to implement.