简体   繁体   English

使 aspectj 与 Scala 模型一起工作

[英]Make aspectj work with scala model

I have a domain made in Scala and some classes made in Java.我有一个用 Scala 制作的域和一些用 Java 制作的类。 I need to make some aspects with Aspectj that I know that work because with a Java class and it works.我需要使用 Aspectj 做一些我知道可以工作的方面,因为使用 Java 类并且它可以工作。 The problem is that when the Scala class is annotated it does not work.问题是当 Scala 类被注释时它不起作用。 Other annotations like hibernate's work well with my Scala class.其他注释(如 hibernate 的)在我的 Scala 类中运行良好。

This is my pom.xml:这是我的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>Group</groupId>
    <artifactId>Parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.source-target.version>1.8</java.source-target.version>
        <aspectj.version>1.8.2</aspectj.version>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.6.1</version>
                    <configuration>
                        <source>${java.source-target.version}</source>
                        <target>${java.source-target.version}</target>
                        <useIncrementalCompilation>false</useIncrementalCompilation>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>createClassesDir</id>
                            <phase>process-resources</phase>
                            <configuration>
                                <tasks>
                                    <mkdir dir="${project.build.directory}\unwoven-classes" />
                                    <mkdir dir="${project.build.directory}\classes" />
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.7</version>
                    <configuration>
                        <complianceLevel>1.8</complianceLevel>
                        <source>${aspectj.version>}</source>
                        <target>${aspectj.version>}</target>
                        <weaveDirectories>
                            <weaveDirectory>${project.build.directory}\unwoven-classes</weaveDirectory>
                        </weaveDirectories>
                    </configuration>
                    <executions>
                        <execution>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>scala-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>scala-compile-first</id>
                            <phase>process-resources</phase>
                            <goals>
                                <goal>add-source</goal>
                                <goal>compile</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>scala-test-compile</id>
                            <phase>process-test-resources</phase>
                            <goals>
                                <goal>testCompile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.scala-lang</groupId>
                <artifactId>scala-library</artifactId>
                <version>2.12.1</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <modules>
        <module>Aspects</module>
    </modules>
</project>

I think that I have to do something with maven, because the aspects and the rest of the code works fine.我认为我必须用 maven 做一些事情,因为方面和其余代码工作正常。 Is there anyway to do that?有没有办法做到这一点?

Thank you!谢谢!

First of all, make sure your aspects (annotation-based or native syntax) always have a .aj file extension (add them to your project via "New aspect" instead of "New class" menu in whatever IDE you use).首先,确保您的方面(基于注释或本机语法)始终具有.aj文件扩展名(在您使用的任何 IDE 中,通过“新方面”而不是“新类”菜单将它们添加到您的项目中)。 I have removed the duplicate class from your repo in my fork and renamed the other one accordingly.我已经从我的fork 中的 repo 中删除了重复的类,并相应地重命名了另一个类。 I chose the native syntax one, by the way.顺便说一下,我选择了本机语法之一。

What was worse, though, is that you somehow expect unwoven Scala classes in a specific directory, but you did not configure the Scala plugin to actually put them there.更糟糕的是,您以某种方式期望特定目录中的非编织 Scala 类,但您没有配置 Scala 插件以实际将它们放在那里。 I fixed that by adding this snippet:我通过添加这个片段来解决这个问题:

<configuration>
    <outputDir>${project.build.directory}/unwoven-classes</outputDir>
</configuration>

Now the AspectJ Maven plugin finds the Scala classes there and performs binary weaving upon them.现在,AspectJ Maven 插件会在那里找到 Scala 类并对它们执行二进制编织。 This fixes both your Java and Scala test.这修复了您的 Java 和 Scala 测试。 Both of them failed in Maven before, now at least the Java one works in IntelliJ, but not the Scala one.它们之前都在 Maven 中失败了,现在至少 Java 可以在 IntelliJ 中运行,但 Scala 不行。 This is due to the fact that IDEA does not know about this strange Maven setup with the additional (intermediate) directory of yours.这是因为 IDEA 不知道这个奇怪的 Maven 设置与您的附加(中间)目录。

So there is nothing wrong with the aspect as such or AspectJ being unable to work with Scala binaries.因此,方面本身或 AspectJ 无法使用 Scala 二进制文件并没有错。 The project setup was wrong and in a way it still is with respect to IDE support.项目设置是错误的,在某种程度上它仍然是关于 IDE 支持的。

So how can you fix it completely?那么如何才能彻底修复呢? You have several options:您有多种选择:

  • Put the aspect code into another Maven module and there configure a weave dependency on the Java + Scala module, weaving all classes from there into the aspect module.将方面代码放入另一个 Maven 模块中,并在那里配置对 Java + Scala 模块的编织依赖,将所有类从那里编织到方面模块中。 But then you might still have issues with running the tests.但是,您可能仍然会遇到运行测试的问题。 But at least you could configure the IDEA project for post-compile weaving with the right dependency.但至少您可以配置 IDEA 项目以使用正确的依赖项进行编译后编织。
  • You could also put the Scala code in its own module instead, define it as a dependency for the Java + AspectJ module and apply binary weaving to it that way.您也可以将 Scala 代码放在它自己的模块中,将其定义为 Java + AspectJ 模块的依赖项,并以这种方式对其应用二进制编织。

Other variants are possible.其他变体也是可能的。 I do not want to over-analyse here, I just fixed your Maven setup in a quick and simple approach to get you going:我不想在这里过度分析,我只是以一种快速而简单的方法修复了您的 Maven 设置,以帮助您前进:

$ mvn clean verify

(...)
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Aktive Codepage: 65001.
Running aspects.AnnotationAspectTest
set(String model.JavaEntity.name)
set(String model.ScalaEntity.name)
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ aspectj-with-scala ---
[INFO] Building jar: C:\Users\Alexander\Documents\java-src\aspectj-with-scala\target\aspectj-with-scala-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
(...)

PS: I have also created a pull request for you to easily integrate my changes into your repo. PS:我还为您创建了一个拉取请求,以便您轻松地将我的更改集成到您的仓库中。

PPS: See, an MCVE is more helpful than what you did before: Post a separate question only showing an aspect and then post this question here with only a Maven POM. PPS:看, MCVE比您之前所做的更有帮助:发布仅显示一个方面的单独问题,然后在此处仅使用 Maven POM 发布此问题。 I needed both plus the other classes in order to reproduce and solve the problem.为了重现和解决问题,我需要两个和其他类。 After you published the GitHub project it was pretty straightforward to find and fix.发布 GitHub 项目后,查找和修复非常简单。

The problem is likely that aspects are often applied to the semantics of your java code - "find a method with a name like X and do the following around it."问题很可能是方面经常应用于您的 Java 代码的语义——“找到一个名称类似于 X 的方法并围绕它执行以下操作。” But Scala code, when viewed from Java, typically does not follow expected naming conventions.但是从 Java 来看,Scala 代码通常不遵循预期的命名约定。 Without more detail on the specific pointcuts being made - and the code on which they're being applied - I couldn't give any more insight.如果没有关于正在制作的特定切入点的更多细节 - 以及应用它们的代码 - 我无法提供更多的见解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM