AspectJ - 丢失的子类 [英] AspectJ - Child Classes Getting Lost

查看:24
本文介绍了AspectJ - 丢失的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确信这对 AspectJ 来说是新手问题,但在查看书籍和网站时,我没有看到我所认识的术语的答案.

I'm sure this amounts to Newbie question for AspectJ but reviewing books and web sites, I'm not seeing the answer in terms I recognize.

总结:在我的客户端 Jar 中,我收到编译错误,抱怨作为方面 B"的一部分添加的方法不存在.

我有一个类似的设置:

         +---------------------+     
         |                     |     
         |  Client Jar         |     
         |                     |     
         +--+---------------+--+     
            |               |        
            |               |        
 +----------+----+  +-------v-------+
 | JSON Serial / |  |  Other Aspect |
 |  Deser Aspect |  +---------------+
 +-------------+-+  +-------v-------+
               |    |  Potential    |
               |    |   Other Jar   |
               |    +---------------+
               |                     
          +----v-----------+         
          |   Javabean     |         
          |   Aspects      |         
          +----------------+         
          +----v-----------+         
          |   Basic Data   |         
          |    Objects     |         
          +----------------+         

本质上,我有两个层面的方面,其中每一层的行为都在扩展.

Essentially, I have two levels of aspects where behaviors are being extended in each layer.

假设基本数据对象"中有以下类:

Assume the following class in "Basic Data Objects":

基本数据对象示例对象

public class SampleObject {
    private String name;
    private int age;
}

以及 JavaBean Aspects 中的以下方面:

and the following aspect in JavaBean Aspects:

privileged aspect SampleObject_JavaBean {
    public String SampleObject.getName() {
       return this.name;
    }
}

以及 JSON Aspects 中的以下方面:

And the following aspect in JSON Aspects:

privileged aspect SampleObject_Json {
    public String SampleObject.getNameValue() {
       return this.name == null ? null : this.name.serialize();
    }
}

最后,在实际的客户端 jar 中,我收到以下编译错误:

Finally, in the actual client jar, I am getting the following as a compilation error:

public void someMethod (SampleObject obj) {
    obj.getNameValue() // <-- This has a compilation error that the getNameValue() is unresolvable.
}

在我的客户端 Jar 中,我收到编译错误,即作为方面 B"的一部分添加的方法不可用.

In my Client Jar, I am getting compilation errors that methods that were added as a part of "Aspect B" are not available.

我的期望是Aspect A"生成的 jar 文件应该编译所有自己的类以及作为Aspect B"一部分提供的所有类.

My expectation was that the "Aspect A" generated jar file should have all its own classes compiled as well as all the classes that were provided as a part of "Aspect B".

方面 B pom:

<project>
    <!-- (...) -->

    <artifactId>aspect-b</artifactId>

        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>lib-data-objects</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>

        <build>
            <plugins>


        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <outxml>true</outxml>
                <complianceLevel>${java.version}</complianceLevel>
                <source>${java.version}</source>
                <target>${java.version}</target>

                <weaveDependencies>
                    <weaveDependency>
                        <groupId>com.example</groupId>
                        <artifactId>lib-data-objects</artifactId>
                    </weaveDependency>
                </weaveDependencies>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

    <!-- (...) -->
</project>

A 方面的 pom:

<project>

<!-- (...) -->

<artifactId>aspect-a</artifactId>

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>

    <dependency>
        <groupId>com.example</groupId>
        <artifactId>lib-data-objects</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>aspect-b</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <outxml>true</outxml>
                <complianceLevel>${java.version}</complianceLevel>
                <source>${java.version}</source>
                <target>${java.version}</target>

                <weaveDependencies>
                    <weaveDependency>
                        <groupId>com.example</groupId>
                        <artifactId>aspect-b</artifactId>
                    </weaveDependency>
                </weaveDependencies>
            </configuration>
        </plugin>
    </plugins>
</build>

<!-- (...) -->

</project>

客户端 Jar pom:

<project>

<!-- (...) -->

<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>aspect-a-wrapper</artifactId>
        <version>${aspect-a.version}</version>
    </dependency>
    <groupId>com.example</groupId>
        <artifactId>lib-data-objects</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <outxml>true</outxml>
                <complianceLevel>${java.version}</complianceLevel>
                <source>${java.version}</source>
                <target>${java.version}</target>

                <weaveDependencies>
                    <weaveDependency>
                        <groupId>com.example</groupId>
                        <artifactId>aspect-a</artifactId>
                    </weaveDependency>
                </weaveDependencies>
            </configuration>
        </plugin>
    </plugins>
</build>

<!-- (...) -->

</project>

推荐答案

正如您在自己的回答中所说,在您的客户端 JAR pom.xml 中,您已经定义了对两者的依赖

As you said in your own answer, in your client JAR pom.xml you have defined dependencies on both

  • 纯数据对象库(没有方面代码)
  • 经过两个编织阶段(Java Bean 和 JSON 类型间声明)的方面增强型数据对象库.

但你只需要后者,所以你应该删除前者.

But you only need the latter, so you should remove the former.

您在方面库中使用 weaveDependencies 是可以且必要的,因为否则它们将无法在您的场景中编译:方面 B 需要数据对象库,否则它找不到应该添加新的类方法来.Aspect B 需要 Aspect A,因为它想使用一个已经增强的库来通过 ITD 添加更多的方法.我不认为这是一个特别好的设置,因为方面 B 需要了解方面 A,这会产生不必要的传递依赖 ClientJar ->AspB ->AspA ->数据对象.也许直接对数据对象库进行方面增强并将链缩短到 ClientJar ->数据对象.如果您真的需要在其他情况下没有任何添加的 ITD 方法的普通库,这只会很糟糕.然后你仍然可以创建一个简单的和完全方面增强的版本(只有一个方面增强阶段,而不是两个传递依赖的阶段).

That you use weaveDependencies in your aspect libraries is okay and necessary because otherwise they will not compile in your scenario: Aspect B needs the data objects library because otherwise it cannot find the classes it should add new methods to. Aspect B needs Aspect A because it wants to use an already aspect-enhanced library to add even more methods via ITD. I don't think that this is a particularly nice setup because Aspect B needs to know about Aspect A, which creates an unnecessary transitive dependency ClientJar -> AspB -> AspA -> DataObj. Maybe it would be wiser to aspect-enhance the data objects library directly and shorten the chain to ClientJar -> DataObj. This is only bad if you really need the plain library without any added ITD methods in other circumstances. Then you could still create a plain and a fully aspect-enhanced version (only one stage of aspect enhancement, not two transitively dependent ones).

更新,2015 年 1 月 2 日:

我有一些剩余的时间,并重新开始研究这个.我最终得到的是一个不错的解决方案(请参阅 GitHub 存储库) 具有以下特征:

I had some leftover time and have started looking into this again. What I have ended up with is a nice solution (see GitHub repo) with the following characteristics:

  • 有一个父模块aspectj-multi-module,子模块是:
    • 数据对象(应用程序类,无方面),无依赖
    • aspect-javabean(Java Bean 相关的 ITD 方面),依赖于 data-objects
    • aspect-json(与 JSON 相关的 ITD 方面),依赖于 data-objects
    • data-objects-aspectj(将切面编入核心类),依赖于data-objectsaspect-javabean方面-json
    • client-jar(创建包含核心 + 方面代码的 JAR 的 JAR,使用方面增强的核心类和 AspectJ 运行时的带有 main 方法的示例类),依赖于 data-objects-aspectj
    • There is a parent module aspectj-multi-module, child modules are:
      • data-objects (application class, no aspects), no dependencies
      • aspect-javabean (Java Bean-related ITD aspect), depends on data-objects
      • aspect-json (JSON-related ITD aspect), depends on data-objects
      • data-objects-aspectj (weave aspects into core classes), depends on data-objects, aspect-javabean, aspect-json
      • client-jar (create JAR of JARs containing core + aspect code, sample class with main method using aspect-enhanced core class and AspectJ runtime), depends on data-objects-aspectj
      • inpath 上的任何内容也将在输出目录/JAR 中.对应的 AspectJ Maven 配置设置是 , section .
      • aspectpath 上的任何内容仅在编译时可用,并且不会 最终出现在输出中目录/JAR.相应的 AspectJ Maven 配置设置是 , section .
      • Whatever is on the inpath will also be in the output directory/JAR. The corresponding AspectJ Maven config setting is <weaveDependency>, section <weaveDependencies>.
      • Whatever is on the aspectpath is only available during compile time and will not end up in the output directory/JAR. The corresponding AspectJ Maven config setting is <aspectLibrary>, section <aspectLibraries>.

      控制台输入/输出:

      $ java -jar client-jar/target/client-jar-1.0-SNAPSHOT.one-jar.jar
      
      SampleObject{name='John Doe', age=33}
      
      Java Bean properties:
        John Doe
        33
      
      JSON properties:
        "Name" : "John Doe"
        "Age" : 33
      

      <小时>

      更新,2015 年 1 月 3 日:

      我通过 Maven 配置文件在模块 data-objects-aspectj 中添加了创建应用于核心代码的自定义方面组合的功能,请参阅 变更集 32ee5fc.

      I added the capability to create a custom mix of aspects applied to your core code during weaving in module data-objects-aspectj by means of Maven profiles, see changeset 32ee5fc.

      这篇关于AspectJ - 丢失的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆