Skip to content

NPE when using LTW cache #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KimmingLau opened this issue Feb 27, 2024 · 9 comments · Fixed by #289
Closed

NPE when using LTW cache #285

KimmingLau opened this issue Feb 27, 2024 · 9 comments · Fixed by #289
Assignees
Labels
bug Something isn't working
Milestone

Comments

@KimmingLau
Copy link
Contributor

ltw-npe-reproducer.zip
step to reproduce:

  1. unzip ltw-npe-reproducer.zip
  2. mvn clean package
  3. cd target; unzip ltw-npe-reproducer-1.0-SNAPSHOT-zip.zip
  4. java -javaagent:aspectjweaver-1.9.21.1.jar -Daj.weaving.cache.enabled=true -Daj.weaving.cache.impl=shared -cp ltw-npe-reproducer-1.0-SNAPSHOT.jar com.foo.bar.Demo
@KimmingLau
Copy link
Contributor Author

KimmingLau commented Feb 27, 2024

java.lang.NullPointerException: Cannot read the array length because "b" is null at java.base/java.io.FileOutputStream.write(FileOutputStream.java:346) at org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap.writeToPath(SimpleCache.java:256) at org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap.put(SimpleCache.java:194) at java.base/java.util.Collections$SynchronizedMap.put(Collections.java:2896) at org.aspectj.weaver.tools.cache.SimpleCache.put(SimpleCache.java:104) at org.aspectj.weaver.loadtime.Aj.preProcess(Aj.java:126) at org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:51) at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244) at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188) at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:610) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027) at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:534) at java.base/java.lang.Class.forName(Class.java:513) at java.base/sun.launcher.LauncherHelper.loadMainClass(LauncherHelper.java:797) at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:692)

@KimmingLau
Copy link
Contributor Author

Due to code changes in #280

@kriegaex
Copy link
Contributor

Thanks. I am taking this seriously, but will be very busy with work and intercontinental travel for a few days. So please, forgive me if I get to this later than I actually want to. (I hate regression bugs!)

KimmingLau added a commit to KimmingLau/aspectj that referenced this issue Feb 28, 2024
1.write SAME_BYTES to cacheMap when wovenbytes is null
2.fix TODO in SimpleCache#getAndInitialize, use Optional to help indicating case in which Hit cache but need to return null

Signed-off-by: KimmingLau <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
This reproduces regression bug #285 when running
org.aspectj.systemtest.ajc171.NewFeatures::testSharedCache.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
This is an additional reproducer for regression bug #285.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
Also update lib/aspectj/aspectjweaver.jar to fix integration tests.

Fixes #285.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
While fixing #285, I noticed that *.ajc171.NewFeatures was never
executed as part of the AspectJ test suite, because since 2012 falsely
*.ajc1610.NewFeatures was imported and executed a second time instead.
In addition to an outdated AspetJ weaver library in 'lib', this was one
more factor why the regression bug was never spotted.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
This is an additional reproducer for regression bug #285.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
Also update lib/aspectj/aspectjweaver.jar to fix integration tests.

Fixes #285.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
Also update lib/aspectj/aspectjweaver.jar to fix integration tests.

Fixes #285.

Co-authored-by: Kimming Lau <[email protected]>
Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
This reproduces regression bug #285 when running
org.aspectj.systemtest.ajc171.NewFeatures::testSharedCache.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
While fixing #285, I noticed that *.ajc171.NewFeatures was never
executed as part of the AspectJ test suite, because since 2012 falsely
*.ajc1610.NewFeatures was imported and executed a second time instead.
In addition to an outdated AspetJ weaver library in 'lib', this was one
more factor why the regression bug was never spotted.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
This is an additional reproducer for regression bug #285.

Signed-off-by: Alexander Kriegisch <[email protected]>
kriegaex added a commit that referenced this issue Mar 2, 2024
Also update lib/aspectj/aspectjweaver.jar to fix integration tests.

Fixes #285.

Co-authored-by: Kimming Lau <[email protected]>
Signed-off-by: Alexander Kriegisch <[email protected]>
@kriegaex
Copy link
Contributor

kriegaex commented Mar 2, 2024

@KimmingLau Can you please test 1.9.22-SNAPSHOT from this repository? Thank you.

<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>

@KimmingLau
Copy link
Contributor Author

Apreciate to do that, but actually I am confused that if SimpleCache#getAndInitialize() return null, how to distinguish between no cache and cache which indicate that the class no need to be woven? That's why I used Optional to express three possible returns from getAndInitialize() method.

@kriegaex
Copy link
Contributor

kriegaex commented Mar 4, 2024

You got a point there. My focus was to fix your problem, not to add an additional optimisation, given the fact that the problem solved was introduced in an optimisation step doing more than solving the problem you raised before about CDS archives. So, I was more conservative here.

Your PR did not communicate its intent by additional tests for these cases, and my simple fix also did not break any existing tests. So I thought, it was enough. Your point seems to be that the weaver is triggered, even though maybe there are unwoven classes in the cache already, testing again if they need to be woven. Am I understanding you correctly here? Please explain the rationale in more detail. Thank you.

@KimmingLau
Copy link
Contributor Author

KimmingLau commented Mar 4, 2024

Your point seems to be that the weaver is triggered, even though maybe there are unwoven classes in the cache already, testing again if they need to be woven

Yes, that's my point. In the old version getAndInitialize() would return the original bytes for class that no need to be woven (which cache bytes are SAME_BYTES), this means the weaving process would not be triggered again. But now it return null in that case, means weaver would be triggered.

I feel like the behavior here seems to be different from before. Forgive me for not being very good at English and not being able to express what I mean very well.

kriegaex added a commit that referenced this issue Mar 4, 2024
1. Write SAME_BYTES to cacheMap when woven bytes are null
2. Fix TODO in SimpleCache::getAndInitialize, using Optional to help
   indicate cache hit for unwoven class
3. Improve test coverage (cache miss, cache hit for unwoven class)

Relates to #285.

Co-authored-by: Alexander Kriegisch <[email protected]>
Signed-off-by: KimmingLau <[email protected]>
Signed-off-by: Alexander Kriegisch <[email protected]>
@kriegaex
Copy link
Contributor

kriegaex commented Mar 4, 2024

I cherry-picked your commits, squashed them into one and modified them a little bit, also adding more tests. See 1f1d429. Thanks for your valuable contribution and reviewing my own commit.

@KimmingLau
Copy link
Contributor Author

Thanks for the review and approval, especially the additional testing code. It's my honor to contribute to such an excellent project.

@kriegaex kriegaex self-assigned this Mar 13, 2024
@kriegaex kriegaex added the bug Something isn't working label Mar 13, 2024
@kriegaex kriegaex added this to the 1.9.21.2 milestone Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants