Gradle + AspectJ日志跟踪正在尝试在“仪器”期间失败并重新编译项目

问题描述

编辑:

我已在此处https://github.com/swapnil-kotwal-sp/basic-demo推送了伪源代码

似乎还可以同时进行AspectJ instrumentation的编译?

但是,我在instrumentation期间得到了警告

[ant:iajc] [warning] build config error: skipping missing,empty or
 corrupt aspectpath entry: 
/Users/swapnil.kotwal/Downloads/basic-demo/my-demo/src/com/my/demo/TracingAspect.java

有人可以帮助我解决此TracingAspect.java问题吗?

我的蚂蚁目标如下所示。.我已将其转换为Gradle构建脚本,如下一个code block

所示
<target name="weave-aspects" depends="compile,jar-common" unless="weave.suppressed"
          description="weaves the AspectJ's aspects into classes compiled by compile target">
    <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
      <classpath>
        <pathelement location="${abcd.proj.base}/lib/aspectj-1.9.4/aspectjtools-1.9.4.jar" />
      </classpath>
    </taskdef>

    <echo message="Weaving the AspectJ's aspects into class files ..." />

    <iajc inpath="${classes}" destdir="${classes}"
          debug="true" fork="true"
          maxmem="${iajc.memoryLimit}"
          source="${javaVersion}">
    <!-- path of jar containing TracingAspect -->
    <aspectpath>
       <path>
         <fileset dir="${pqr.bundle.image}" includes="pqr-bundle-common*.jar" />
       </path>
    </aspectpath>
    <classpath>
       <pathelement path="${deps}" />
       <pathelement path="${abcd.proj.base}/lib/aspectj-1.9.4/aspectjrt-1.9.4.jar" />
      </classpath>
    </iajc>
  </target>

分级转换为


plugins {
        id "io.freefair.aspectj.post-compile-weaving" version "5.1.1"
        //id "aspectj.gradle" version "0.1.6"
        //id "aspectj.AspectjGradlePlugin" version "0.0.3"
    }

configurations {
    ajc
    aspects
    compile {
        extendsFrom aspects
    }
}

ext {
    aspectjVersion = '1.9.2'
}

dependencies {
    implementation gradleApi() // for custom gradle task/pugin development

    compile project('my-project')
    compile project('my-project1')
    compile project('my-project2')
    // ...

    ajc "org.aspectj:aspectjtools:$aspectjVersion"
    compile "org.aspectj:aspectjrt:$aspectjVersion"
    compile "org.aspectj:aspectjweaver:$aspectjVersion"
    aspects project('my-project1')
    // ...
}


compileJava {
    dependsOn configurations.ajc.getTaskDependencyFromProjectDependency(true,"compileJava")

    doLast{
        System.out.println("Java Version: " + JavaVersion.current());
        ant.taskdef( resource:"org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties",classpath: configurations.ajc.asPath)

        ant.iajc(
                maxmem: "1024m",fork: "true",Xlint: "ignore",destDir: sourceSets.main.output.classesDirs.asPath,//my-common.jar consist of my own AspectTracing.class
                aspectPath: "$projectDir/image/pqr-bundle-common*.jar",//aspectPath: configurations.aspects.asPath,sourceRootCopyFilter: "**/*.java",classpath: configurations.compile.asPath,source: project.sourceCompatibility,target: project.targetCompatibility
        ){
            sourceroots{
                sourceSets.main.java.srcDirs.each{
                    //ignoring root project and adding only sub-modules
                    if(!it.absolutePath.contains("/src/main/java")) {
                        pathelement(location: it.absolutePath)
                    }
                }
            }
        }
    }
}

TracingAspect.java如下所示。此类是aspectpath jar

的一部分
    <aspectpath>
       <path>
         <fileset dir="${pqr.bundle.image}" includes="pqr-bundle-common*.jar" />
       </path>
    </aspectpath>
/*
 * The pertypewithin causes all classes that don't have the Untraced annotation
 * to be woven. The pointcuts further limit the use of the tracing loggers to
 * avoid infinite recursion,etc...
 */
@Aspect("pertypewithin(!is(InterfaceType) && !is(EnumType) && (!@my.common.logging.Untraced "
        + "(my-somepackaje..* || my-anotherpackage..*)))")
@Untraced
public class TracingAspect {

    private MyLogger myLogger;
    private static final String ENTERING_PREFIX = "Entering {0}";
    private static final String EXITING_PREFIX = "Exiting {0}";
    private static final String ARGUMENTS = ": Arguments =>";
    private static final String ARGUMENTS_NOT_AVAILABLE = ARGUMENTS + " N/A";
    private static final String RETURN = ",Returns =>";
    private static final String RETURN_NOT_AVAILABLE = RETURN + " N/A";
    private static final String THROWING = "Throwing {0}";

    @Pointcut("staticinitialization(*)")
    public void staticInit() {
    }

    /**
     * This is run in a static initializer block for every woven class,and is
     * used to initialize the trace logger for the class.
     */
    @After("staticInit()")
    public void initLogger(JoinPoint.StaticPart jps) {
        myLogger = MyLogger.getLogger(jps.getSignature().getDeclaringTypeName());
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // Pointcuts
    //
    ////////////////////////////////////////////////////////////////////////////

    @Pointcut("execution(new(..))")
    void tracedConstructors() {
    }

    // The !execution(String toString()) avoids infinite recursion by not
    // tracing toString() methods.
    // Also,don't trace the compile-time inserted 'access$nnn' methods. That
    // might (in very specific cases) lead to recursion but more generally just
    // confusing.
    @Pointcut("execution(* *(..)) && !execution(String toString()) && !execution(* access$*(..)) "
            + "&& !@annotation(my.common.logging.Untraced)")
    void tracedMethods() {
    }

    // Advice starts below.

    @Before("tracedConstructors()")
    public void traceConstructorEntry(JoinPoint thisJoinPoint) {
        if (null != myLogger)
            myLogger.trace(() -> entering(thisJoinPoint.getSignature().getName(),thisJoinPoint.getArgs()));
    }

    @AfterReturning("tracedConstructors()")
    public void traceConstructorExit(JoinPoint thisJoinPoint) {
        if (null != myLogger)
            myLogger.trace(() -> exiting(thisJoinPoint.getSignature().getName(),thisJoinPoint.getArgs(),null));
    }

    @AfterThrowing(pointcut = "tracedConstructors()",throwing = "t")
    public void traceConstructorThrow(JoinPoint thisJoinPoint,Throwable t) {
        if (null != myLogger)
            myLogger.trace(() -> MessageFormat.format(THROWING,thisJoinPoint.getSignature().getName()) + " - "
                    + t.toString());
    }

    @Before("tracedMethods()")
    public void traceMethodEntry(JoinPoint thisJoinPoint) {
        if (null != myLogger)
            myLogger.trace(() -> entering(thisJoinPoint.getSignature().getName(),thisJoinPoint.getArgs()));
    }

    @AfterReturning(pointcut = "tracedMethods()",returning = "r")
    public void traceMethodExit(JoinPoint thisJoinPoint,Object r) {
        // Add sensitive return value to log context
        if (((MethodSignature) thisJoinPoint.getSignature()).getMethod()
                .getAnnotation(SensitiveTraceReturn.class) != null) {
            LogContext.addSensitiveValue(r);
        }
        if (null != myLogger){
            myLogger.trace(() -> exiting(thisJoinPoint.getSignature().getName(),r));
        }
    }

    @AfterThrowing(pointcut = "tracedMethods()",throwing = "t")
    public void traceMethodThrow(JoinPoint thisJoinPoint,thisJoinPoint.getSignature().getName()) + " - "
                    + t.toString());
    }

    // End of Advice

    /**
     * Creates entering message trace statement
     *
     * @param method
     *            method name of the log entry
     * @param args
     *            {@code Object} array representing the message parameters
     */
    private String entering(String method,Object[] args) {
        StringBuffer msgBuffer = new StringBuffer(ENTERING_PREFIX);
        Object[] temp = { method };

        if (args != null && args.length > 0) {
            int index = 1;
            msgBuffer.append(ARGUMENTS);
            for (Object arg : args) {
                if (index > 1) {
                    msgBuffer.append(",");
                }
                msgBuffer.append(" {").append(index).append("}");
                index++;
            }
            temp = ArrayUtils.addAll(temp,args);
        } else {
            msgBuffer.append(ARGUMENTS_NOT_AVAILABLE);
        }

        return MessageFormat.format(msgBuffer.toString(),temp);
    }

    /**
     * Creates exiting message trace statement
     *
     * @param method
     *            method name of the log entry
     * @param args
     *            {@code Object} array representing the message parameters
     * @param returnValue
     *            return value from the method,if any
     */
    private String exiting(String method,Object[] args,Object returnValue) {
        StringBuffer msgBuffer = new StringBuffer(EXITING_PREFIX);
        Object[] temp = { method };

        int index = 1;
        if (args != null && args.length > 0) {
            msgBuffer.append(ARGUMENTS);
            for (Object arg : args) {
                if (index > 1) {
                    msgBuffer.append(",args);
        } else {
            msgBuffer.append(ARGUMENTS_NOT_AVAILABLE);
        }

        if (null != returnValue) {
            msgBuffer.append(RETURN).append(" {").append(index).append("}");
            temp = ArrayUtils.addAll(temp,new Object[] { returnValue });
        } else {
            msgBuffer.append(RETURN_NOT_AVAILABLE);
        }
        temp = ArrayUtils.addAll(temp,args);

        return MessageFormat.format(msgBuffer.toString(),temp);
    }
}

interface :- my.common.logging.Untraced仅在空白处(目前)

public @interface Untraced {
}

但是,它在instrumentation期间由于随机编译错误而失败。

(注意:如果没有我的AspectJ编译,则jar创建会正确进行。)

通常,AspectJ应该进行日志跟踪编织,但是它试图再次编译它,因此失败了。我在这里想念什么吗?

失败的Java代码如下:

private static void runRule(boolean before) {
    String str = (before) ? "before" : "after" ;
}

错误是:

[error] Syntax error,insert "|| Expression" to complete Expression
[ant:iajc] String str = (before) ? "before" : "after" ;
[ant:iajc]               

解决方法

我已在此处https://github.com/swapnil-kotwal-sp/basic-demo

推送了示例示例代码

我还可以在instrumentation期间解决我的业务项目问题,问题出在下面的一些代码上。

private static void runRule(boolean before) {
    String str = (before) ? "before" : "after" ;
}

基本上,AspectJ不喜欢boolean before周围的圆括号,我更改了代码,AspectJ开始正常工作。

private static void runRule(boolean before) {
    String str = before ? "before" : "after" ;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...