【问题标题】:AspectJ advice does not fire in Maven multi-module setupAspectJ 建议在 Maven 多模块设置中不会触发
【发布时间】:2017-09-01 19:19:20
【问题描述】:

我正在尝试使用 Aspectj 进行 AOP,但我不知道为什么不执行我的方面,它只是运行主类。这是我第一次这样做,所以我可能做错了什么。

这是我的代码:

方面:

@Aspect
public class YourAspect {

    @Pointcut("@annotation(yourAnnotationVariableName)")
    public void annotationPointCutDefinition(YourAnnotation yourAnnotationVariableName){
    }

    @Pointcut("execution(* *(..))")
    public void atExecution(){}

    @Around("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint, YourAnnotation yourAnnotationVariableName) throws Throwable {
        if(yourAnnotationVariableName.isRun()) {
            Object returnObject = null;

            try {
                System.out.println("aspects.YourAspect's aroundAdvice's body is now executed Before yourMethodAround is called.");
                returnObject = joinPoint.proceed();
            } catch (Throwable throwable) {
                throw throwable;
            } finally {
                System.out.println("aspects.YourAspect's aroundAdvice's body is now executed After yourMethodAround is called.");
            }
            return returnObject;
        }
        return joinPoint.proceed();
    }

    @After("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()")
    public void printNewLine(JoinPoint pointcut, YourAnnotation yourAnnotationVariableName){
        System.out.print("End\n\r");
    }
}

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface YourAnnotation {
    public boolean isRun() default true;
}

主类:

public class MainClass{
    public static void main(String[] args) {
        MainClass yourClass = new MainClass ();
        yourClass.yourMethodAround();
    }

    @YourAnnotation
    public void yourMethodAround(){
        System.out.println("Executing TestTarget.yourMethodAround()");
    }
}

我正在使用两个模块,POM 看起来像这样:

Aspect 的 POM:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

        <groupId>Group</groupId>
        <artifactId>Aspects</artifactId>
        <version>1.0-SNAPSHOT</version>

        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                </plugin>
            </plugins>
        </build>

        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.10</version>
            </dependency>
        </dependencies>

    </project>

主 POM:

    <?xml version="1.0" encoding="UTF-8"?>
    <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/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    <groupId>Group</groupId>
    <artifactId>Main</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.7</version>
                    <configuration>
                        <complianceLevel>1.8</complianceLevel>
                        <source>1.8</source>
                        <target>1.8</target>
                        <aspectLibraries>
                            <aspectLibrary>
                                <groupId>Group</groupId>
                                <artifactId>Aspects</artifactId>
                            </aspectLibrary>
                        </aspectLibraries>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>compile</goal>
                                <goal>test-compile</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.5.5</version>
                    <configuration>
                        <appendAssemblyId>false</appendAssemblyId>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>aspects.MainClass</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                    <executions>
                        <execution>
                            <id>a-make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>aspects.MainClass</mainClass>
                </configuration>
            </plugin>
         </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>Group</groupId>
            <artifactId>Aspects</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

我在两个项目中都做了 mvn clean install,然后在 Main 项目中做了 mvn exec:java,它只是运行方法,而不是方面。谁能帮帮我?

谢谢!

【问题讨论】:

  • 您是否真的在切入点中使用了yourAnnotationVariableName?它应该有注解类型作为它的参数blog.jayway.com/2015/09/08/defining-pointcuts-by-annotations
  • 我关注了那个网页。在我的切入点中使用 yourAnnotationVariableName 是什么意思?你能再解释一下吗?
  • 关于 Maven 多模块项目,特别是如何使用 AspectJ Maven 插件,存在一些问题和错误假设。例如,切面模块不配置任何插件版本,也不使用主模块作为父模块。即使是这样,这也意味着循环引用,因为如果方面模块依赖于 main 并且 main 具有方面作为依赖项,则无法编译。我建议您创建一个公共父级,然后创建一个应用程序和一个具有正确配置的方面模块(我可以帮助您)。
  • 此外,您可能需要考虑为切面和应用程序模块都使用的公共类添加另一个模块,在其中放置两者都使用的注释类。否则需要将注解类放入切面模块。如@Mikhail Antonov 所示,将所有内容放入单模块项目中是一种简化的解决方法,但如果您有理由创建可重用的方面模块,那将行不通。
  • 感谢您的帮助!我已经设法让它在不同的项目中工作,但我认为我的项目 pom 中有很多东西,有没有办法缩小它?代码如下!

标签: java maven aop aspectj aspectj-maven-plugin


【解决方案1】:

这是一个多模块解决方案。

主 POM(所有其他的父级):

这里我们定义了所有具有基本配置的插件(更具体的配置可以在“应用程序”模块中找到)并管理所有依赖版本。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>de.scrum-master.stackoverflow</groupId>
  <artifactId>main</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.10</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>
            <!-- IMPORTANT -->
            <useIncrementalCompilation>false</useIncrementalCompilation>
          </configuration>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.10</version>
          <configuration>
            <!--<showWeaveInfo>true</showWeaveInfo> -->
            <source>${java.source-target.version}</source>
            <target>${java.source-target.version}</target>
            <Xlint>ignore</Xlint>
            <complianceLevel>${java.source-target.version}</complianceLevel>
            <encoding>${project.build.sourceEncoding}</encoding>
            <!--<verbose>true</verbose> -->
            <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn> -->
          </configuration>
          <executions>
            <execution>
              <!-- IMPORTANT -->
              <phase>process-sources</phase>
              <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjweaver</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
          </dependencies>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.5.5</version>
          <configuration>
            <appendAssemblyId>false</appendAssemblyId>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
          </configuration>
          <executions>
            <execution>
              <id>a-make-assembly</id>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>

        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.5.0</version>
        </plugin>

      </plugins>
    </pluginManagement>

  </build>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
      </dependency>
      <dependency>
        <groupId>de.scrum-master.stackoverflow</groupId>
        <artifactId>common</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>de.scrum-master.stackoverflow</groupId>
        <artifactId>aspect</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <modules>
    <module>common</module>
    <module>application</module>
    <module>aspect</module>
  </modules>

</project>

模块“通用”:

此模块包含“应用程序”和“方面”使用的代码,在本例中更具体地说是注释类。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>de.scrum-master.stackoverflow</groupId>
    <artifactId>main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>common</artifactId>

</project>
package de.scrum_master.common;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface YourAnnotation {
  boolean isRun() default true;
}

模块“方面”:

这里我们只有方面代码。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>de.scrum-master.stackoverflow</groupId>
    <artifactId>main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>aspect</artifactId>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
    </dependency>
    <dependency>
      <groupId>de.scrum-master.stackoverflow</groupId>
      <artifactId>common</artifactId>
    </dependency>
  </dependencies>

</project>
package de.scrum_master.aspect;

import de.scrum_master.common.YourAnnotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class YourAspect {
  @Pointcut("@annotation(yourAnnotationVariableName)")
  public void annotationPointCutDefinition(YourAnnotation yourAnnotationVariableName) {
  }

  @Pointcut("execution(* *(..))")
  public void atExecution() {
  }

  @Around("annotationPointCutDefinition(yourAnnotationVariableName) && atExecution()")
  public Object aroundAdvice(ProceedingJoinPoint thisJoinPoint, YourAnnotation yourAnnotationVariableName) throws Throwable {
    if (yourAnnotationVariableName.isRun()) {
      Object result;
      try {
        System.out.println("Before " + thisJoinPoint);
        result = thisJoinPoint.proceed();
      } catch (Throwable t) {
        throw t;
      } finally {
        System.out.println("After " + thisJoinPoint);
      }
      return result;
    }
    return thisJoinPoint.proceed();
  }
}

模块“应用程序”:

此模块包含应用程序代码。它配置了 Exec Maven 和 Maven Assembly 插件。此外,将“方面”模块定义为 AspectJ Maven 的方面库。

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>de.scrum-master.stackoverflow</groupId>
    <artifactId>main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>application</artifactId>

  <build>
    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>de.scrum_master.app.MainClass</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <configuration>
          <mainClass>de.scrum_master.app.MainClass</mainClass>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <configuration>
          <aspectLibraries>
            <aspectLibrary>
              <groupId>de.scrum-master.stackoverflow</groupId>
              <artifactId>aspect</artifactId>
            </aspectLibrary>
          </aspectLibraries>
        </configuration>
      </plugin>

    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>de.scrum-master.stackoverflow</groupId>
      <artifactId>common</artifactId>
    </dependency>
    <dependency>
      <groupId>de.scrum-master.stackoverflow</groupId>
      <artifactId>aspect</artifactId>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
    </dependency>
  </dependencies>
</project>
package de.scrum_master.app;

import de.scrum_master.common.YourAnnotation;

public class MainClass {
  public static void main(String[] args) {
    MainClass yourClass = new MainClass();
    yourClass.yourMethodAround();
  }

  @YourAnnotation
  public void yourMethodAround() {
    System.out.println("Executing TestTarget.yourMethodAround()");
  }
}

构建日志:

Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem
$ mvn clean install

(...)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] main ............................................... SUCCESS [  0.241 s]
[INFO] common ............................................. SUCCESS [  0.970 s]
[INFO] aspect ............................................. SUCCESS [  1.058 s]
[INFO] application ........................................ SUCCESS [  0.607 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.111 s
[INFO] Finished at: 2017-04-07T17:15:39+02:00
[INFO] Final Memory: 23M/378M
[INFO] ------------------------------------------------------------------------

运行日志:

Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem
$ cd application/

Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem/application
$ mvn exec:java
(...)
[INFO] ------------------------------------------------------------------------
[INFO] Building application 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.5.0:java (default-cli) @ application ---
Before execution(void de.scrum_master.app.MainClass.yourMethodAround())
Executing TestTarget.yourMethodAround()
After execution(void de.scrum_master.app.MainClass.yourMethodAround())
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
(...)

Alexander@Xander-PC MINGW64 ~/Documents/java-src/SO_AJ_MavenMultiModuleProblem/application
$ java -jar target/application-1.0-SNAPSHOT.jar
Before execution(void de.scrum_master.app.MainClass.yourMethodAround())
Executing TestTarget.yourMethodAround()
After execution(void de.scrum_master.app.MainClass.yourMethodAround())

更新:我将整个示例项目推送到GitHub repository

【讨论】:

  • 这是一个很好的解决方案!我一会儿试试。我喜欢这样做的是我在父 pom 上运行 mvn clean isntall 并且所有它们都被编译。但是,如果我的模块之一具有不同的配置文件,会发生什么情况?在这种情况下如何指定它?现在我执行 mvn clean install -Pprofile,但在这种情况下,我将在父节点上运行它,而不是在子节点上。谢谢!
  • 我不明白这个问题。如果您使用-Pprofile 运行主构建,则该配置文件将应用于该配置文件所在的所有模块。
  • 我不知道。因为配置文件只存在于一个模块中,而不存在于另一个模块中。我以为我背后有一个诡计。我会试试看 !谢谢!
  • 我完全不明白你什么时候必须编写写在父 pom 上的插件或依赖项,因为有时你会这样做,有时不会。有什么区别?
  • 你必须使用我所有的代码和我所有的 POM,而不仅仅是部分。你还没有这样做,我可以很容易地发现,因为我使用的是 1.10 版的 AspectJ Maven,你仍然使用 1.7。因此,您一定是搞砸了设置。
【解决方案2】:

好的,给你。我没有将东西拆分到不同的项目/包中以使其尽可能简单。

项目 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>Group</groupId>
    <artifactId>Main</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>yourpackage.AspectJRawTest</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>

    </build>
</project>

注释(你写对了):

package yourpackage;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyCustomAnnotation {
    public boolean isRun() default true;
}

将在带注释的方法之前运行的自定义建议。我不确定这个,术语对我来说不是很清楚......但它似乎有效:)

package yourpackage;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyCustomAspect {
    @Before("execution(* *.*(..)) && @annotation(MyCustomAnnotation)")
    public void advice(JoinPoint joinPoint) {
        System.out.printf("BINGO! advice() called before '%s'%n", joinPoint);
    }
}

最后是主类:

package yourpackage;

public class AspectJRawTest {

    public static void main(String[] args) {
        System.out.println("custom annotation playground");

        ISomething something = new SomethingImpl();

        something.annotatedMethod();
        something.notAnnotatedMethod();
    }

}

interface ISomething {
    void annotatedMethod();

    void notAnnotatedMethod();
}

class SomethingImpl implements ISomething {
    @MyCustomAnnotation
    public void annotatedMethod() {
        System.out.println("I am annotated and something must be printed by an advice above.");
    }

    public void notAnnotatedMethod() {
        System.out.println("I am not annotated and I will not get any special treatment.");
    }
}

我用这样的 maven 构建它:mvn clean compile assembly:single 创建一个包含依赖项的可执行 jar。然后,执行:

java -jar target/Main-1.0-SNAPSHOT-jar-with-dependencies.jar
custom annotation playground
BINGO! advice() called before 'execution(void yourpackage.SomethingImpl.annotatedMethod())'
I am annotated and something must be printed by an advice above.
I am not annotated and I will not get any special treatment.

稍后我会在某处上传一个完整的项目并为您提供a link,但我发布的内容应该足够了。

我已经在 IDEA 中对此进行了测试,但我无法配置它来为我进行正确的编织(命名任何其他 IDE,你会遇到同样的问题)。但是我现在没有时间做这个,你必须自己处理这个任务。好消息,这一定是可能的,因为一切都适用于准系统 maven。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2021-06-18
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多