From 7cf155bdac345fca67a14d7c1552d78ff4a7ee00 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Mon, 2 Apr 2018 10:15:20 -0700 Subject: [PATCH] 533038: Clear some generated class entries during class redefinition --- .../src/org/aspectj/weaver/loadtime/Aj.java | 11 ++++++- .../loadtime/ClassLoaderWeavingAdaptor.java | 31 +++++++++++++++++-- .../weaver/loadtime/ClassPreProcessor.java | 17 +++------- .../ClassPreProcessorAgentAdapter.java | 21 ++++++------- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java index 0654e4cba..e9c347acb 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java @@ -66,6 +66,7 @@ public class Aj implements ClassPreProcessor { /** * Initialization */ + @Override public void initialize() { } @@ -80,6 +81,7 @@ public class Aj implements ClassPreProcessor { * @param loader * @return woven bytes */ + @Override public byte[] preProcess(String className, byte[] bytes, ClassLoader loader, ProtectionDomain protectionDomain) { // TODO AV needs to doc that if (loader == null || className == null || loader.getClass().getName().equals(deleLoader)) { @@ -171,6 +173,7 @@ public class Aj implements ClassPreProcessor { return instance; } + @Override public boolean equals(Object obj) { if (!(obj instanceof AdaptorKey)) { return false; @@ -181,6 +184,7 @@ public class Aj implements ClassPreProcessor { && loaderClass.equals(other.loaderClass); } + @Override public int hashCode() { return hashValue; } @@ -301,7 +305,7 @@ public class Aj implements ClassPreProcessor { if (loader.equals(myClassLoader)){ adaptor = myClassLoaderAdaptor; } else { - adaptor = (ExplicitlyInitializedClassLoaderWeavingAdaptor) weavingAdaptors.get(adaptorKey); + adaptor = weavingAdaptors.get(adaptorKey); } if (adaptor == null) { // create it and put it back in the weavingAdaptors map but avoid any kind of instantiation @@ -370,4 +374,9 @@ public class Aj implements ClassPreProcessor { ((ClassLoaderWeavingAdaptor) WeaverContainer.getWeaver(loader, weavingContext)).flushGeneratedClasses(); } + @Override + public void prepareForRedefinition(ClassLoader loader, String className) { + ((ClassLoaderWeavingAdaptor) WeaverContainer.getWeaver(loader, weavingContext)).flushGeneratedClassesFor(className); + } + } \ No newline at end of file diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java index 24c5ba1bd..6fa259d03 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java @@ -12,8 +12,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.security.ProtectionDomain; @@ -24,6 +22,8 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; @@ -114,6 +114,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { * * @deprecated */ + @Deprecated public ClassLoaderWeavingAdaptor(final ClassLoader deprecatedLoader, final IWeavingContext deprecatedContext) { super(); if (trace.isTraceEnabled()) { @@ -135,6 +136,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { * Callback when we need to define a Closure in the JVM * */ + @Override public void acceptClass (String name, byte[] originalBytes, byte[] wovenBytes) { try { if (shouldDump(name.replace('/', '.'), false)) { @@ -1006,6 +1008,30 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { generatedClasses = new HashMap(); } + /** + * Remove generated classes based on the supplied className. This will + * remove any entries related to this name - so the class itself plus + * and inner classes. + * @param className a slashed classname (e.g. com/foo/Bar) + */ + public void flushGeneratedClassesFor(String className) { + try { + String dottedClassName = className.replace('/', '.'); + String dottedClassNameDollar = dottedClassName+"$"; // to pickup inner classes + Iterator> iter = generatedClasses.entrySet().iterator(); + while (iter.hasNext()) { + Entry next = iter.next(); + String existingGeneratedName = next.getKey(); + if (existingGeneratedName.equals(dottedClassName) || + existingGeneratedName.startsWith(dottedClassNameDollar)) { + iter.remove(); + } + } + } catch (Throwable t) { + new RuntimeException("Unexpected problem tidying up generated classes for "+className,t).printStackTrace(); + } + } + private Unsafe unsafe; private Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { @@ -1061,4 +1087,5 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { trace.exit("defineClass", clazz); } } + } \ No newline at end of file diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java index 12e620215..97348b281 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassPreProcessor.java @@ -1,13 +1,10 @@ /******************************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005,2018 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Vasseur initial implementation *******************************************************************************/ package org.aspectj.weaver.loadtime; @@ -18,6 +15,7 @@ import java.security.ProtectionDomain; * further use on Java 1.3 / 1.4 * * @author Alexandre Vasseur + * @author Andy Clement */ public interface ClassPreProcessor { @@ -26,14 +24,7 @@ public interface ClassPreProcessor { */ void initialize(); - /** - * Weave - * - * @param className - * @param bytes - * @param classLoader - * @param a protection domain that may be used for defining extraneous classes generated as part of modifying the one passed in - * @return - */ byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader, ProtectionDomain protectionDomain); + + void prepareForRedefinition(ClassLoader loader, String className); } \ No newline at end of file diff --git a/loadtime5/java5-src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java b/loadtime5/java5-src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java index ae5a999c9..a3201816a 100644 --- a/loadtime5/java5-src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java +++ b/loadtime5/java5-src/org/aspectj/weaver/loadtime/ClassPreProcessorAgentAdapter.java @@ -1,13 +1,10 @@ /******************************************************************************* - * Copyright (c) 2005 Contributors. + * Copyright (c) 2005,2018 Contributors. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Vasseur initial implementation *******************************************************************************/ package org.aspectj.weaver.loadtime; @@ -18,19 +15,17 @@ import java.security.ProtectionDomain; /** * Java 1.5 adapter for class pre processor * - * @author Alexandre Vasseur + * @author Alexandre Vasseur + * @author Andy Clement */ public class ClassPreProcessorAgentAdapter implements ClassFileTransformer { - /** - * Concrete preprocessor. - */ - private static ClassPreProcessor s_preProcessor; + private static ClassPreProcessor classPreProcessor; static { try { - s_preProcessor = new Aj(); - s_preProcessor.initialize(); + classPreProcessor = new Aj(); + classPreProcessor.initialize(); } catch (Exception e) { throw new ExceptionInInitializerError("could not initialize JSR163 preprocessor due to: " + e.toString()); } @@ -46,11 +41,13 @@ public class ClassPreProcessorAgentAdapter implements ClassFileTransformer { * @param bytes the incoming bytes (before weaving) * @return the woven bytes */ + @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { if (classBeingRedefined != null) { System.err.println("INFO: (Enh120375): AspectJ attempting reweave of '" + className + "'"); + classPreProcessor.prepareForRedefinition(loader, className); } - return s_preProcessor.preProcess(className, bytes, loader, protectionDomain); + return classPreProcessor.preProcess(className, bytes, loader, protectionDomain); } } -- 2.39.5