Closed KimmingLau closed 7 months ago
Hello. Thanks for the report. What you say makes sense at first glance, but I would have to check if any consumers of transformed classes might expect non-null results for whatever reasons. Because I am unfamiliar with CDS archives, please provide a full, minimal example with exact steps to reproduce the problem. I want to see for myself what you are doing. Please also explain why you are doing it. I wonder why AspectJ firstly does not skip JDK classes when weaving and secondly tries to instrument code that is not visible to its class loader. There are too many open questions without a reproducer. Currently, I would not even know how to write a regression test for it.
Besides, is there any connection between this issue and #278? It strikes me as a strange coincidence, that two issues concerning class-loading are opened within just 10 minutes.
AppCdsDemo-1.0-SNAPSHOT-zip.zip
Hi. Thanks for your replies. Here is a reproducible demo, unzip it and run the following command with jdk21 runtime
java -XX:+UnlockDiagnosticVMOptions -XX:+AllowArchivingWithJavaAgent -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -javaagent:aspectjweaver-1.9.5.jar -cp AppCdsDemo-1.0-SNAPSHOT.jar com.vip.demo.Demo
You will see a crash when the JVM exits because it try to dump a CDS archive but validation failed. After Spending a lot time reading JVM source code, I found the root cause was that the AspectJ agent returned the original bytes when processing classes loaded by bootstrap classloader, but at the JVM level, as long as the return value of ClassFileTransformer is not null, it will be considered that the class has been modified and the returned byte array will be copied to new memory with a new pointer pointing to it.
You would say this is a JVM bug about CDS, yes, I think so too. But this phenomenon makes me have to think about that - is Aj#preProcess() method better to return null instead of the original bytes for classes loaded by bootstrap? Even for all classes that do not need to be woven.
By the way, we use CDS to improve the startup speed of the application, and most of us use AspectJ for monitoring and tracking. That's why we meet this situation.
lib
directory and have no idea what is in there.For reference, this is what I see on the console:
[0.398s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
[0.398s][warning][cds] Skipping org/aspectj/weaver/ResolvedType$Missing: Unsupported location
[0.398s][warning][cds] Skipping java/util/HashMap$HashMapSpliterator: Unsupported location
[0.399s][warning][cds] Skipping sun/management/VMManagement: Unsupported location
[0.399s][warning][cds] Skipping java/lang/invoke/GenerateJLIClassesHelper$HolderClassBuilder: Unsupported location
[0.399s][warning][cds] Skipping org/aspectj/apache/bcel/generic/Type$2: Unsupported location
[0.399s][warning][cds] Skipping org/aspectj/apache/bcel/classfile/ClassFormatException: Unsupported location
[0.401s][warning][cds] Skipping java/lang/management/ManagementFactory: Unsupported location
...
[0.402s][warning][cds] Skipping sun/management/VMManagementImpl: Unsupported location
[0.402s][warning][cds] Skipping java/util/TreeMap: Unsupported location
[0.402s][warning][cds] Skipping org/aspectj/apache/bcel/generic/InvokeDynamic: Unsupported location
[0.402s][warning][cds] Skipping java/lang/invoke/GenerateJLIClassesHelper: Unsupported location
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (systemDictionaryShared.cpp:575), pid=17044, tid=8792
# guarantee(!k->is_shared_unregistered_class()) failed: Class loader type must be set for BUILTIN class java/lang/invoke/BoundMethodHandle$Species_LLJ
#
# JRE version: Java(TM) SE Runtime Environment (21.0+35) (build 21+35-LTS-2513)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21+35-LTS-2513, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\alexa\Documents\java-src\AJ_GH-277\hs_err_pid17044.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
And this is the written error dump:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (systemDictionaryShared.cpp:575), pid=17044, tid=8792
# guarantee(!k->is_shared_unregistered_class()) failed: Class loader type must be set for BUILTIN class java/lang/invoke/BoundMethodHandle$Species_LLJ
#
# JRE version: Java(TM) SE Runtime Environment (21.0+35) (build 21+35-LTS-2513)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21+35-LTS-2513, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
--------------- S U M M A R Y ------------
Command Line: -XX:+UnlockDiagnosticVMOptions -XX:+AllowArchivingWithJavaAgent -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -javaagent:aspectjweaver-1.9.21.jar com.vip.demo.Demo
...
Environment Variables:
JAVA_HOME=c:\Program Files\Java\jdk-21
...
--------------- S Y S T E M ---------------
OS:
Windows 10 , 64 bit Build 19041 (10.0.19041.3636)
OS uptime: 2 days 20:27 hours
Hyper-V role detected
CPU: total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 142 stepping 9 microcode 0xec, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, fma, vzeroupper, clflush, clflushopt, hv, rdtscp, f16c
Processor Information for all 4 processors :
Max Mhz: 2904, Current Mhz: 2703, Mhz Limit: 2700
Memory: 4k page, system-wide physical 16234M (5319M free)
TotalPageFile size 32469M (AvailPageFile size 15609M)
current process WorkingSet (physical memory assigned to process): 60M, peak: 60M
current process commit charge ("private bytes"): 342M, peak: 342M
vm_info: Java HotSpot(TM) 64-Bit Server VM (21+35-LTS-2513) for windows-amd64 JRE (21+35-LTS-2513), built on 2023-08-09T20:25:10Z by "mach5one" with MS VC++ 17.1 (VS2022)
END.
One more question: Do you have a working counter-example with a Java agent transforming your demo class, but returning null for the others? I.e. a proof of concept that in that case, it actually works as expected? Also with source code, please.
Oh sorry, there is a typo in the command, I've fixed it on the comment above.
I have never used CDS before, so please also tell me how to run the application after creating the archive. After I changed org.aspectj.weaver.loadtime.Aj::preProcess
to always return null
where in previously it returned bytes
, I tried this:
$ java -XX:+UnlockDiagnosticVMOptions -XX:+AllowArchivingWithJavaAgent -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -javaagent:aspectjweaver-1.9.21.1-SNAPSHOT.jar -cp AppCdsDemo-1.0-SNAPSHOT.jar com.vip.demo.Demo
[0.412s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
[0.412s][warning][cds] Skipping org/aspectj/weaver/tools/TraceFactory: Unsupported location
[0.412s][warning][cds] Skipping org/aspectj/weaver/ArrayReferenceType: Unsupported location
[0.412s][warning][cds] Skipping org/aspectj/apache/bcel/classfile/LocalVariableTable: Unsupported location
...
[0.413s][warning][cds] Skipping org/aspectj/apache/bcel/classfile/LineNumberTable: Unsupported location
[0.413s][warning][cds] Skipping aj/org/objectweb/asm/ClassVisitor: Unsupported location
$ ls -l
...
-r--r--r-- 1 alexa 197609 1048576 Feb 6 14:25 demo.jsa
$ java -XX:+UnlockDiagnosticVMOptions -XX:+AllowArchivingWithJavaAgent -XX:SharedArchiveFile=demo.jsa -cp AppCdsDemo-1.0-SNAPSHOT.jar com.vip.demo.Demo -javaagent:aspectjweaver-1.9.21.1-SNAPSHOT.jar
[0.012s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
Is that what you would expect? And did I call the program correctly, again with -javaagent
, or is the result expected to contain the woven files already? Unfortunately, your program does not print anything, no aspects are involved and I do not see, if aspects have been applied correctly.
Decompiling your demo class yields:
package com.vip.demo;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;
public class Demo {
public Demo() {
}
public static void main(String[] args) {
List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
}
}
That is not much. A more meaningful reproducer would be helpful. I do not want to do all the work from scratch that you obviously have done already.
That's it, I met the same core dump error like yours and I've try another version of aspectjweaver but it was failed too.
I'm sorry I don't have the POC you expected, but you can try to modify the method public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, ProtectionDomain protectionDomain)
in Aj.java, and let it return null when the class loaded by bootstrap classloader(i.e. loader == null). Using the new building aspectweaver.jar to replace that in demo, you will find that CDS works as exepected, which means the demo.jsa file generated successfully.
Here is my source code you can build from scratch.
AppCdsDemo.zip
Hi, after generating .jsa file, it means CDS dumping works, and you can the same command to run the application again, and JVM will use .jsa file to load application classes. You can add JVM option -Xshare:on
to validate the jsa file. The complete command is in the following:
java -XX:+UnlockDiagnosticVMOptions -Xshare:on -XX:+AllowArchivingWithJavaAgent -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -javaagent:aspectjweaver-1.9.5.jar -cp AppCdsDemo-1.0-SNAPSHOT.jar com.vip.demo.Demo
And here are some information about CDS (the first one would be the quick start):
https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html#application-class-data-sharing
https://openjdk.org/jeps/310
https://openjdk.org/jeps/341
https://openjdk.org/jeps/350
https://dev.java/learn/jvm/cds-appcds
Hm, what is the point of creating those optimised files for faster start-up, if then the load-time weaver needs to do its work again? I would have expected you want to create such an archive, because when starting the application again the classes are woven already. Is there any performance gain in doing it like you described?
BTW, java agents can in principle also instrument JDK bootstrap classes, albeit with certain structural limitations. AspectJ happens not to do that, but it does not mean that it never will in the future. What would you expect to happen in such a case when running the java agent again on the CDS archive?
Sorry for the many questions, but I do not want to blindly change some code, but also understand what the whole purpose is. That has an influence on both my motivation and the prioritisation of this issue. As the saying goes, if you want to pitch an idea or make someone do something for you, you need to be able to sell it. Let us not forget, that I am doing this work for free, unless you decide to hire me or otherwise sponsor the change.
Hm, what is the point of creating those optimised files for faster start-up, if then the load-time weaver needs to do its work again? I would have expected you want to create such an archive, because when starting the application again the classes are woven already. Is there any performance gain in doing it like you described?
I think it is a very good question
I can understand your position very well. As CDS is a new feature that few people use. It will inevitably be risky to modify the originally stable code in order to support it. Appreciate for your reply again.
Best wishes!
I am working on this, because independently of CDS it makes sense to return null
, if the candidate class is not transformed. But for now, you can just
-javaagent
and only use that parameter later during runtime, when you really need it, because the archived classes are not the woven ones anyway,The latter option might be right, if you use production aspects that always should be in place when running the application. If your aspects are rather used temporarily, e.g. for debugging or tracing, and should not be in the byte code permanently, the former option might is better. A hybrid solution would be CTW and aspects with activation flag, e.g. using if()
pointcuts.
An important open question for me as someone who has never used CDS before, which I kindly request you to answer: Is there a way to dump classes transformed by a Java agent into a CDS file? If there is such a way and you are using it, please let me know and explain how to activate it, so I can test it. JDK-8213813 (Add the AllowArchivingWithJavaAgent diagnostic vm option to allow the use of the -javaagent option during CDS dumping) does not explain anything about it.
Is there a way to dump classes transformed by a Java agent into a CDS file?
OK, I think I have found out. My experimental findings, both as a note to myself and information to the audience:
When creating the archive with the agent on the command line, i.e. when using -javaagent:aspectjweaver.jar -XX:+AllowArchivingWithJavaAgent
, the agent also must be on the classpath, otherwise during the CDS dump yields lots of messages like
...
[0.877s][warning][cds] Skipping org/aspectj/weaver/IWeaveRequestor: Unsupported location
[0.877s][warning][cds] Skipping org/aspectj/apache/bcel/generic/ReturnaddressType: Unsupported location
[0.877s][warning][cds] Skipping org/aspectj/weaver/loadtime/DefaultWeavingContext: Unsupported location
...
The dump file is also much smaller than when doing the same with the agent on the classpath, in my test case 2.4M without aspectjweaver on the CP versus 6.9M with. Example:
$ rm -f *.jsa
$ java -XX:+UnlockDiagnosticVMOptions -Xshare:on -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -cp "AppCdsDemo-1.0-SNAPSHOT.jar;aspectjweaver-1.9.21.1-SNAPSHOT.jar" -XX:+AllowArchivingWithJavaAgent -javaagent:aspectjweaver-1.9.21.1-SNAPSHOT.jar com.vip.demo.Demo
[AppClassLoader@5a07e868] weaveinfo Join point 'method-execution(void com.vip.demo.Demo.main(java.lang.String[]))' in Type 'com.vip.demo.Demo' (Demo.java:12) advised by before advice from 'com.vip.demo.MyAspect' (MyAspect.java)
execution(void com.vip.demo.Demo.main(String[]))
Hello world
[0.936s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
[0.936s][warning][cds] Skipping aj/org/objectweb/asm/Type: Old class has been linked
[0.936s][warning][cds] Skipping org/aspectj/weaver/bcel/asm/StackMapAdder$AspectJClassVisitor: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/MethodWriter: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/commons/ClassRemapper: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Label: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/ClassReader: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Attribute: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Frame: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/CurrentFrame: super class aj/org/objectweb/asm/Frame is excluded
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/ClassWriter: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/ClassVisitor: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Context: Old class has been linked
[0.937s][warning][cds] Skipping org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor$MethodAndConstructorRemover: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/MethodVisitor: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/commons/MethodRemapper: super class aj/org/objectweb/asm/MethodVisitor is excluded
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/ByteVector: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/AnnotationVisitor: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/commons/AnnotationRemapper: super class aj/org/objectweb/asm/AnnotationVisitor is excluded
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/commons/FieldRemapper: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/FieldVisitor: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/FieldWriter: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Edge: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/SymbolTable$Entry: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/SymbolTable: Old class has been linked
[0.937s][warning][cds] Skipping org/aspectj/weaver/bcel/asm/StackMapAdder$AspectJConnectClassWriter: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/commons/Remapper: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Symbol: Old class has been linked
[0.937s][warning][cds] Skipping org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor$ClassNameRemapper: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/Handler: Old class has been linked
[0.937s][warning][cds] Skipping aj/org/objectweb/asm/AnnotationWriter: Old class has been linked
[0.937s][warning][cds] Skipping org/aspectj/weaver/bcel/asm/StackMapAdder$AspectJClassVisitor$AJMethodVisitor: Old class has been linked
alexa@Xander-UB MINGW64 ~/Documents/java-src/AJ_GH-277
$ ls -lh demo.jsa
-r--r--r-- 1 alexa 197609 6.9M Feb 7 09:17 demo.jsa
See? No more Skipping ... Unsupported location
warnings anymore, only a few Old class has been linked
ones, which seem to be OK.
Now let us run the application again with the identical command line:
$ java -XX:+UnlockDiagnosticVMOptions -Xshare:on -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -cp "AppCdsDemo-1.0-SNAPSHOT.jar;aspectjweaver-1.9.21.1-SNAPSHOT.jar" -XX:+AllowArchivingWithJavaAgent -javaagent:aspectjweaver-1.9.21.1-SNAPSHOT.jar com.vip.demo.Demo
[0.014s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
[AppClassLoader@2626b418] weaveinfo Join point 'method-execution(void com.vip.demo.Demo.main(java.lang.String[]))' in Type 'com.vip.demo.Demo' (Demo.java:12) advised by before advice from 'com.vip.demo.MyAspect' (MyAspect.java)
execution(void com.vip.demo.Demo.main(String[]))
Hello world
Please note above:
weaveinfo Join point
message.execution(void com.vip.demo.Demo.main(String[]))
as expected.Now, let us go one step further and remove the -javaagent
option from the command line:
$ java -XX:+UnlockDiagnosticVMOptions -Xshare:on -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=demo.jsa -cp "AppCdsDemo-1.0-SNAPSHOT.jar;aspectjweaver-1.9.21.1-SNAPSHOT.jar" -XX:+AllowArchivingWithJavaAgent com.vip.demo.Demo
[0.012s][warning][cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment
execution(void com.vip.demo.Demo.main(String[]))
Hello world
Very interesting! There is no more weaver message, but still the aspect does its job, because obviously the application class has been archived in its woven state. I.e., the effect is similar to a "poor man's compiler-time weaving". The same log output we would probably see, if we would just build using compile-time weaving and creating the CDS archive while running the woven application with just aspectjrt.jar
on the classpath. That would yield a smaller CDS archive, because the weaver classes would not be necessary, only the runtime classes. Anyway, it works with the weaver scenario, too, after I locally changed the code to return null
for unwoven classes.
Good morning kriegaex, I'm so excited that you are so interested in this problem. I was confused by Skipping ... Unsupported location
warning logs before, and you solved the problem by putting the agent jar on the classpath, amazing!
@KimmingLau, yes, CDS seems to need a bit of assistance there when creating the archive. For simple weaving, this is unnecessary, but obviously CDS disregards (or rather cannot find) agent classes, if it cannot find them on the CP additionally. According to the JDK-8213813 description and the warning "[cds] This archive was created with AllowArchivingWithJavaAgent. It should be used for testing purposes only and should not be used in a production environment", running the CDS creator with an agent is not meant to modify byte code for production, i.e. the missing support for adding agent JAR classes to the CP automatically probably cannot be termed a bug. The OpenJDK team would probably reject it, even though it would be convenient to have this automatism. However, I can imagine cases in which the classes are not wanted in the CDS archive, which is why I guess the opt-in solution is acceptable.
@KimmingLau, the problem should be fixed. Please try the latest 1.9.21.1-SNAPSHOT
.
<repositories>
<repository>
<id>ossrh-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
BTW, the snapshot also contains an improvement which lets you use LTW without --add-opens java.base/java.lang=ALL-UNNAMED
on JDk 16+. Until 1.9.21, without that option LTW does not work, unless you are lucky not to need around advice or in general anything that needs to define new classes during weaving.
Another note for the record: While creating CDS archives with -XX:ArchiveClassesAtExit=demo.jsa
and then running them works on JDKs 13-19 even without my fix, it fails on JDKs 20-21. I.e., the fact that the JDK crashes on JDKs 20-21 just because an agent returns identical class bytes for a bootstrap class is to be considered a JDK bug, not one in the AspectJ Weaver or any other java agent. The AspectJ change is simply a case of defensive programming.
I created a minimal reproducer as a Maven project with a very simple agent, not AspectJ: https://github.com/kriegaex/cds-javaagent-bug
Just run mvn clean verify
to reproduce the error on JDKs 20 or 21. On older JDKs 13-19, there is no error.
As a workaround, edit the line containing
<argument>-javaagent:${project.basedir}/../cds-javaagent-agent/target/cds-javaagent-agent-1.0-SNAPSHOT.jar=XXXreturnNull</argument>
in file cds-javaagent-test/pom.xml, removing the "XXX". Then, the agent will return null
instead of the original class bytes.
BTW, the problem does not occur with any program that runs with the agent, but specifically if the program contains ManagementFactory.getGarbageCollectorMXBeans()
.
The reproducer serves as the input for a new OpenJDK bug I just created. It has the internal review ID 9076545. As soon as the bug is accepted and visible in the public JDK bug database, I will add a link here.
Yes, because ManagementFactory.getGarbageCollectorMXBeans()
contains a combined lamba expression, which cause BoundMethodHandle$Species_LLJ
loading by bootstrap classloader. I've also reported a similar one to JDK bug database, but maybe my reproducer was not completed like yours,. they required me to provide more information. Anyway, It would be nice if they knew it was a bug.
The reproducer serves as the input for a new OpenJDK bug I just created. It has the internal review ID 9076545. As soon as the bug is accepted and visible in the public JDK bug database, I will add a link here.
We try to experience dynamic AppCDS which is a new feature from JDK19 AppCDS with LTW javaagent. But we found that jdk core classes cannot be load from the default archive, because when Aj realize a class is loaded by boostrap classloader, it will return the original bytes. This will cause the JVM to think that the class has been modified by ClassFileTransformer, and do not load the class from default CDS archive.
According to ClassFileTransformer javadoc , it refer to that return null if no transform is performed. So I think when a class isn't been weaved, Aj should return null instead of the original bytes.