使用Maven编译多个源代码目录

216

在一个maven项目中,有没有一种方法可以编译多个Java源代码目录?

10个回答

297
您可以使用build-helper添加新的源代码目录:
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>add-source</goal>
                    </goals>
                    <configuration>
                        <sources>
                            <source>src/main/generated</source>
                        </sources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

4
这种方法的唯一问题是最终生成的成果物包括了Java源代码文件(.java文件)。有没有办法排除源文件,只包含.class文件呢? - saravana_pc
19
提醒其他人(比如我一样的人),plugin元素在/project/build/plugins中而不是在/project/build/pluginManagement/plugins中。 - Betlista
3
如果您正在使用Eclipse,您可能需要从Eclipse市场安装“m2e connector for build-helper-maven-plugin”,以消除pom.xml中的错误。 - dieend
1
如果你收到了像 'build.plugins.plugin.version' for org.codehaus.mojo:build-helper-maven-plugin is missing 这样的警告,你需要在 <plugin> 标签内添加 <version>1.12</version> 标签。 - Alphaaa
9
在2017年,最好的方法是创建一个XML面条(指一种编程技巧),但这样做有问题,难道没有人注意到吗? - Tom
显示剩余6条评论

66

我天真地这样做:

<build>
  <finalName>osmwse</finalName>
  <sourceDirectory>src/main/java, src/interfaces, src/services</sourceDirectory>
</build>

3
对我也有效 :) 但 Eclipse 似乎不喜欢它。 它似乎认为 "src/main/java,src/interfaces" 是单个 src,因此将其标记为(缺失)。 - Joel
5
对我来说,这导致Maven 3.2.2找不到任何源代码。 - user149408
我有和@Joel类似的经历,代码编译成功但出现了一些问题,比如无法识别“main”方法。 - John
4
对于maven 3.8.1版本不起作用。此版本的maven文档中也没有写明在<tag> <sourceDirectory>中可能存在这样的内容。 --- maven-compiler-plugin:3.8.1:compile (default-compile) @ xxx-xxx --- 没有要编译的源文件。 - Eliahu
我在NetBeans上工作时,没有给IntelliJ或Eclipse带来任何问题。 - user1133275
1
有人能指导我去哪里找到文档,说明我们可以在<sourceDirectory>中使用用逗号分隔的多个目录吗? - AhmedRana

46

这对我起作用了

<build>
    <sourceDirectory>.</sourceDirectory>
    <plugins>
        <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
        <includes>
            <include>src/main/java/**/*.java</include>
            <include>src/main2/java/**/*.java</include>
        </includes>
        </configuration>
        </plugin>
    </plugins>
</build>

21
依我之见,这不是一个好主意,因为有几个插件都假设sourceDirectory(可能还包括其他的sources)是源文件根目录。在你的方案中,只有maven-compiler-plugin知道这些实际的根目录。 - Laurent Pireyn
3
@Laurent,你说得对。这个想法在几年前是不错的,但现在有更好的选择。上面提到的build-helper是我的首选选项。 - sal
5
这不会将其添加到项目模型中,所以在集成开发环境中无法正常工作。 - David Phillips
+1 @sal,使用 WAR 项目依赖项非常顺利。 - ATorras
1
如果我想包含一个外部源目录(包含我在Maven项目中使用的Java类),那么这是行不通的。如果我的外部源位于Eclipse工作区之外怎么办?我该怎么做? - Aerox
在我的 Maven 3.5.4 上运行良好。 - Cesar Moore

25

为了使其在IntelliJ中工作,您还可以通过以下方式向编译器插件添加generatedSourcesDirectory:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>
    </configuration>
</plugin>

想要补充一下,在Eclipse中也可以将生成的源代码作为项目配置中的源位置添加进去。 - Adam Hawkes
3
这条路径似乎是用于由注解处理器生成的源代码。即使它可以工作,某些插件可能会以不同的方式处理这个路径。例如,我期望当运行 'clean' 时,这个目录可能会被删除。 - kapex
2
你把它放在哪里了? - Pavel Niedoba
IntelliJ 2021.2.3 这仍然有效,并且这是我找到的唯一解决方案。我同意 @kapex 的看法,它是用于注释的,但是我花了一天时间尝试找到“正确的方法”,但失败了。 - cb4
为了使构建更加健壮,并更符合Maven标准:<generatedSourcesDirectory>${project.build.directory}/generated-sources/main/java</generatedSourcesDirectory> - cb4

9
这也适用于使用Maven的情况,只需定义资源标签即可。您可以将src文件夹命名为任何想要的名称。
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>

        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>

        <resource>
            <directory>src/main/generated</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>

12
通常情况下,资源文件不是代码,它们不会被编译。该信息来源于http://maven.apache.org/pom.html#Resources。 - SJuan76

7
这适用于Maven 3.5.4,现在Intellij Idea将此代码视为源代码。
<plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>3.3</version>
     <configuration>
         <generatedSourcesDirectory>src/main/generated</generatedSourcesDirectory>                    
     </configuration>
</plugin>

4
尽管evokk的回答基本正确,但缺少测试类。 您需要使用目标add-test-source添加测试类:
<execution>
    <phase>generate-sources</phase>
    <goals>
        <goal>add-test-source</goal>
    </goals>
    <configuration>
       <sources>
            <source>target/generated/some-test-classes</source>
        </sources>
    </configuration>
</execution>

<phase>generate-sources</phase> 这个是正确的,或者应该是generate-test-sources - Raja Nagendra Kumar

2
使用了build-helper-maven-plugin插件进行构建,并更新了src/main/generated文件夹。然后mvn clean compile可以在../common/src/main/java或../common上工作,因此保留了后者。确认IntelliJ IDEA(版本10.5.2)的编译级别失败,如David Phillips所提到的。 问题在于IDEA没有将另一个源根添加到项目中。手动添加解决了问题。这不是很好,因为项目中的任何编辑都应该来自maven而不是直接编辑IDEA的项目选项。但是,在它们直接支持build-helper-maven-plugin并自动添加源之前,我能够使用它来解决问题。
然后需要另一种解决方法才能使其正常工作。由于每次IDEA重新导入pom更改后,新添加的源被保存在模块上,但失去了其源文件夹选择,因此无用。因此,对于IDEA,需要设置以下内容:
- 选择-项目设置/ Maven /导入/保留源和测试文件夹。 - 添加-项目结构/项目设置/模块/{Module} /源/添加内容根目录。
现在在导入时保留这些文件夹也不是世界上最好的做法,但可以尝试一下。

两种选项都不适用于我使用的IntelliJ Idea 9.0.4。我还没有尝试在最近的Eclipse中使用build-helper选项,但是当我在3.4和m2插件上尝试时它并没有起作用。Maven不喜欢多个源树或从同一项目构建的多个工件,任何试图规避此限制的尝试通常都是可怕的黑客行为。 - sal
我已经使用IntelliJ很多年了,从未转换到eclipse,所以无法对其进行评价,但听说它通常也非常好。对于IntelliJ,每两年升级一次个人许可证的费用为100美元/年。新的主要版本通常在每年的1月份发布。然后在前一年的最后2-3个月,他们允许您购买上一个版本并免费升级到即将推出的版本。现在正在进行中,因此这是购买10并获得11的“安全”时间。此外,如果您不需要JSP和其他企业功能,请使用免费的社区版。 - arntg

1
这可以分为两步完成:
  • 对于每个源目录,您应该创建自己的模块。
  • 在所有模块中,您应该指定相同的构建目录:${build.directory}

如果您使用启动的Jetty (jetty:run),则任何模块中的任何类的重新编译(使用Maven、IDEA或Eclipse)都将导致Jetty重启。修改资源的情况也是一样的。


1
在配置中,您可以使用<compileSourceRoots>
oal:          org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-cli)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <basedir default-value="${basedir}"/>
  <buildDirectory default-value="${project.build.directory}"/>
  <compilePath default-value="${project.compileClasspathElements}"/>
  <compileSourceRoots default-value="${project.compileSourceRoots}"/>
  <compilerId default-value="javac">${maven.compiler.compilerId}</compilerId>
  <compilerReuseStrategy default-value="${reuseCreated}">${maven.compiler.compilerReuseStrategy}</compilerReuseStrategy>
  <compilerVersion>${maven.compiler.compilerVersion}</compilerVersion>
  <debug default-value="true">${maven.compiler.debug}</debug>
  <debuglevel>${maven.compiler.debuglevel}</debuglevel>
  <encoding default-value="${project.build.sourceEncoding}">${encoding}</encoding>
  <executable>${maven.compiler.executable}</executable>
  <failOnError default-value="true">${maven.compiler.failOnError}</failOnError>
  <failOnWarning default-value="false">${maven.compiler.failOnWarning}</failOnWarning>
  <forceJavacCompilerUse default-value="false">${maven.compiler.forceJavacCompilerUse}</forceJavacCompilerUse>
  <fork default-value="false">${maven.compiler.fork}</fork>
  <generatedSourcesDirectory default-value="${project.build.directory}/generated-sources/annotations"/>
  <maxmem>${maven.compiler.maxmem}</maxmem>
  <meminitial>${maven.compiler.meminitial}</meminitial>
  <mojoExecution default-value="${mojoExecution}"/>
  <optimize default-value="false">${maven.compiler.optimize}</optimize>
  <outputDirectory default-value="${project.build.outputDirectory}"/>
  <parameters default-value="false">${maven.compiler.parameters}</parameters>
  <project default-value="${project}"/>
  <projectArtifact default-value="${project.artifact}"/>
  <release>${maven.compiler.release}</release>
  <session default-value="${session}"/>
  <showDeprecation default-value="false">${maven.compiler.showDeprecation}</showDeprecation>
  <showWarnings default-value="false">${maven.compiler.showWarnings}</showWarnings>
  <skipMain>${maven.main.skip}</skipMain>
  <skipMultiThreadWarning default-value="false">${maven.compiler.skipMultiThreadWarning}</skipMultiThreadWarning>
  <source default-value="1.6">${maven.compiler.source}</source>
  <staleMillis default-value="0">${lastModGranularityMs}</staleMillis>
  <target default-value="1.6">${maven.compiler.target}</target>
  <useIncrementalCompilation default-value="true">${maven.compiler.useIncrementalCompilation}</useIncrementalCompilation>
  <verbose default-value="false">${maven.compiler.verbose}</verbose>
</configuration>

这些是编译器插件3.8.1版本可用的所有配置。不同版本有不同的配置,你可以在一般的mvn命令后加上-X来运行代码以查找它们。

mvn clean install -X
mvn compiler:compile -X

并且可以通过ID或目标或插件名称进行搜索。这对其他插件也可能有所帮助。Eclipse、intelliJ可能无法显示所有配置作为建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接