/*******************************************************************************
- * Copyright (c) 2005 Contributors.
+ * Copyright (c) 2005, 2017 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
- * David Knibb weaving context enhancments
- * John Kew (vmware) caching hook
*******************************************************************************/
package org.aspectj.weaver.loadtime;
-import java.io.*;
+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.CodeSource;
-import java.security.Permissions;
import java.security.ProtectionDomain;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.Constants;
import org.aspectj.weaver.ltw.LTWWorld;
import org.aspectj.weaver.patterns.PatternParser;
import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.tools.*;
+import org.aspectj.weaver.tools.GeneratedClassHandler;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
+import org.aspectj.weaver.tools.WeavingAdaptor;
import org.aspectj.weaver.tools.cache.WeavedClassCache;
import sun.misc.Unsafe;
* @author Alexandre Vasseur
* @author Andy Clement
* @author Abraham Nevado
+ * @author David Knibb
+ * @author John Kew
*/
public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
private boolean initialized;
- private List<TypePattern> m_dumpTypePattern = new ArrayList<TypePattern>();
- private boolean m_dumpBefore = false;
+ private List<TypePattern> dumpTypePattern = new ArrayList<TypePattern>();
+ private boolean dumpBefore = false;
private boolean dumpDirPerClassloader = false;
private boolean hasExcludes = false;
private boolean hasIncludes = false;
private List<TypePattern> includeTypePattern = new ArrayList<TypePattern>();
- private List<String> m_includeStartsWith = new ArrayList<String>();
+ private List<String> includeStartsWith = new ArrayList<String>();
private List<String> includeExactName = new ArrayList<String>();
private boolean includeStar = false;
- private List<TypePattern> m_aspectExcludeTypePattern = new ArrayList<TypePattern>();
- private List<String> m_aspectExcludeStartsWith = new ArrayList<String>();
- private List<TypePattern> m_aspectIncludeTypePattern = new ArrayList<TypePattern>();
- private List<String> m_aspectIncludeStartsWith = new ArrayList<String>();
+ private List<TypePattern> aspectExcludeTypePattern = new ArrayList<TypePattern>();
+ private List<String> aspectExcludeStartsWith = new ArrayList<String>();
+ private List<TypePattern> aspectIncludeTypePattern = new ArrayList<TypePattern>();
+ private List<String> aspectIncludeStartsWith = new ArrayList<String>();
private StringBuffer namespace;
private IWeavingContext weavingContext;
this.generatedClassHandler = new SimpleGeneratedClassHandler(classLoader);
- List definitions = weavingContext.getDefinitions(classLoader, this);
+ List<Definition> definitions = weavingContext.getDefinitions(classLoader, this);
if (definitions.isEmpty()) {
disable(); // TODO maw Needed to ensure messages are flushed
if (trace.isTraceEnabled()) {
String file = System.getProperty("aj5.def", null);
if (file != null) {
info("using (-Daj5.def) " + file);
- definitions.add(DocumentParser.parse((new File(file)).toURL()));
+ definitions.add(DocumentParser.parse((new File(file)).toURI().toURL()));
}
}
if (!configFile.exists()) {
warn("configuration does not exist: " + nextDefinition);
} else {
- definitions.add(DocumentParser.parse(configFile.toURL()));
+ definitions.add(DocumentParser.parse(configFile.toURI().toURL()));
}
} catch (MalformedURLException mue) {
error("malformed definition url: " + nextDefinition);
for (Definition definition : definitions) {
for (String exclude : definition.getAspectExcludePatterns()) {
TypePattern excludePattern = new PatternParser(exclude).parseTypePattern();
- m_aspectExcludeTypePattern.add(excludePattern);
+ aspectExcludeTypePattern.add(excludePattern);
fastMatchInfo = looksLikeStartsWith(exclude);
if (fastMatchInfo != null) {
- m_aspectExcludeStartsWith.add(fastMatchInfo);
+ aspectExcludeStartsWith.add(fastMatchInfo);
}
}
}
for (Definition definition : definitions) {
for (String include : definition.getAspectIncludePatterns()) {
TypePattern includePattern = new PatternParser(include).parseTypePattern();
- m_aspectIncludeTypePattern.add(includePattern);
+ aspectIncludeTypePattern.add(includePattern);
fastMatchInfo = looksLikeStartsWith(include);
if (fastMatchInfo != null) {
- m_aspectIncludeStartsWith.add(fastMatchInfo);
+ aspectIncludeStartsWith.add(fastMatchInfo);
}
}
}
String include = iterator1.next();
fastMatchInfo = looksLikeStartsWith(include);
if (fastMatchInfo != null) {
- m_includeStartsWith.add(fastMatchInfo);
+ includeStartsWith.add(fastMatchInfo);
} else if (include.equals("*")) {
includeStar = true;
} else if ((fastMatchInfo = looksLikeExactName(include)) != null) {
for (Iterator<String> iterator1 = definition.getDumpPatterns().iterator(); iterator1.hasNext();) {
String dump = iterator1.next();
TypePattern pattern = new PatternParser(dump).parseTypePattern();
- m_dumpTypePattern.add(pattern);
+ dumpTypePattern.add(pattern);
}
if (definition.shouldDumpBefore()) {
- m_dumpBefore = true;
+ dumpBefore = true;
}
if (definition.createDumpDirPerClassloader()) {
dumpDirPerClassloader = true;
}
}
boolean fastAccept = false;// defaults to false if no fast include
- for (int i = 0; i < m_includeStartsWith.size(); i++) {
+ for (int i = 0; i < includeStartsWith.size(); i++) {
didSomeIncludeMatching = true;
- fastAccept = fastClassName.startsWith(m_includeStartsWith.get(i));
+ fastAccept = fastClassName.startsWith(includeStartsWith.get(i));
if (fastAccept) {
return true;
}
}
}
}
- for (int i = 0; i < m_includeStartsWith.size(); i++) {
+ for (int i = 0; i < includeStartsWith.size(); i++) {
didSomeIncludeMatching = true;
- boolean fastaccept = fastClassName.startsWith(m_includeStartsWith.get(i));
+ boolean fastaccept = fastClassName.startsWith(includeStartsWith.get(i));
if (fastaccept) {
return true;
}
// this can be nice but very dangerous as well to change that
private boolean acceptAspect(String aspectClassName) {
// avoid ResolvedType if not needed
- if (m_aspectExcludeTypePattern.isEmpty() && m_aspectIncludeTypePattern.isEmpty()) {
+ if (aspectExcludeTypePattern.isEmpty() && aspectIncludeTypePattern.isEmpty()) {
return true;
}
// still try to avoid ResolvedType if we have simple patterns
// EXCLUDE: if one match then reject
String fastClassName = aspectClassName.replace('/', '.').replace('.', '$');
- for (int i = 0; i < m_aspectExcludeStartsWith.size(); i++) {
- if (fastClassName.startsWith(m_aspectExcludeStartsWith.get(i))) {
+ for (int i = 0; i < aspectExcludeStartsWith.size(); i++) {
+ if (fastClassName.startsWith(aspectExcludeStartsWith.get(i))) {
return false;
}
}
// INCLUDE: if one match then accept
- for (int i = 0; i < m_aspectIncludeStartsWith.size(); i++) {
- if (fastClassName.startsWith(m_aspectIncludeStartsWith.get(i))) {
+ for (int i = 0; i < aspectIncludeStartsWith.size(); i++) {
+ if (fastClassName.startsWith(aspectIncludeStartsWith.get(i))) {
return true;
}
}
// needs further analysis
ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(aspectClassName), true);
// exclude are "AND"ed
- for (Iterator iterator = m_aspectExcludeTypePattern.iterator(); iterator.hasNext();) {
- TypePattern typePattern = (TypePattern) iterator.next();
+ for (TypePattern typePattern: aspectExcludeTypePattern) {
if (typePattern.matchesStatically(classInfo)) {
// exclude match - skip
return false;
}
// include are "OR"ed
boolean accept = true;// defaults to true if no include
- for (Iterator iterator = m_aspectIncludeTypePattern.iterator(); iterator.hasNext();) {
- TypePattern typePattern = (TypePattern) iterator.next();
+ for (TypePattern typePattern: aspectIncludeTypePattern) {
accept = typePattern.matchesStatically(classInfo);
if (accept) {
break;
@Override
protected boolean shouldDump(String className, boolean before) {
// Don't dump before weaving unless asked to
- if (before && !m_dumpBefore) {
+ if (before && !dumpBefore) {
return false;
}
// avoid ResolvedType if not needed
- if (m_dumpTypePattern.isEmpty()) {
+ if (dumpTypePattern.isEmpty()) {
return false;
}
// TODO AV - optimize for className.startWith only
ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(className), true);
// dump
- for (Iterator<TypePattern> iterator = m_dumpTypePattern.iterator(); iterator.hasNext();) {
+ for (Iterator<TypePattern> iterator = dumpTypePattern.iterator(); iterator.hasNext();) {
TypePattern typePattern = iterator.next();
if (typePattern.matchesStatically(classInfo)) {
// dump match
*/
public void flushGeneratedClasses() {
// System.err.println("? ClassLoaderWeavingAdaptor.flushGeneratedClasses() generatedClasses=" + generatedClasses);
- generatedClasses = new HashMap();
+ generatedClasses = new HashMap<>();
}
- private Method defineClassMethod;
- private Method defineClassWithProtectionDomainMethod;
private Unsafe unsafe;
private Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
}
Object clazz = null;
debug("generating class '" + name + "'");
-
try {
-// loader.getClass().getProtectionDomain()
-// ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("",""),(Certificate[])null), new Permissions());
clazz = getUnsafe().defineClass(name, bytes, 0, bytes.length, loader, null);
-// if (defineClassMethod == null) {
-// defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] { String.class,
-// bytes.getClass(), int.class, int.class });
-// }
-// defineClassMethod.setAccessible(true);
-// clazz = defineClassMethod.invoke(loader, new Object[] { name, bytes, new Integer(0), new Integer(bytes.length) });
-// } catch (InvocationTargetException e) {
-// if (e.getTargetException() instanceof LinkageError) {
-// warn("define generated class failed", e.getTargetException());
-// // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
-// // TODO maw I don't think this is OK and
-// } else {
-// warn("define generated class failed", e.getTargetException());
-// }
+ } catch (LinkageError le) {
+ // likely thrown due to defining something that already exists?
+ // Old comments from before moving to Unsafe.defineClass():
+ // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
+ // TODO maw I don't think this is OK and
} catch (Exception e) {
+ e.printStackTrace(System.err);
warn("define generated class failed", e);
}
Object clazz = null;
debug("generating class '" + name + "'");
try {
-// // System.out.println(">> Defining with protection domain " + name + " pd=" + protectionDomain);
-// if (defineClassWithProtectionDomainMethod == null) {
-// defineClassWithProtectionDomainMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[] {
-// String.class, bytes.getClass(), int.class, int.class, ProtectionDomain.class });
-// }
-// defineClassWithProtectionDomainMethod.setAccessible(true);
-// clazz = defineClassWithProtectionDomainMethod.invoke(loader, new Object[] { name, bytes, Integer.valueOf(0),
-// new Integer(bytes.length), protectionDomain });
getUnsafe().defineClass(name, bytes, 0, bytes.length, loader, protectionDomain);
-// } catch (InvocationTargetException e) {
-// if (e.getTargetException() instanceof LinkageError) {
-// warn("define generated class failed", e.getTargetException());
-// // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
-// // TODO maw I don't think this is OK and
-// } else {
-// warn("define generated class failed", e.getTargetException());
-// }
+ } catch (LinkageError le) {
+ // likely thrown due to defining something that already exists?
+ // Old comments from before moving to Unsafe.defineClass():
+ // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
+ // TODO maw I don't think this is OK and
} catch (Exception e) {
warn("define generated class failed", e);
}