java - AspectJ: ClassLoading issue when trying to use external aop.xml file -


i m trying externalize configuration of aop.xml removed aop.xml meta-inf , made available in server manual configuration sys admins.

when try use external aop.xml using

-dorg.aspectj.weaver.loadtime.configuration="file:d:\workspace\tomcat7\shared\lib\aop.xml" 

i java.lang.runtimeexception: cannot register non aspect: aspectclass.... because aj casses not loaded appclassloader yet @ time. , next time tries register aspects webappclassloader ( after classes loaded), works fine, still exceptions logged 1st attempt register it.

the exception caught , logged @ classloaderweavingadaptor.java line 307.

when following line called: success = registeraspects(weaver, loader, definitions);

the exception caught , logged.

    try {         registeroptions(weaver, loader, definitions);         registeraspectexclude(weaver, loader, definitions);         registeraspectinclude(weaver, loader, definitions);         success = registeraspects(weaver, loader, definitions);         registerincludeexclude(weaver, loader, definitions);         registerdump(weaver, loader, definitions);     } catch (exception ex) {         trace.error("register definition failed", ex);         success = false;         warn("register definition failed", (ex instanceof abortexception) ? null : ex);     } 

the exception thrown excactly in following line in bcelweaver.java

if (type.isaspect()) {       ...... } else {         // fixme av - better warning upon no such aspect aop.xml         runtimeexception ex = new runtimeexception("cannot register non aspect: " + type.getname() + " , " + aspectname);         if (trace.istraceenabled()) {             trace.exit("addlibraryaspect", ex);         }         throw ex;     } 

how can prevent classloader logging error console, when aspects not loaded yet. thinking of commenting line logs exception source file , rebuilding aspectjweaver jar file, looking better solution without modifying aspectj source.

i not sure there easy way out of problem. said haven't worked aspectj before believe mis-behaviour of weaver.

problem description: during boot agent tries apply weaving other not webappclassloader whole classloader chain (once per classloader) i.e. to: sun.misc.launcher$appclassloader, sun.misc.launcher$extclassloader, org.apache.catalina.loader.standardclassloader (the tomcat's classloader). when use meta-inf/aop.xml approach disables weaving above classloaders because "a configuration file not available" (if enable verbose mode can see messages in console). when use file configuration approach, configuration is available classloaders in chain. since find configuration file, agent parses definitions, not find aspects' class , shows error.

the weird thing that, described in configuration documentation if use weavingurlclassloader approach load time weaving, "... allows user explicitly restrict class loader classes can woven". feature (!) classloader approach can have agent approach doesn't. (unfortunately not able use approach)

the (and bad) news: news can create own agent ignore weaving aforementioned classloaders. bad news restricting weaving per classloader not enough because if have other applications in same server, tomcat still use webappclassloader load them still error messages applications. (perhaps extend classes below filter packages/classes well, in case).

below can find 2 class modified agent. use them need following:

  • un-jar aspectjweaver.jar folder
  • under org/aspectj/weaver/loadtime create new folder filter match package name , put there 2 new classes after compile them.
  • edit meta-inf/manifest.mf file , change line

    premain-class: org.aspectj.weaver.loadtime.agent to
    premain-class: org.aspectj.weaver.loadtime.filter.filteragent

  • re-jar , have new agent ready.

  • when starting jvm can pass new system property comma separated list of classloaders ignore i.e. -dorg.aspectj.weaver.loadtime.filter=sun.misc.launcher$appclassloader,sun.misc.launcher$extclassloader,org.apache.catalina.loader.standardclassloader ( have set catalina_opts that).

the classes modified copy of original agent's classes agent , classpreprocessoragentadapter. code have added part parses above system property if exists , ignore calls classloaders not interested in.

use @ own risk :) hope helps

package org.aspectj.weaver.loadtime.filter;  import java.lang.instrument.classfiletransformer; import java.lang.instrument.instrumentation;  public class filteragent {      private static instrumentation s_instrumentation;      // use our own version of classfiletransformer filter out selected classloaders      private static classfiletransformer s_transformer = new classpreprocessorfilteredadapter();      /**      * jsr-163 premain agent entry method      *      * @param options      * @param instrumentation      */     public static void premain(string options, instrumentation instrumentation) {         /* handle duplicate agents */         if (s_instrumentation != null) {             return;         }         s_instrumentation = instrumentation;         s_instrumentation.addtransformer(s_transformer);     }      public static instrumentation getinstrumentation() {         if (s_instrumentation == null) {             throw new unsupportedoperationexception("java 5 not started premain -javaagent aspectj");         }         return s_instrumentation;     } } //----------------------------------------------------------------------------------- package org.aspectj.weaver.loadtime.filter;  import java.lang.instrument.classfiletransformer; import java.lang.instrument.illegalclassformatexception; import java.security.protectiondomain; import java.util.hashmap; import java.util.map;  import org.aspectj.weaver.loadtime.aj; import org.aspectj.weaver.loadtime.classpreprocessor;   public class classpreprocessorfilteredadapter implements classfiletransformer {      /**      * concrete preprocessor.      */     private static classpreprocessor s_preprocessor;      private static map<string, string> ignoredclassloadernames = new hashmap<string, string>();      static {         try {             s_preprocessor = new aj();             s_preprocessor.initialize();               string ignoredloaders = system.getproperty("org.aspectj.weaver.loadtime.filter", "");             if (ignoredloaders.length() > 0) {                 string[] loaders = ignoredloaders.split(",");                  (string s : loaders) {                     s = s.trim();                     ignoredclassloadernames.put(s, s);                     system.out.println("---> filtered out classloader: " + s);                 }             }          } catch (exception e) {             throw new exceptionininitializererror("could not initialize jsr163 preprocessor due to: " + e.tostring());         }     }      /**      * invokes weaver modify set of input bytes.      *       * @param loader defining class loader      * @param classname name of class being loaded      * @param classbeingredefined set when hotswap being attempted      * @param protectiondomain protection domain class being loaded      * @param bytes incoming bytes (before weaving)      * @return 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 + "'");         }          string loadername = loader.getclass().getname();         if (shouldignoreclassloader(loadername)) {             return bytes;         }         return s_preprocessor.preprocess(classname, bytes, loader, protectiondomain);     }      private boolean shouldignoreclassloader(string loadername) {         boolean result = false;         string ignoredloader = ignoredclassloadernames.get(loadername);         if (ignoredloader != null) {             result = true;    // if loader name exists in map ignore weaving         }         return result;     } } 

Comments

Popular posts from this blog

ios - UICollectionView Self Sizing Cells with Auto Layout -

node.js - ldapjs - write after end error -

DOM Manipulation in Wordpress (and elsewhere) using php -