Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的方面是在其原始设置中执行的,而不是在打包为单独的jar并从其他地方调用时执行的?_Java_Eclipse_Jar_Aspectj - Fatal编程技术网

Java 为什么我的方面是在其原始设置中执行的,而不是在打包为单独的jar并从其他地方调用时执行的?

Java 为什么我的方面是在其原始设置中执行的,而不是在打包为单独的jar并从其他地方调用时执行的?,java,eclipse,jar,aspectj,Java,Eclipse,Jar,Aspectj,我是aspectj的新手 我编写了以下方面,旨在向类型为public*doSomething*(..)的函数调用添加日志记录。如果我的主类是同一个项目的一部分,则方面的编织将在没有故障的情况下执行,代码将执行。如果我将编织好的代码打包到一个jar中,并从另一个eclipse项目调用它,则不会执行建议。另一个场景是将方面(.aj)打包到一个单独的jar中,并将该jar添加到eclipse中的“方面路径”,这使eclipse能够正确地编织方面。问题是我需要将其包装到一个jar中,并从其他地方调用代码

我是aspectj的新手

我编写了以下方面,旨在向类型为
public*doSomething*(..)
的函数调用添加日志记录。如果我的主类是同一个项目的一部分,则方面的编织将在没有故障的情况下执行,代码将执行。如果我将编织好的代码打包到一个jar中,并从另一个eclipse项目调用它,则不会执行建议。另一个场景是将方面(.aj)打包到一个单独的jar中,并将该jar添加到eclipse中的“方面路径”,这使eclipse能够正确地编织方面。问题是我需要将其包装到一个jar中,并从其他地方调用代码。这也不起作用(我想这并不奇怪……)为什么

import org.aspectj.lang.JoinPoint;
导入org.aspectj.lang.reflect.CodeSignature;
导入org.apache.log4j.Logger;
公共方面日志记录{
切入点allPublic():!cflow(调用(public void main(..)&&(调用(public*doSomething*(..));
私有静态最终记录器log=Logger.getLogger(“Logging.aspect”);
@SuppressWarnings({“未选中”、“未使用”})
私有void打印参数(JoinPoint jp){
CodeSignature methodSignature=(CodeSignature)jp.getSignature();
字符串methodName=methodSignature.getName();
对象[]ParamName=methodSignature.getParameterNames();
类[]paramTypes=(类[])methodSignature.getParameterTypes();
Object[]paramObjects=jp.getArgs();
StringBuffer infoMsg=新的StringBuffer();
append(“输入函数:”+methodName);
if(paramNames!=null&¶mNames.length>0){
如果(paramNames.length==1){
infoMsg.append(“带输入参数:[“+paramNames[1]+”]=[“+paramObjects[1]+”]);
}
否则{
append(“带有输入参数:”);
}
for(int i=1;i
应该建议的班级:

public class Main {

    private static final Logger log = Logger.getLogger("A.class");

    public static void doSomethingAa(int number, String message, Map<String, String> map){
        log.debug("A");
    } 

    public static void doSomethingB(int id, String name){
        log.debug("B");
    }

    public static void main(String[] args){
        Map<String, String> map1 = new TreeMap<String, String>();
        Map<String, String> map2 = new TreeMap<String, String>();

        map1.put("FirstKey", "FirstValue");
        map1.put("SecondKey", "SecondValue");

        map2.put("Tal", "Guy");
        map2.put("Happy", "Birthday");

        A.doSomethingAa(17, "Tal", map1);
        A.doSomethingAa(35, "Guy", map2); 

        A.doSomethingB(12, "TalG");
        A.doSomethingB(40, "GuyG");

        System.out.println("Finished running main");

    }

}
公共类主{
私有静态最终记录器log=Logger.getLogger(“A.class”);
公共静态void doSomethingAa(整数、字符串消息、地图){
log.debug(“A”);
} 
公共静态void doSomethingB(int-id,字符串名){
log.debug(“B”);
}
公共静态void main(字符串[]args){
Map map1=新树映射();
Map map2=新树映射();
map1.put(“第一键”、“第一值”);
map1.put(“第二个键”、“第二个值”);
地图2.放置(“Tal”、“Guy”);
map2.put(“快乐”、“生日”);
A.doSomethingAa(17,“Tal”,map1);
A.doSomethingAa(35,“Guy”,map2);
A.doSomethingB(12,“TalG”);
A.doSomethingB(40,“GuyG”);
System.out.println(“完成运行的主管道”);
}
}

谢谢大家

我还没有尝试在插件开发中使用aspectj,所以可能还有一些额外的东西。但是,为了确保目标在编译时正确编织并可以运行,您需要做一些事情

  • 正在编织的插件需要依赖于包含方面的插件
  • 方面需要位于类路径上的导出包中
  • 目标插件需要在类路径上有aspectjrt,这样它才能处理方面
  • 编译目标时,需要使用aspectj编译器来编织目标

更新,我无法重现您的问题(即,它在我的盒子上工作正常)。为了复制这种情况,我在源目录中创建了一个带有单个Logging.aj文件的AspectJ项目。我将其作为jar文件(称为logging.jar)导出到另一个项目的根目录(另一个项目也设置为包含“Main”类的AspectJ项目)。然后,我修改了“main”项目的方面路径,以包括logging.jar和方面,并将建议编织到每个doSomethingAa()和doSomethingB()方法调用中

我在代码中发现的唯一问题是,静态方法调用是针对“A”而不是“Main”

以下是主项目的.classpath文件中的条目:

<classpathentry kind="lib" path="logging.jar">
  <attributes>
    <attribute name="org.eclipse.ajdt.aspectpath"
        value="org.eclipse.ajdt.aspectpath"/>
  </attributes>
</classpathentry>
运行时,此操作失败,并出现NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at Client.main(Client.java:6)
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.Signature
为了解决这个问题,我修改了aj_客户端的.classpath,使其上有aspectjrt(通过手动将AspectJ运行时库类路径容器添加到.classpath),然后重新运行,程序执行并输出日志语句:

Entering function: doSomethingAa with input parameters:  [java.lang.String message] = [Tal] [java.util.Map map] = [{FirstKey=FirstValue, SecondKey=SecondValue}]
log4j:WARN No appenders could be found for logger (A.class).
log4j:WARN Please initialize the log4j system properly.
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingAa with input parameters:  [java.lang.String message] = [Guy] [java.util.Map map] = [{Happy=Birthday, Tal=Guy}]
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingB with input parameters:  [java.lang.String name] = [TalG]
Exit function: void target.Main.doSomethingB(int, String)
Entering function: doSomethingB with input parameters:  [java.lang.String name] = [GuyG]
Exit function: void target.Main.doSomethingB(int, String)
Finished running main
aj_客户端的.classpath文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src/main/java"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
    <!-- the other jars for the logging and target projects -->
    <classpathentry kind="lib" path="/aj_target/target.jar"/>
    <classpathentry kind="lib" path="/aj_target/log4j-1.2.14.jar"/>
    <classpathentry kind="lib" path="/aj_target/logging.jar"/>
    <classpathentry kind="output" path="target/classes"/>
</classpath>
注意:在清理、构建和导出target.jar之前,您需要小心确保已经清理、构建和导出了logging.jar,然后才清理客户机项目。如果你把订单搞砸了,你会得到不匹配的内容


摘要

因此,只要您的客户机项目引用了使用AspectJ构建的“target.jar”(因此Logging.aj是编织的),您的类路径上有一个aspectjrt.jar,并且您已经正确配置了log4j,日志记录就会被输出


您可以通过添加类路径容器或指定兼容aspectjrt.jar的路径来指定aspectjrt依赖关系这是一个有趣的问题,如果没有其他人可以回答,我会在有机会的时候看一看。所有的研究都是+1。这将使赏金
Entering function: doSomethingAa with input parameters:  [java.lang.String message] = [Tal] [java.util.Map map] = [{FirstKey=FirstValue, SecondKey=SecondValue}]
log4j:WARN No appenders could be found for logger (A.class).
log4j:WARN Please initialize the log4j system properly.
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingAa with input parameters:  [java.lang.String message] = [Guy] [java.util.Map map] = [{Happy=Birthday, Tal=Guy}]
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingB with input parameters:  [java.lang.String name] = [TalG]
Exit function: void target.Main.doSomethingB(int, String)
Entering function: doSomethingB with input parameters:  [java.lang.String name] = [GuyG]
Exit function: void target.Main.doSomethingB(int, String)
Finished running main
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src/main/java"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
    <!-- the other jars for the logging and target projects -->
    <classpathentry kind="lib" path="/aj_target/target.jar"/>
    <classpathentry kind="lib" path="/aj_target/log4j-1.2.14.jar"/>
    <classpathentry kind="lib" path="/aj_target/logging.jar"/>
    <classpathentry kind="output" path="target/classes"/>
</classpath>
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
<!--aspectjrt from Maven repository-->
<classpathentry kind="lib" path="C:/maven-2.2.0/repo/aspectj/aspectjrt/1.5.3/aspectjrt-1.5.3.jar"/>
<!--aspectjrt from Eclipse plugin -->
<classpathentry kind="lib" path="C:/eclipse-3.5/eclipse/plugins/org.aspectj.runtime_1.6.5.20090618034232/aspectjrt.jar"/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  <appender name="console" class="org.apache.log4j.ConsoleAppender"> 
    <param name="Target" value="System.out"/> 
    <layout class="org.apache.log4j.PatternLayout"> 
      <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> 
    </layout> 
  </appender> 

  <root> 
    <priority value ="debug" /> 
    <appender-ref ref="console" /> 
  </root>

</log4j:configuration>
DEBUG class - A
INFO  Logging - Exit function: void target.Main.doSomethingAa(int, String, Map)
INFO  Logging - Entering function: doSomethingB with input parameters:  [java.lang.String name] = [TalG]
DEBUG class - B
INFO  Logging - Exit function: void target.Main.doSomethingB(int, String)
INFO  Logging - Entering function: doSomethingB with input parameters:  [java.lang.String name] = [GuyG]
DEBUG class - B
INFO  Logging - Exit function: void target.Main.doSomethingB(int, String)
Finished running main