diff --git a/loadtime/src/main/java/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/main/java/org/aspectj/weaver/loadtime/Aj.java index 3c6ab2952c..6044ea3074 100644 --- a/loadtime/src/main/java/org/aspectj/weaver/loadtime/Aj.java +++ b/loadtime/src/main/java/org/aspectj/weaver/loadtime/Aj.java @@ -75,18 +75,18 @@ public void initialize() { private final static String deleLoader2 = "jdk.internal.reflect.DelegatingClassLoader"; // On JDK11+ @Override - public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, ProtectionDomain protectionDomain) { + public byte[] preProcess(String className, final byte[] bytes, ClassLoader loader, ProtectionDomain protectionDomain) { if (loader == null || className == null || loader.getClass().getName().equals(deleLoader) || loader.getClass().getName().equals(deleLoader2)) { // skip boot loader, null classes (hibernate), or those from a reflection loader - return bytes; + return null; } if (loadersToSkip != null) { // Check whether to reject it if (loadersToSkip.contains(loader.getClass().getName())) { // System.out.println("debug: no weaver created for loader '"+loader.getClass().getName()+"'"); - return bytes; + return null; } } @@ -109,7 +109,7 @@ public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, Pro if (weavingAdaptor == null) { if (trace.isTraceEnabled()) trace.exit("preProcess"); - return bytes; + return null; } try { weavingAdaptor.setActiveProtectionDomain(protectionDomain); @@ -134,7 +134,7 @@ public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, Pro // would make sense at least in test f.e. see TestHelper.handleMessage() if (trace.isTraceEnabled()) trace.exit("preProcess", th); - return bytes; + return null; } finally { CompilationAndWeavingContext.resetForThread(); } diff --git a/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessor.java b/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessor.java index ab305cb32e..af9bf16e9e 100644 --- a/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessor.java +++ b/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessor.java @@ -24,7 +24,7 @@ public interface ClassPreProcessor { */ void initialize(); - byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader, ProtectionDomain protectionDomain); + byte[] preProcess(String className, final byte[] bytes, ClassLoader classLoader, ProtectionDomain protectionDomain); void prepareForRedefinition(ClassLoader loader, String className); } diff --git a/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java b/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java index 2a778585e2..45de1f14e0 100644 --- a/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java +++ b/loadtime/src/main/java/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java @@ -43,7 +43,7 @@ public class ClassPreProcessorAgentAdapter implements ClassFileTransformer { */ @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, - byte[] bytes) throws IllegalClassFormatException { + final byte[] bytes) throws IllegalClassFormatException { if (classBeingRedefined != null) { System.err.println("INFO: (Enh120375): AspectJ attempting reweave of '" + className + "'"); classPreProcessor.prepareForRedefinition(loader, className); diff --git a/weaver/src/main/java/org/aspectj/weaver/tools/WeavingAdaptor.java b/weaver/src/main/java/org/aspectj/weaver/tools/WeavingAdaptor.java index 3ce3eef6ea..771c8d67bf 100644 --- a/weaver/src/main/java/org/aspectj/weaver/tools/WeavingAdaptor.java +++ b/weaver/src/main/java/org/aspectj/weaver/tools/WeavingAdaptor.java @@ -324,20 +324,21 @@ protected Boolean initialValue() { * @return the woven bytes * @exception IOException weave failed */ - public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException { + public byte[] weaveClass(String name, final byte[] bytes, boolean mustWeave) throws IOException { if (trace == null) { // Pr231945: we are likely to be under tomcat and ENABLE_CLEAR_REFERENCES hasn't been set System.err .println("AspectJ Weaver cannot continue to weave, static state has been cleared. Are you under Tomcat? In order to weave '" + name + "' during shutdown, 'org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false' must be set (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=231945)."); - return bytes; + return null; } if (weaverRunning.get()) { // System.out.println("AJC: avoiding re-entrant call to transform " + name); - return bytes; + return null; } try { + byte[] newBytes = null; weaverRunning.set(true); if (trace.isTraceEnabled()) { trace.enter("weaveClass", this, new Object[] { name, bytes }); @@ -347,7 +348,7 @@ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IO if (trace.isTraceEnabled()) { trace.exit("weaveClass", false); } - return bytes; + return null; } boolean debugOn = !messageHandler.isIgnoring(Message.DEBUG); @@ -360,15 +361,14 @@ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IO // Determine if we have the weaved class cached CachedClassReference cacheKey = null; - final byte[] original_bytes = bytes; if (cache != null && !mustWeave) { - cacheKey = cache.createCacheKey(name, original_bytes); - CachedClassEntry entry = cache.get(cacheKey, original_bytes); + cacheKey = cache.createCacheKey(name, bytes); + CachedClassEntry entry = cache.get(cacheKey, bytes); if (entry != null) { // If the entry has been explicitly ignored // return the original bytes if (entry.isIgnored()) { - return bytes; + return null; } return entry.getBytes(); } @@ -382,7 +382,12 @@ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IO if (debugOn) { debug("weaving '" + name + "'"); } - bytes = getWovenBytes(name, bytes); + newBytes = getWovenBytes(name, bytes); + // TODO: Is this OK performance-wise? + if (Arrays.equals(bytes, newBytes)) { + // null means unchanged in java.lang.instrument.ClassFileTransformer::transform + newBytes = null; + } // temporarily out - searching for @Aspect annotated types is a slow thing to do - we should // expect the user to name them if they want them woven - just like code style // } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) { @@ -405,10 +410,10 @@ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IO if (cacheKey != null) { // If no transform has been applied, mark the class // as ignored. - if (Arrays.equals(original_bytes, bytes)) { - cache.ignore(cacheKey, original_bytes); + if (newBytes == null) { + cache.ignore(cacheKey, bytes); } else { - cache.put(cacheKey, original_bytes, bytes); + cache.put(cacheKey, bytes, newBytes); } } } else if (debugOn) { @@ -422,9 +427,9 @@ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IO } if (trace.isTraceEnabled()) { - trace.exit("weaveClass", bytes); + trace.exit("weaveClass", newBytes); } - return bytes; + return newBytes; } finally { weaverRunning.remove(); } diff --git a/weaver/src/main/java/org/aspectj/weaver/tools/cache/SimpleCache.java b/weaver/src/main/java/org/aspectj/weaver/tools/cache/SimpleCache.java index 4bbf8d9c9b..0cf759e73f 100644 --- a/weaver/src/main/java/org/aspectj/weaver/tools/cache/SimpleCache.java +++ b/weaver/src/main/java/org/aspectj/weaver/tools/cache/SimpleCache.java @@ -72,6 +72,7 @@ public byte[] getAndInitialize(String classname, byte[] bytes, byte[] res = get(classname, bytes); if (Arrays.equals(SAME_BYTES, res)) { + // TODO: Should we return null (means "not transformed") in this case? return bytes; } else { if (res != null) {