2017-04-13 2 views
0

私はScalaで作られたドメインとJavaで作られたいくつかのクラスを持っています。私はAspectjを使っていくつかの側面を作っておく必要があります。なぜなら、Javaクラスではうまくいくからです。 問題は、Scalaクラスに注釈が付けられても機能しないということです。 hibernateのような他の注釈は私のScalaクラスとうまく機能します。スカラ型でaspectjを動作させる

これは私の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> 

私は側面と、コードの残りの部分は正常に動作しますので、私は、Mavenのに何かをしなければならないと思います。 これはどうしてですか?

ありがとうございました!

答えて

1

まず、あなたのアスペクト(注釈ベースまたはネイティブ構文)のファイル拡張子が常に.ajであることを確認します(使用するIDEの「新しいクラス」メニューではなく「新しいアスペクト」を使用してプロジェクトに追加します) 。私はforkのレポから重複したクラスを削除し、それに応じて別のクラスに名前を変更しました。ところで、私はネイティブ構文を選択しました。

さらに悪いことに、特定のディレクトリで不自然なScalaクラスが何らかの形で予想されますが、Scalaプラグインを実際にそこに配置するように設定していないということです。

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

今AspectJのMavenプラグインがScalaのクラスを検出し、それらにバイナリ織りを実行します。私はこのスニペットを追加することで固定しました。これにより、JavaとScalaの両方のテストが修正されます。どちらも以前はMavenで失敗していましたが、少なくともJava 1はIntelliJで動作しますが、Scalaでは動作しません。これは、IDEAがあなたの追加の(中間の)ディレクトリを持つこの奇妙なMaven設定について知らないという事実のためです。

アスペクトがスカラのバイナリでは動作しないため、アスペクトには何も問題はありません。プロジェクトの設定は間違っていましたが、IDEサポートに関してはまだまだです。

どうすれば完全に修正できますか?

  • アスペクトコードを別のMavenモジュールに入れて、Java + Scalaモジュールにウィーブ依存性を設定し、そこからすべてのクラスをアスペクトモジュールに組み込みます。しかし、あなたはまだテストを実行することに問題があるかもしれません。しかし、少なくとも、IDEAプロジェクトをポストコンパイル製織に適切な依存関係で設定することができます。
  • 代わりにScalaコードを独自のモジュールに入れて、Java + AspectJモジュールの依存関係として定義し、そのようにバイナリウィービングを適用することもできます。

他の変形も可能である。私はちょうどあなたが軌道に乗るために迅速かつ簡単なアプローチであなたの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:あなたは簡単に私の変更を統合するために、私はまたpull requestを作成しましたあなたのレポ

P.P.S .: MCVEは以前よりも役に立ちました。別の質問を投稿して、面倒を見るだけで、Maven POMだけでこの質問を投稿してください。問題を再現して解決するためには、他のクラスに加えて両方とも必要でした。 GitHubプロジェクトを公開した後は、見つけて修正するのがかなり簡単でした。

+0

ありがとうございました!このソリューションは、私がアップロードしたプロジェクトで完璧に動作します。私は既にプルリクエストを受け入れて、それをマルチモジュールにするため少し変更しました。あなたの忍耐と助けてくれてありがとう! – Motomine

+0

私は最後の質問[ここ](http://stackoverflow.com/questions/43422025/using-aspectj-when-i-run-the-application-with-tomcat)を投稿しました。それは可能ならば??ありがとうございました! – Motomine

+0

これを読んでいる他の人たちのために、@ Motomineのマルチモジュール設定が壊れていて、すべてのテストがMavenで失敗し、IntelliJ IDEAでも失敗しました。私の[フォーク](https://github.com/kriegaex/aspectj-with-scala)にそれを修正し、別のプルリクエストを発行した場合。だから誰かがScala対応のAspectJマルチモジュール設定のショーケースを探しているのであれば、それを見つけることができます。 – kriegaex

0

この問題は、Javaコードのセマンティクスによく適用されることがあります。「Xのような名前のメソッドを見つけて、それを回避する」しかし、Javaから見た場合、Scalaコードは通常、予想される命名規則に従いません。具体的なポイントカットについての詳細や、それらが適用されているコードがなくても、私はそれ以上の洞察を与えることはできませんでした。

+0

私は同意します。私があなたの他の質問で言ったように、完全な[MCVE](http://stackoverflow.com/help/mcve)をコードと共に公開し、GitHubで構成を構築してください。多分私は、あなたの設定を分析することによってあなたのための解決策を見つけることができます。 – kriegaex

+0

私はあなたの意見を見て、私はそれを理解していますが、注釈を使用すると、これは起こりそうにないと思います。たくさんのコードがありますが、あなたが私を助けることができるかどうかを私はGitHubにしばらくアップロードします。ありがとうございました – Motomine

+0

@kriegaex私は完全な例[here](https://github.com/tsandler/aspectj-with-scala)をアップロードしました。この例では、Javaクラスで動作するテストは動作しますが、Scalaクラスで動作するテストは失敗します。 – Motomine

関連する問題