You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ClassLoaderWeavingAdaptor.java 40KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. /*******************************************************************************
  2. * Copyright (c) 2005, 2017 Contributors.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *******************************************************************************/
  9. package org.aspectj.weaver.loadtime;
  10. import java.io.File;
  11. import java.io.IOException;
  12. import java.io.InputStream;
  13. import java.lang.reflect.Field;
  14. import java.lang.reflect.Method;
  15. import java.net.MalformedURLException;
  16. import java.net.URL;
  17. import java.security.ProtectionDomain;
  18. import java.util.ArrayList;
  19. import java.util.Enumeration;
  20. import java.util.HashMap;
  21. import java.util.HashSet;
  22. import java.util.Iterator;
  23. import java.util.LinkedList;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Map.Entry;
  27. import java.util.Properties;
  28. import java.util.Set;
  29. import java.util.StringTokenizer;
  30. import org.aspectj.bridge.AbortException;
  31. import org.aspectj.bridge.Constants;
  32. import org.aspectj.bridge.MessageUtil;
  33. import org.aspectj.util.LangUtil;
  34. import org.aspectj.weaver.IUnwovenClassFile;
  35. import org.aspectj.weaver.Lint;
  36. import org.aspectj.weaver.Lint.Kind;
  37. import org.aspectj.weaver.ResolvedType;
  38. import org.aspectj.weaver.UnresolvedType;
  39. import org.aspectj.weaver.World;
  40. import org.aspectj.weaver.bcel.BcelWeakClassLoaderReference;
  41. import org.aspectj.weaver.bcel.BcelWeaver;
  42. import org.aspectj.weaver.bcel.BcelWorld;
  43. import org.aspectj.weaver.bcel.Utility;
  44. import org.aspectj.weaver.loadtime.definition.Definition;
  45. import org.aspectj.weaver.loadtime.definition.DocumentParser;
  46. import org.aspectj.weaver.ltw.LTWWorld;
  47. import org.aspectj.weaver.patterns.PatternParser;
  48. import org.aspectj.weaver.patterns.TypePattern;
  49. import org.aspectj.weaver.tools.GeneratedClassHandler;
  50. import org.aspectj.weaver.tools.Trace;
  51. import org.aspectj.weaver.tools.TraceFactory;
  52. import org.aspectj.weaver.tools.WeavingAdaptor;
  53. import org.aspectj.weaver.tools.cache.WeavedClassCache;
  54. import sun.misc.Unsafe;
  55. /**
  56. * @author Alexandre Vasseur
  57. * @author Andy Clement
  58. * @author Abraham Nevado
  59. * @author David Knibb
  60. * @author John Kew
  61. */
  62. public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
  63. private final static String AOP_XML = Constants.AOP_USER_XML + ";" + Constants.AOP_AJC_XML + ";" + Constants.AOP_OSGI_XML;
  64. private boolean initialized;
  65. private List<TypePattern> dumpTypePattern = new ArrayList<TypePattern>();
  66. private boolean dumpBefore = false;
  67. private boolean dumpDirPerClassloader = false;
  68. private boolean hasExcludes = false;
  69. private List<TypePattern> excludeTypePattern = new ArrayList<TypePattern>(); // anything
  70. private List<String> excludeStartsWith = new ArrayList<String>(); // com.foo..*
  71. private List<String> excludeStarDotDotStar = new ArrayList<String>(); // *..*CGLIB*
  72. private List<String> excludeExactName = new ArrayList<String>(); // com.foo.Bar
  73. private List<String> excludeEndsWith = new ArrayList<String>(); // com.foo.Bar
  74. private List<String[]> excludeSpecial = new ArrayList<String[]>();
  75. private boolean hasIncludes = false;
  76. private List<TypePattern> includeTypePattern = new ArrayList<TypePattern>();
  77. private List<String> includeStartsWith = new ArrayList<String>();
  78. private List<String> includeExactName = new ArrayList<String>();
  79. private boolean includeStar = false;
  80. private List<TypePattern> aspectExcludeTypePattern = new ArrayList<TypePattern>();
  81. private List<String> aspectExcludeStartsWith = new ArrayList<String>();
  82. private List<TypePattern> aspectIncludeTypePattern = new ArrayList<TypePattern>();
  83. private List<String> aspectIncludeStartsWith = new ArrayList<String>();
  84. private StringBuffer namespace;
  85. private IWeavingContext weavingContext;
  86. private List<ConcreteAspectCodeGen> concreteAspects = new ArrayList<ConcreteAspectCodeGen>();
  87. private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassLoaderWeavingAdaptor.class);
  88. public ClassLoaderWeavingAdaptor() {
  89. super();
  90. if (trace.isTraceEnabled()) {
  91. trace.enter("<init>", this);
  92. }
  93. if (trace.isTraceEnabled()) {
  94. trace.exit("<init>");
  95. }
  96. }
  97. /**
  98. * We don't need a reference to the class loader and using it during construction can cause problems with recursion. It also
  99. * makes sense to supply the weaving context during initialization to.
  100. *
  101. * @deprecated
  102. */
  103. @Deprecated
  104. public ClassLoaderWeavingAdaptor(final ClassLoader deprecatedLoader, final IWeavingContext deprecatedContext) {
  105. super();
  106. if (trace.isTraceEnabled()) {
  107. trace.enter("<init>", this, new Object[] { deprecatedLoader, deprecatedContext });
  108. }
  109. if (trace.isTraceEnabled()) {
  110. trace.exit("<init>");
  111. }
  112. }
  113. class SimpleGeneratedClassHandler implements GeneratedClassHandler {
  114. private BcelWeakClassLoaderReference loaderRef;
  115. SimpleGeneratedClassHandler(ClassLoader loader) {
  116. loaderRef = new BcelWeakClassLoaderReference(loader);
  117. }
  118. /**
  119. * Callback when we need to define a Closure in the JVM
  120. *
  121. */
  122. @Override
  123. public void acceptClass (String name, byte[] originalBytes, byte[] wovenBytes) {
  124. try {
  125. if (shouldDump(name.replace('/', '.'), false)) {
  126. dump(name, wovenBytes, false);
  127. }
  128. } catch (Throwable throwable) {
  129. throwable.printStackTrace();
  130. }
  131. if (activeProtectionDomain != null) {
  132. defineClass(loaderRef.getClassLoader(), name, wovenBytes, activeProtectionDomain);
  133. } else {
  134. defineClass(loaderRef.getClassLoader(), name, wovenBytes); // could be done lazily using the hook
  135. }
  136. }
  137. }
  138. public void initialize(final ClassLoader classLoader, IWeavingContext context) {
  139. if (initialized) {
  140. return;
  141. }
  142. boolean success = true;
  143. this.weavingContext = context;
  144. if (weavingContext == null) {
  145. weavingContext = new DefaultWeavingContext(classLoader);
  146. }
  147. createMessageHandler();
  148. this.generatedClassHandler = new SimpleGeneratedClassHandler(classLoader);
  149. List<Definition> definitions = weavingContext.getDefinitions(classLoader, this);
  150. if (definitions.isEmpty()) {
  151. disable(); // TODO maw Needed to ensure messages are flushed
  152. if (trace.isTraceEnabled()) {
  153. trace.exit("initialize", definitions);
  154. }
  155. return;
  156. }
  157. // TODO when the world works in terms of the context, we can remove the loader
  158. bcelWorld = new LTWWorld(classLoader, weavingContext, getMessageHandler(), null);
  159. weaver = new BcelWeaver(bcelWorld);
  160. // register the definitions
  161. success = registerDefinitions(weaver, classLoader, definitions);
  162. if (success) {
  163. // after adding aspects
  164. weaver.prepareForWeave();
  165. enable(); // TODO maw Needed to ensure messages are flushed
  166. success = weaveAndDefineConceteAspects();
  167. }
  168. if (success) {
  169. enable();
  170. } else {
  171. disable();
  172. bcelWorld = null;
  173. weaver = null;
  174. }
  175. if (WeavedClassCache.isEnabled()) {
  176. initializeCache(classLoader, getAspectClassNames(definitions), generatedClassHandler, getMessageHandler());
  177. }
  178. initialized = true;
  179. if (trace.isTraceEnabled()) {
  180. trace.exit("initialize", isEnabled());
  181. }
  182. }
  183. /**
  184. * Get the list of all aspects from the defintion list
  185. * @param definitions
  186. * @return
  187. */
  188. List<String> getAspectClassNames(List<Definition> definitions) {
  189. List<String> aspects = new LinkedList<String>();
  190. for (Iterator<Definition> it = definitions.iterator(); it.hasNext(); ) {
  191. Definition def = it.next();
  192. List<String> defAspects = def.getAspectClassNames();
  193. if (defAspects != null) {
  194. aspects.addAll(defAspects);
  195. }
  196. }
  197. return aspects;
  198. }
  199. /**
  200. * Load and cache the aop.xml/properties according to the classloader visibility rules
  201. *
  202. * @param loader
  203. */
  204. List<Definition> parseDefinitions(final ClassLoader loader) {
  205. if (trace.isTraceEnabled()) {
  206. trace.enter("parseDefinitions", this);
  207. }
  208. List<Definition> definitions = new ArrayList<Definition>();
  209. try {
  210. info("register classloader " + getClassLoaderName(loader));
  211. // TODO av underoptimized: we will parse each XML once per CL that see it
  212. // TODO av dev mode needed ? TBD -Daj5.def=...
  213. if (loader.equals(ClassLoader.getSystemClassLoader())) {
  214. String file = System.getProperty("aj5.def", null);
  215. if (file != null) {
  216. info("using (-Daj5.def) " + file);
  217. definitions.add(DocumentParser.parse((new File(file)).toURI().toURL()));
  218. }
  219. }
  220. String resourcePath = System.getProperty("org.aspectj.weaver.loadtime.configuration", AOP_XML);
  221. if (trace.isTraceEnabled()) {
  222. trace.event("parseDefinitions", this, resourcePath);
  223. }
  224. StringTokenizer st = new StringTokenizer(resourcePath, ";");
  225. while (st.hasMoreTokens()) {
  226. String nextDefinition = st.nextToken();
  227. if (nextDefinition.startsWith("file:")) {
  228. try {
  229. String fpath = new URL(nextDefinition).getFile();
  230. File configFile = new File(fpath);
  231. if (!configFile.exists()) {
  232. warn("configuration does not exist: " + nextDefinition);
  233. } else {
  234. definitions.add(DocumentParser.parse(configFile.toURI().toURL()));
  235. }
  236. } catch (MalformedURLException mue) {
  237. error("malformed definition url: " + nextDefinition);
  238. }
  239. } else {
  240. Enumeration<URL> xmls = weavingContext.getResources(nextDefinition);
  241. // System.out.println("? registerDefinitions: found-aop.xml=" + xmls.hasMoreElements() + ", loader=" + loader);
  242. Set<URL> seenBefore = new HashSet<URL>();
  243. while (xmls.hasMoreElements()) {
  244. URL xml = xmls.nextElement();
  245. if (trace.isTraceEnabled()) {
  246. trace.event("parseDefinitions", this, xml);
  247. }
  248. if (!seenBefore.contains(xml)) {
  249. info("using configuration " + weavingContext.getFile(xml));
  250. definitions.add(DocumentParser.parse(xml));
  251. seenBefore.add(xml);
  252. } else {
  253. debug("ignoring duplicate definition: " + xml);
  254. }
  255. }
  256. }
  257. }
  258. if (definitions.isEmpty()) {
  259. info("no configuration found. Disabling weaver for class loader " + getClassLoaderName(loader));
  260. }
  261. } catch (Exception e) {
  262. definitions.clear();
  263. warn("parse definitions failed", e);
  264. }
  265. if (trace.isTraceEnabled()) {
  266. trace.exit("parseDefinitions", definitions);
  267. }
  268. return definitions;
  269. }
  270. private boolean registerDefinitions(final BcelWeaver weaver, final ClassLoader loader, List<Definition> definitions) {
  271. if (trace.isTraceEnabled()) {
  272. trace.enter("registerDefinitions", this, definitions);
  273. }
  274. boolean success = true;
  275. try {
  276. registerOptions(weaver, loader, definitions);
  277. registerAspectExclude(weaver, loader, definitions);
  278. registerAspectInclude(weaver, loader, definitions);
  279. success = registerAspects(weaver, loader, definitions);
  280. registerIncludeExclude(weaver, loader, definitions);
  281. registerDump(weaver, loader, definitions);
  282. } catch (Exception ex) {
  283. trace.error("register definition failed", ex);
  284. success = false;
  285. warn("register definition failed", (ex instanceof AbortException) ? null : ex);
  286. }
  287. if (trace.isTraceEnabled()) {
  288. trace.exit("registerDefinitions", success);
  289. }
  290. return success;
  291. }
  292. private String getClassLoaderName(ClassLoader loader) {
  293. return weavingContext.getClassLoaderName();
  294. }
  295. /**
  296. * Configure the weaver according to the option directives TODO av - don't know if it is that good to reuse, since we only allow
  297. * a small subset of options in LTW
  298. *
  299. * @param weaver
  300. * @param loader
  301. * @param definitions
  302. */
  303. private void registerOptions(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  304. StringBuffer allOptions = new StringBuffer();
  305. for (Definition definition : definitions) {
  306. allOptions.append(definition.getWeaverOptions()).append(' ');
  307. }
  308. Options.WeaverOption weaverOption = Options.parse(allOptions.toString(), loader, getMessageHandler());
  309. // configure the weaver and world
  310. // AV - code duplicates AspectJBuilder.initWorldAndWeaver()
  311. World world = weaver.getWorld();
  312. setMessageHandler(weaverOption.messageHandler);
  313. world.setXlazyTjp(weaverOption.lazyTjp);
  314. world.setXHasMemberSupportEnabled(weaverOption.hasMember);
  315. world.setTiming(weaverOption.timers, true);
  316. world.setOptionalJoinpoints(weaverOption.optionalJoinpoints);
  317. world.setPinpointMode(weaverOption.pinpoint);
  318. weaver.setReweavableMode(weaverOption.notReWeavable);
  319. if (weaverOption.loadersToSkip != null && weaverOption.loadersToSkip.length() > 0) {
  320. Aj.loadersToSkip = LangUtil.anySplit(weaverOption.loadersToSkip, ",");
  321. }
  322. if (Aj.loadersToSkip != null) {
  323. MessageUtil.info(world.getMessageHandler(),"no longer creating weavers for these classloaders: "+Aj.loadersToSkip);
  324. }
  325. world.performExtraConfiguration(weaverOption.xSet);
  326. world.setXnoInline(weaverOption.noInline);
  327. // AMC - autodetect as per line below, needed for AtAjLTWTests.testLTWUnweavable
  328. world.setBehaveInJava5Way(LangUtil.is15VMOrGreater());
  329. world.setAddSerialVerUID(weaverOption.addSerialVersionUID);
  330. /* First load defaults */
  331. bcelWorld.getLint().loadDefaultProperties();
  332. /* Second overlay LTW defaults */
  333. bcelWorld.getLint().adviceDidNotMatch.setKind(null);
  334. /* Third load user file using -Xlintfile so that -Xlint wins */
  335. if (weaverOption.lintFile != null) {
  336. InputStream resource = null;
  337. try {
  338. resource = loader.getResourceAsStream(weaverOption.lintFile);
  339. Exception failure = null;
  340. if (resource != null) {
  341. try {
  342. Properties properties = new Properties();
  343. properties.load(resource);
  344. world.getLint().setFromProperties(properties);
  345. } catch (IOException e) {
  346. failure = e;
  347. }
  348. }
  349. if (failure != null || resource == null) {
  350. warn("Cannot access resource for -Xlintfile:" + weaverOption.lintFile, failure);
  351. // world.getMessageHandler().handleMessage(new Message(
  352. // "Cannot access resource for -Xlintfile:"+weaverOption.lintFile,
  353. // IMessage.WARNING,
  354. // failure,
  355. // null));
  356. }
  357. } finally {
  358. try {
  359. resource.close();
  360. } catch (Throwable t) {
  361. }
  362. }
  363. }
  364. /* Fourth override with -Xlint */
  365. if (weaverOption.lint != null) {
  366. if (weaverOption.lint.equals("default")) {// FIXME should be AjBuildConfig.AJLINT_DEFAULT but yetanother deps..
  367. bcelWorld.getLint().loadDefaultProperties();
  368. } else {
  369. bcelWorld.getLint().setAll(weaverOption.lint);
  370. if (weaverOption.lint.equals("ignore")) {
  371. bcelWorld.setAllLintIgnored();
  372. }
  373. }
  374. }
  375. // TODO proceedOnError option
  376. }
  377. private void registerAspectExclude(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  378. String fastMatchInfo = null;
  379. for (Definition definition : definitions) {
  380. for (String exclude : definition.getAspectExcludePatterns()) {
  381. TypePattern excludePattern = new PatternParser(exclude).parseTypePattern();
  382. aspectExcludeTypePattern.add(excludePattern);
  383. fastMatchInfo = looksLikeStartsWith(exclude);
  384. if (fastMatchInfo != null) {
  385. aspectExcludeStartsWith.add(fastMatchInfo);
  386. }
  387. }
  388. }
  389. }
  390. private void registerAspectInclude(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  391. String fastMatchInfo = null;
  392. for (Definition definition : definitions) {
  393. for (String include : definition.getAspectIncludePatterns()) {
  394. TypePattern includePattern = new PatternParser(include).parseTypePattern();
  395. aspectIncludeTypePattern.add(includePattern);
  396. fastMatchInfo = looksLikeStartsWith(include);
  397. if (fastMatchInfo != null) {
  398. aspectIncludeStartsWith.add(fastMatchInfo);
  399. }
  400. }
  401. }
  402. }
  403. protected void lint(String name, String[] infos) {
  404. Lint lint = bcelWorld.getLint();
  405. Kind kind = lint.getLintKind(name);
  406. kind.signal(infos, null, null);
  407. }
  408. @Override
  409. public String getContextId() {
  410. return weavingContext.getId();
  411. }
  412. /**
  413. * Register the aspect, following include / exclude rules
  414. *
  415. * @param weaver
  416. * @param loader
  417. * @param definitions
  418. */
  419. private boolean registerAspects(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  420. if (trace.isTraceEnabled()) {
  421. trace.enter("registerAspects", this, new Object[] { weaver, loader, definitions });
  422. }
  423. boolean success = true;
  424. // TODO: the exclude aspect allow to exclude aspect defined upper in the CL hierarchy - is it what we want ??
  425. // if not, review the getResource so that we track which resource is defined by which CL
  426. // iterate aspectClassNames
  427. // exclude if in any of the exclude list
  428. for (Definition definition : definitions) {
  429. for (String aspectClassName : definition.getAspectClassNames()) {
  430. if (acceptAspect(aspectClassName)) {
  431. info("register aspect " + aspectClassName);
  432. // System.err.println("? ClassLoaderWeavingAdaptor.registerAspects() aspectName=" + aspectClassName +
  433. // ", loader=" + loader + ", bundle=" + weavingContext.getClassLoaderName());
  434. String requiredType = definition.getAspectRequires(aspectClassName);
  435. if (requiredType != null) {
  436. // This aspect expresses that it requires a type to be around, otherwise it should 'switch off'
  437. ((BcelWorld) weaver.getWorld()).addAspectRequires(aspectClassName, requiredType);
  438. }
  439. String definedScope = definition.getScopeForAspect(aspectClassName);
  440. if (definedScope != null) {
  441. ((BcelWorld) weaver.getWorld()).addScopedAspect(aspectClassName, definedScope);
  442. }
  443. // ResolvedType aspect =
  444. weaver.addLibraryAspect(aspectClassName);
  445. // generate key for SC
  446. if (namespace == null) {
  447. namespace = new StringBuffer(aspectClassName);
  448. } else {
  449. namespace = namespace.append(";").append(aspectClassName);
  450. }
  451. } else {
  452. // warn("aspect excluded: " + aspectClassName);
  453. lint("aspectExcludedByConfiguration", new String[] { aspectClassName, getClassLoaderName(loader) });
  454. }
  455. }
  456. }
  457. // iterate concreteAspects
  458. // exclude if in any of the exclude list - note that the user defined name matters for that to happen
  459. for (Definition definition : definitions) {
  460. for (Definition.ConcreteAspect concreteAspect : definition.getConcreteAspects()) {
  461. if (acceptAspect(concreteAspect.name)) {
  462. info("define aspect " + concreteAspect.name);
  463. ConcreteAspectCodeGen gen = new ConcreteAspectCodeGen(concreteAspect, weaver.getWorld());
  464. if (!gen.validate()) {
  465. error("Concrete-aspect '" + concreteAspect.name + "' could not be registered");
  466. success = false;
  467. break;
  468. }
  469. ((BcelWorld) weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(concreteAspect.name, gen.getBytes()),
  470. true);
  471. concreteAspects.add(gen);
  472. weaver.addLibraryAspect(concreteAspect.name);
  473. // generate key for SC
  474. if (namespace == null) {
  475. namespace = new StringBuffer(concreteAspect.name);
  476. } else {
  477. namespace = namespace.append(";" + concreteAspect.name);
  478. }
  479. }
  480. }
  481. }
  482. /* We couldn't register one or more aspects so disable the adaptor */
  483. if (!success) {
  484. warn("failure(s) registering aspects. Disabling weaver for class loader " + getClassLoaderName(loader));
  485. }
  486. /* We didn't register any aspects so disable the adaptor */
  487. else if (namespace == null) {
  488. success = false;
  489. info("no aspects registered. Disabling weaver for class loader " + getClassLoaderName(loader));
  490. }
  491. if (trace.isTraceEnabled()) {
  492. trace.exit("registerAspects", success);
  493. }
  494. return success;
  495. }
  496. private boolean weaveAndDefineConceteAspects() {
  497. if (trace.isTraceEnabled()) {
  498. trace.enter("weaveAndDefineConceteAspects", this, concreteAspects);
  499. }
  500. boolean success = true;
  501. for (ConcreteAspectCodeGen gen : concreteAspects) {
  502. String name = gen.getClassName();
  503. byte[] bytes = gen.getBytes();
  504. try {
  505. byte[] newBytes = weaveClass(name, bytes, true);
  506. this.generatedClassHandler.acceptClass(name, bytes, newBytes);
  507. } catch (IOException ex) {
  508. trace.error("weaveAndDefineConceteAspects", ex);
  509. error("exception weaving aspect '" + name + "'", ex);
  510. }
  511. }
  512. if (trace.isTraceEnabled()) {
  513. trace.exit("weaveAndDefineConceteAspects", success);
  514. }
  515. return success;
  516. }
  517. /**
  518. * Register the include / exclude filters. We duplicate simple patterns in startWith filters that will allow faster matching
  519. * without ResolvedType
  520. *
  521. * @param weaver
  522. * @param loader
  523. * @param definitions
  524. */
  525. private void registerIncludeExclude(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  526. String fastMatchInfo = null;
  527. for (Definition definition : definitions) {
  528. for (Iterator<String> iterator1 = definition.getIncludePatterns().iterator(); iterator1.hasNext();) {
  529. hasIncludes = true;
  530. String include = iterator1.next();
  531. fastMatchInfo = looksLikeStartsWith(include);
  532. if (fastMatchInfo != null) {
  533. includeStartsWith.add(fastMatchInfo);
  534. } else if (include.equals("*")) {
  535. includeStar = true;
  536. } else if ((fastMatchInfo = looksLikeExactName(include)) != null) {
  537. includeExactName.add(fastMatchInfo);
  538. } else {
  539. TypePattern includePattern = new PatternParser(include).parseTypePattern();
  540. includeTypePattern.add(includePattern);
  541. }
  542. }
  543. for (Iterator<String> iterator1 = definition.getExcludePatterns().iterator(); iterator1.hasNext();) {
  544. hasExcludes = true;
  545. String exclude = iterator1.next();
  546. fastMatchInfo = looksLikeStartsWith(exclude);
  547. if (fastMatchInfo != null) {
  548. excludeStartsWith.add(fastMatchInfo);
  549. } else if ((fastMatchInfo = looksLikeStarDotDotStarExclude(exclude)) != null) {
  550. excludeStarDotDotStar.add(fastMatchInfo);
  551. } else if ((fastMatchInfo = looksLikeExactName(exclude)) != null) {
  552. excludeExactName.add(exclude);
  553. } else if ((fastMatchInfo = looksLikeEndsWith(exclude)) != null) {
  554. excludeEndsWith.add(fastMatchInfo);
  555. } else if (exclude
  556. .equals("org.codehaus.groovy..* && !org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController*")) {
  557. // TODO need a more sophisticated analysis here, to allow for similar situations
  558. excludeSpecial.add(new String[] { "org.codehaus.groovy.",
  559. "org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController" });
  560. // for the related test:
  561. // } else if (exclude.equals("testdata..* && !testdata.sub.Oran*")) {
  562. // excludeSpecial.add(new String[] { "testdata.", "testdata.sub.Oran" });
  563. } else {
  564. TypePattern excludePattern = new PatternParser(exclude).parseTypePattern();
  565. excludeTypePattern.add(excludePattern);
  566. }
  567. }
  568. }
  569. }
  570. /**
  571. * Checks if the pattern looks like "*..*XXXX*" and if so returns XXXX. This will enable fast name matching of CGLIB exclusion
  572. *
  573. */
  574. private String looksLikeStarDotDotStarExclude(String typePattern) {
  575. if (!typePattern.startsWith("*..*")) {
  576. return null;
  577. }
  578. if (!typePattern.endsWith("*")) {
  579. return null;
  580. }
  581. String subPattern = typePattern.substring(4, typePattern.length() - 1);
  582. if (hasStarDot(subPattern, 0)) {
  583. return null;
  584. }
  585. return subPattern.replace('$', '.');
  586. }
  587. /**
  588. * Checks if the pattern looks like "com.foo.Bar" - an exact name
  589. */
  590. private String looksLikeExactName(String typePattern) {
  591. if (hasSpaceAnnotationPlus(typePattern, 0) || typePattern.indexOf("*") != -1) {
  592. return null;
  593. }
  594. return typePattern.replace('$', '.');
  595. }
  596. /**
  597. * Checks if the pattern looks like "*Exception"
  598. */
  599. private String looksLikeEndsWith(String typePattern) {
  600. if (typePattern.charAt(0) != '*') {
  601. return null;
  602. }
  603. if (hasSpaceAnnotationPlus(typePattern, 1) || hasStarDot(typePattern, 1)) {
  604. return null;
  605. }
  606. return typePattern.substring(1).replace('$', '.');
  607. }
  608. /**
  609. * Determine if something in the string is going to affect our ability to optimize. Checks for: ' ' '@' '+'
  610. */
  611. private boolean hasSpaceAnnotationPlus(String string, int pos) {
  612. for (int i = pos, max = string.length(); i < max; i++) {
  613. char ch = string.charAt(i);
  614. if (ch == ' ' || ch == '@' || ch == '+') {
  615. return true;
  616. }
  617. }
  618. return false;
  619. }
  620. /**
  621. * Determine if something in the string is going to affect our ability to optimize. Checks for: '*' '.'
  622. */
  623. private boolean hasStarDot(String string, int pos) {
  624. for (int i = pos, max = string.length(); i < max; i++) {
  625. char ch = string.charAt(i);
  626. if (ch == '*' || ch == '.') {
  627. return true;
  628. }
  629. }
  630. return false;
  631. }
  632. /**
  633. * Checks if the type pattern looks like "com.foo..*"
  634. */
  635. private String looksLikeStartsWith(String typePattern) {
  636. if (hasSpaceAnnotationPlus(typePattern, 0) || typePattern.charAt(typePattern.length() - 1) != '*') {
  637. return null;
  638. }
  639. // now must looks like with "charsss..*" or "cha.rss..*" etc
  640. // note that "*" and "*..*" won't be fast matched
  641. // and that "charsss.*" will not neither
  642. int length = typePattern.length();
  643. if (typePattern.endsWith("..*") && length > 3) {
  644. if (typePattern.indexOf("..") == length - 3 // no ".." before last sequence
  645. && typePattern.indexOf('*') == length - 1) { // no earlier '*'
  646. return typePattern.substring(0, length - 2).replace('$', '.'); // "charsss." or "char.rss." etc
  647. }
  648. }
  649. return null;
  650. }
  651. /**
  652. * Register the dump filter
  653. *
  654. * @param weaver
  655. * @param loader
  656. * @param definitions
  657. */
  658. private void registerDump(final BcelWeaver weaver, final ClassLoader loader, final List<Definition> definitions) {
  659. for (Definition definition : definitions) {
  660. for (Iterator<String> iterator1 = definition.getDumpPatterns().iterator(); iterator1.hasNext();) {
  661. String dump = iterator1.next();
  662. TypePattern pattern = new PatternParser(dump).parseTypePattern();
  663. dumpTypePattern.add(pattern);
  664. }
  665. if (definition.shouldDumpBefore()) {
  666. dumpBefore = true;
  667. }
  668. if (definition.createDumpDirPerClassloader()) {
  669. dumpDirPerClassloader = true;
  670. }
  671. }
  672. }
  673. /**
  674. * Determine whether a type should be accepted for weaving, by checking it against any includes/excludes.
  675. *
  676. * @param className the name of the type to possibly accept
  677. * @param bytes the bytecode for the type (in case we need to look inside, eg. annotations)
  678. * @return true if it should be accepted for weaving
  679. */
  680. @Override
  681. protected boolean accept(String className, byte[] bytes) {
  682. if (!hasExcludes && !hasIncludes) {
  683. return true;
  684. }
  685. // still try to avoid ResolvedType if we have simple patterns
  686. String fastClassName = className.replace('/', '.');
  687. for (String excludeStartsWithString : excludeStartsWith) {
  688. if (fastClassName.startsWith(excludeStartsWithString)) {
  689. return false;
  690. }
  691. }
  692. // Fast exclusion of patterns like: "*..*CGLIB*"
  693. if (!excludeStarDotDotStar.isEmpty()) {
  694. for (String namePiece : excludeStarDotDotStar) {
  695. int index = fastClassName.lastIndexOf('.');
  696. if (fastClassName.indexOf(namePiece, index + 1) != -1) {
  697. return false;
  698. }
  699. }
  700. }
  701. fastClassName = fastClassName.replace('$', '.');
  702. if (!excludeEndsWith.isEmpty()) {
  703. for (String lastPiece : excludeEndsWith) {
  704. if (fastClassName.endsWith(lastPiece)) {
  705. return false;
  706. }
  707. }
  708. }
  709. // Fast exclusion of exact names
  710. if (!excludeExactName.isEmpty()) {
  711. for (String name : excludeExactName) {
  712. if (fastClassName.equals(name)) {
  713. return false;
  714. }
  715. }
  716. }
  717. if (!excludeSpecial.isEmpty()) {
  718. for (String[] entry : excludeSpecial) {
  719. String excludeThese = entry[0];
  720. String exceptThese = entry[1];
  721. if (fastClassName.startsWith(excludeThese) && !fastClassName.startsWith(exceptThese)) {
  722. return false;
  723. }
  724. }
  725. }
  726. /*
  727. * Bug 120363 If we have an exclude pattern that cannot be matched using "starts with" then we cannot fast accept
  728. */
  729. boolean didSomeIncludeMatching = false;
  730. if (excludeTypePattern.isEmpty()) {
  731. if (includeStar) {
  732. return true;
  733. }
  734. if (!includeExactName.isEmpty()) {
  735. didSomeIncludeMatching = true;
  736. for (String exactname : includeExactName) {
  737. if (fastClassName.equals(exactname)) {
  738. return true;
  739. }
  740. }
  741. }
  742. boolean fastAccept = false;// defaults to false if no fast include
  743. for (int i = 0; i < includeStartsWith.size(); i++) {
  744. didSomeIncludeMatching = true;
  745. fastAccept = fastClassName.startsWith(includeStartsWith.get(i));
  746. if (fastAccept) {
  747. return true;
  748. }
  749. }
  750. // We may have processed all patterns now... check that and return
  751. if (includeTypePattern.isEmpty()) {
  752. return !didSomeIncludeMatching;
  753. }
  754. }
  755. boolean accept;
  756. try {
  757. ensureDelegateInitialized(className, bytes);
  758. ResolvedType classInfo = delegateForCurrentClass.getResolvedTypeX();
  759. // exclude are "AND"ed
  760. for (TypePattern typePattern : excludeTypePattern) {
  761. if (typePattern.matchesStatically(classInfo)) {
  762. // exclude match - skip
  763. return false;
  764. }
  765. }
  766. // include are "OR"ed
  767. if (includeStar) {
  768. return true;
  769. }
  770. if (!includeExactName.isEmpty()) {
  771. didSomeIncludeMatching = true;
  772. for (String exactname : includeExactName) {
  773. if (fastClassName.equals(exactname)) {
  774. return true;
  775. }
  776. }
  777. }
  778. for (int i = 0; i < includeStartsWith.size(); i++) {
  779. didSomeIncludeMatching = true;
  780. boolean fastaccept = fastClassName.startsWith(includeStartsWith.get(i));
  781. if (fastaccept) {
  782. return true;
  783. }
  784. }
  785. accept = !didSomeIncludeMatching; // only true if no includes at all
  786. for (TypePattern typePattern : includeTypePattern) {
  787. accept = typePattern.matchesStatically(classInfo);
  788. if (accept) {
  789. break;
  790. }
  791. // goes on if this include did not match ("OR"ed)
  792. }
  793. } finally {
  794. this.bcelWorld.demote();
  795. }
  796. return accept;
  797. }
  798. // FIXME we don't use include/exclude of others aop.xml
  799. // this can be nice but very dangerous as well to change that
  800. private boolean acceptAspect(String aspectClassName) {
  801. // avoid ResolvedType if not needed
  802. if (aspectExcludeTypePattern.isEmpty() && aspectIncludeTypePattern.isEmpty()) {
  803. return true;
  804. }
  805. // still try to avoid ResolvedType if we have simple patterns
  806. // EXCLUDE: if one match then reject
  807. String fastClassName = aspectClassName.replace('/', '.').replace('.', '$');
  808. for (int i = 0; i < aspectExcludeStartsWith.size(); i++) {
  809. if (fastClassName.startsWith(aspectExcludeStartsWith.get(i))) {
  810. return false;
  811. }
  812. }
  813. // INCLUDE: if one match then accept
  814. for (int i = 0; i < aspectIncludeStartsWith.size(); i++) {
  815. if (fastClassName.startsWith(aspectIncludeStartsWith.get(i))) {
  816. return true;
  817. }
  818. }
  819. // needs further analysis
  820. ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(aspectClassName), true);
  821. // exclude are "AND"ed
  822. for (TypePattern typePattern: aspectExcludeTypePattern) {
  823. if (typePattern.matchesStatically(classInfo)) {
  824. // exclude match - skip
  825. return false;
  826. }
  827. }
  828. // include are "OR"ed
  829. boolean accept = true;// defaults to true if no include
  830. for (TypePattern typePattern: aspectIncludeTypePattern) {
  831. accept = typePattern.matchesStatically(classInfo);
  832. if (accept) {
  833. break;
  834. }
  835. // goes on if this include did not match ("OR"ed)
  836. }
  837. return accept;
  838. }
  839. @Override
  840. protected boolean shouldDump(String className, boolean before) {
  841. // Don't dump before weaving unless asked to
  842. if (before && !dumpBefore) {
  843. return false;
  844. }
  845. // avoid ResolvedType if not needed
  846. if (dumpTypePattern.isEmpty()) {
  847. return false;
  848. }
  849. // TODO AV - optimize for className.startWith only
  850. ResolvedType classInfo = weaver.getWorld().resolve(UnresolvedType.forName(className), true);
  851. // dump
  852. for (Iterator<TypePattern> iterator = dumpTypePattern.iterator(); iterator.hasNext();) {
  853. TypePattern typePattern = iterator.next();
  854. if (typePattern.matchesStatically(classInfo)) {
  855. // dump match
  856. return true;
  857. }
  858. }
  859. return false;
  860. }
  861. @Override
  862. protected String getDumpDir() {
  863. if (dumpDirPerClassloader) {
  864. StringBuffer dir = new StringBuffer();
  865. dir.append("_ajdump").append(File.separator).append(weavingContext.getId());
  866. return dir.toString();
  867. } else {
  868. return super.getDumpDir();
  869. }
  870. }
  871. /*
  872. * shared classes methods
  873. */
  874. /**
  875. * @return Returns the key.
  876. */
  877. public String getNamespace() {
  878. // System.out.println("ClassLoaderWeavingAdaptor.getNamespace() classloader=" + weavingContext.getClassLoaderName() +
  879. // ", namespace=" + namespace);
  880. if (namespace == null) {
  881. return "";
  882. } else {
  883. return new String(namespace);
  884. }
  885. }
  886. /**
  887. * Check to see if any classes are stored in the generated classes cache. Then flush the cache if it is not empty
  888. *
  889. * @param className TODO
  890. * @return true if a class has been generated and is stored in the cache
  891. */
  892. public boolean generatedClassesExistFor(String className) {
  893. // System.err.println("? ClassLoaderWeavingAdaptor.generatedClassesExist() classname=" + className + ", size=" +
  894. // generatedClasses);
  895. if (className == null) {
  896. return !generatedClasses.isEmpty();
  897. } else {
  898. return generatedClasses.containsKey(className);
  899. }
  900. }
  901. /**
  902. * Flush the generated classes cache
  903. */
  904. public void flushGeneratedClasses() {
  905. // System.err.println("? ClassLoaderWeavingAdaptor.flushGeneratedClasses() generatedClasses=" + generatedClasses);
  906. generatedClasses = new HashMap<String, IUnwovenClassFile>();
  907. }
  908. /**
  909. * Remove generated classes based on the supplied className. This will
  910. * remove any entries related to this name - so the class itself plus
  911. * and inner classes.
  912. * @param className a slashed classname (e.g. com/foo/Bar)
  913. */
  914. public void flushGeneratedClassesFor(String className) {
  915. try {
  916. String dottedClassName = className.replace('/', '.');
  917. String dottedClassNameDollar = dottedClassName+"$"; // to pickup inner classes
  918. Iterator<Map.Entry<String, IUnwovenClassFile>> iter = generatedClasses.entrySet().iterator();
  919. while (iter.hasNext()) {
  920. Entry<String, IUnwovenClassFile> next = iter.next();
  921. String existingGeneratedName = next.getKey();
  922. if (existingGeneratedName.equals(dottedClassName) ||
  923. existingGeneratedName.startsWith(dottedClassNameDollar)) {
  924. iter.remove();
  925. }
  926. }
  927. } catch (Throwable t) {
  928. new RuntimeException("Unexpected problem tidying up generated classes for "+className,t).printStackTrace();
  929. }
  930. }
  931. private Unsafe unsafe;
  932. private Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
  933. if (unsafe == null) {
  934. Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
  935. theUnsafeField.setAccessible(true);
  936. return (Unsafe) theUnsafeField.get(null);
  937. }
  938. return unsafe;
  939. }
  940. private static Method bindTo_Method, invokeWithArguments_Method = null;
  941. private static Object defineClassMethodHandle = null;
  942. private static Boolean initializedForJava11 = false;
  943. // In order to let this code compile on earlier versions of Java (8), use reflection to discover the elements
  944. // we need to define classes.
  945. private static synchronized void initializeForJava11() {
  946. if (initializedForJava11) return;
  947. try {
  948. // MethodType defineClassMethodType = MethodType.methodType(Class.class, new Class[]{String.class, byte[].class, int.class, int.class});
  949. Class<?> methodType_Class = Class.forName("java.lang.invoke.MethodType");
  950. Method methodTypeMethodOnMethodTypeClass = methodType_Class.getDeclaredMethod("methodType", Class.class,Class[].class);
  951. methodTypeMethodOnMethodTypeClass.setAccessible(true);
  952. Object defineClassMethodType = methodTypeMethodOnMethodTypeClass.invoke(null, Class.class, new Class[] {String.class,byte[].class,int.class,int.class});
  953. // MethodHandles.Lookup methodHandlesLookup = MethodHandles.lookup();
  954. Class<?> methodHandles_Class = Class.forName("java.lang.invoke.MethodHandles");
  955. Method lookupMethodOnMethodHandlesClass = methodHandles_Class.getDeclaredMethod("lookup");
  956. lookupMethodOnMethodHandlesClass.setAccessible(true);
  957. Object methodHandlesLookup = lookupMethodOnMethodHandlesClass.invoke(null);
  958. // MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup);
  959. Class<?> methodHandlesLookup_Class = Class.forName("java.lang.invoke.MethodHandles$Lookup");
  960. Method privateLookupMethodOnMethodHandlesClass = methodHandles_Class.getDeclaredMethod("privateLookupIn",Class.class,methodHandlesLookup_Class);
  961. privateLookupMethodOnMethodHandlesClass.setAccessible(true);
  962. Object lookup = privateLookupMethodOnMethodHandlesClass.invoke(null, ClassLoader.class, methodHandlesLookup);
  963. // MethodHandle defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType);
  964. Method findVirtual_Method = methodHandlesLookup_Class.getDeclaredMethod("findVirtual", Class.class,String.class,methodType_Class);
  965. findVirtual_Method.setAccessible(true);
  966. defineClassMethodHandle = findVirtual_Method.invoke(lookup, ClassLoader.class, "defineClass",defineClassMethodType);
  967. // clazz = defineClassMethodHandle.bindTo(loader).invokeWithArguments(name, bytes, 0, bytes.length);
  968. Class<?> methodHandle_Class = Class.forName("java.lang.invoke.MethodHandle");
  969. bindTo_Method = methodHandle_Class.getDeclaredMethod("bindTo", Object.class);
  970. invokeWithArguments_Method = methodHandle_Class.getDeclaredMethod("invokeWithArguments",Object[].class);
  971. initializedForJava11 = true;
  972. } catch (Exception e) {
  973. e.printStackTrace();
  974. }
  975. }
  976. private void defineClass(ClassLoader loader, String name, byte[] bytes, ProtectionDomain protectionDomain) {
  977. if (trace.isTraceEnabled()) {
  978. trace.enter("defineClass", this, new Object[] { loader, name, bytes });
  979. }
  980. Object clazz = null;
  981. debug("generating class '" + name + "'");
  982. if (LangUtil.is11VMOrGreater()) {
  983. try {
  984. if (!initializedForJava11) {
  985. initializeForJava11();
  986. }
  987. // Do this: clazz = defineClassMethodHandle.bindTo(loader).invokeWithArguments(name, bytes, 0, bytes.length);
  988. Object o = bindTo_Method.invoke(defineClassMethodHandle,loader);
  989. clazz = invokeWithArguments_Method.invoke(o, new Object[] {new Object[] {name, bytes, 0, bytes.length}});
  990. } catch (Throwable t) {
  991. t.printStackTrace(System.err);
  992. warn("define generated class failed", t);
  993. }
  994. } else {
  995. try {
  996. if (defineClassMethod == null) {
  997. synchronized (lock) {
  998. getUnsafe();
  999. defineClassMethod =
  1000. Unsafe.class.getDeclaredMethod("defineClass", String.class,byte[].class,Integer.TYPE,Integer.TYPE, ClassLoader.class,ProtectionDomain.class);
  1001. }
  1002. }
  1003. defineClassMethod.setAccessible(true);
  1004. clazz = defineClassMethod.invoke(getUnsafe(), name,bytes,0,bytes.length,loader,protectionDomain);
  1005. } catch (LinkageError le) {
  1006. le.printStackTrace();
  1007. // likely thrown due to defining something that already exists?
  1008. // Old comments from before moving to Unsafe.defineClass():
  1009. // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
  1010. // TODO maw I don't think this is OK and
  1011. } catch (Exception e) {
  1012. e.printStackTrace(System.err);
  1013. warn("define generated class failed", e);
  1014. }
  1015. }
  1016. if (trace.isTraceEnabled()) {
  1017. trace.exit("defineClass", clazz);
  1018. }
  1019. }
  1020. static Method defineClassMethod;
  1021. private static String lock = "lock";
  1022. // /*
  1023. // This method is equivalent to the following code but use reflection to compile on Java 7:
  1024. // MethodHandles.Lookup baseLookup = MethodHandles.lookup();
  1025. // MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(ClassLoader.class, baseLookup);
  1026. // MethodHandle defineClassMethodHandle = lookup.findVirtual(ClassLoader.class, "defineClass", defineClassMethodType);
  1027. // handle.bindTo(classLoader).invokeWithArguments(className, classBytes, 0, classBytes.length));
  1028. // */
  1029. //@Override
  1030. //@SuppressWarnings("unchecked")
  1031. //public <T> Class<T> defineClass(ClassLoader classLoader, String className, byte[] classBytes) {
  1032. // Object baseLookup = methodHandlesLookup.invoke(null);
  1033. // Object lookup = methodHandlesPrivateLookupIn.invoke(null, ClassLoader.class, baseLookup);
  1034. // MethodHandle defineClassMethodHandle = (MethodHandle) lookupFindVirtual.invoke(lookup, ClassLoader.class, "defineClass", defineClassMethodType);
  1035. // try {
  1036. // return Cast.uncheckedCast(defineClassMethodHandle.bindTo(classLoader).invokeWithArguments(className, classBytes, 0, classBytes.length));
  1037. // } catch (Throwable throwable) {
  1038. // throw new RuntimeException(throwable);
  1039. // return (Class) defineClassMethodHandle.bindTo(classLoader).invokeWithArguments(className, classBytes, 0, classBytes.length);
  1040. // } catch (Throwable e) {
  1041. // throw new RuntimeException(e);
  1042. // }
  1043. //}
  1044. private void defineClass(ClassLoader loader, String name, byte[] bytes){
  1045. defineClass(loader,name,bytes,null);//, ProtectionDomain protectionDomain) {
  1046. }
  1047. // if (trace.isTraceEnabled()) {
  1048. // trace.enter("defineClass", this, new Object[] { loader, name, bytes, protectionDomain });
  1049. // }
  1050. // Object clazz = null;
  1051. // debug("generating class '" + name + "'");
  1052. // try {
  1053. // getUnsafe().defineClass(name, bytes, 0, bytes.length, loader, protectionDomain);
  1054. // } catch (LinkageError le) {
  1055. // // likely thrown due to defining something that already exists?
  1056. // // Old comments from before moving to Unsafe.defineClass():
  1057. // // is already defined (happens for X$ajcMightHaveAspect interfaces since aspects are reweaved)
  1058. // // TODO maw I don't think this is OK and
  1059. // } catch (Exception e) {
  1060. // warn("define generated class failed", e);
  1061. // }
  1062. //
  1063. // if (trace.isTraceEnabled()) {
  1064. // trace.exit("defineClass", clazz);
  1065. // }
  1066. // }
  1067. }